]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'block-2.6.24' of git://git.kernel.dk/data/git/linux-2.6-block
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 12 Oct 2007 02:14:22 +0000 (19:14 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 12 Oct 2007 02:14:22 +0000 (19:14 -0700)
* 'block-2.6.24' of git://git.kernel.dk/data/git/linux-2.6-block: (37 commits)
  [BLOCK] Fix failing compile with BLK_DEV_IO_TRACE=n
  compat_ioctl: move floppy handlers to block/compat_ioctl.c
  compat_ioctl: move cdrom handlers to block/compat_ioctl.c
  compat_ioctl: move BLKPG handling to block/compat_ioctl.c
  compat_ioctl: move hdio calls to block/compat_ioctl.c
  compat_ioctl: handle blk_trace ioctls
  compat_ioctl: add compat_blkdev_driver_ioctl()
  compat_ioctl: move common block ioctls to compat_blkdev_ioctl
  Sysace: Don't enable IRQ until after interrupt handler is registered
  Sysace: sparse fixes
  Sysace: Minor coding convention fixup
  drivers/block/umem: use DRIVER_NAME where appropriate
  drivers/block/umem: trim trailing whitespace
  drivers/block/umem: minor cleanups
  drivers/block/umem: use dev_printk()
  drivers/block/umem: move private include away from include/linux
  Sysace: Labels in C code should not be indented.
  Sysace: Add of_platform_bus binding
  Sysace: Move IRQ handler registration to occur after FSM is initialized
  Sysace: minor rework and cleanup changes
  ...

1523 files changed:
Documentation/dvb/faq.txt
Documentation/feature-removal-schedule.txt
Documentation/kernel-parameters.txt
Documentation/lguest/lguest.c
Documentation/video4linux/CARDLIST.bttv
Documentation/video4linux/CARDLIST.cx23885 [new file with mode: 0644]
Documentation/video4linux/CARDLIST.saa7134
Kbuild
MAINTAINERS
Makefile
arch/arm/mach-imx/mx1ads.c
arch/avr32/boards/atngw100/flash.c
arch/avr32/boards/atngw100/setup.c
arch/avr32/boards/atstk1000/atstk1002.c
arch/avr32/boards/atstk1000/flash.c
arch/avr32/kernel/Makefile
arch/avr32/kernel/entry-avr32b.S
arch/avr32/kernel/setup.c
arch/avr32/kernel/vmlinux.lds.S [moved from arch/avr32/kernel/vmlinux.lds.c with 95% similarity]
arch/avr32/mach-at32ap/at32ap7000.c
arch/avr32/mach-at32ap/clock.c
arch/avr32/mach-at32ap/hsmc.c
arch/avr32/mach-at32ap/pio.c
arch/avr32/mach-at32ap/pm.h
arch/avr32/mm/init.c
arch/blackfin/Kconfig
arch/blackfin/configs/BF533-EZKIT_defconfig
arch/blackfin/configs/BF533-STAMP_defconfig
arch/blackfin/configs/BF537-STAMP_defconfig
arch/blackfin/configs/BF548-EZKIT_defconfig
arch/blackfin/configs/BF561-EZKIT_defconfig
arch/blackfin/configs/PNAV-10_defconfig
arch/blackfin/kernel/Makefile
arch/blackfin/kernel/bfin_dma_5xx.c
arch/blackfin/kernel/bfin_gpio.c
arch/blackfin/kernel/bfin_ksyms.c
arch/blackfin/kernel/cacheinit.c
arch/blackfin/kernel/cplbinit.c
arch/blackfin/kernel/early_printk.c [new file with mode: 0644]
arch/blackfin/kernel/irqchip.c
arch/blackfin/kernel/process.c
arch/blackfin/kernel/ptrace.c
arch/blackfin/kernel/reboot.c [new file with mode: 0644]
arch/blackfin/kernel/setup.c
arch/blackfin/kernel/traps.c
arch/blackfin/kernel/vmlinux.lds.S
arch/blackfin/lib/memcmp.S
arch/blackfin/lib/memcpy.S
arch/blackfin/lib/memmove.S
arch/blackfin/mach-bf533/boards/cm_bf533.c
arch/blackfin/mach-bf533/boards/ezkit.c
arch/blackfin/mach-bf533/boards/stamp.c
arch/blackfin/mach-bf533/head.S
arch/blackfin/mach-bf537/Kconfig
arch/blackfin/mach-bf537/boards/cm_bf537.c
arch/blackfin/mach-bf537/boards/generic_board.c
arch/blackfin/mach-bf537/boards/pnav10.c
arch/blackfin/mach-bf537/boards/stamp.c
arch/blackfin/mach-bf537/head.S
arch/blackfin/mach-bf548/Kconfig
arch/blackfin/mach-bf548/Makefile
arch/blackfin/mach-bf548/boards/ezkit.c
arch/blackfin/mach-bf548/gpio.c [deleted file]
arch/blackfin/mach-bf548/head.S
arch/blackfin/mach-bf561/boards/cm_bf561.c
arch/blackfin/mach-bf561/boards/ezkit.c
arch/blackfin/mach-bf561/head.S
arch/blackfin/mach-common/Makefile
arch/blackfin/mach-common/arch_checks.c [new file with mode: 0644]
arch/blackfin/mach-common/cache.S
arch/blackfin/mach-common/cacheinit.S
arch/blackfin/mach-common/cplbhdlr.S
arch/blackfin/mach-common/cplbmgr.S
arch/blackfin/mach-common/dpmc.S
arch/blackfin/mach-common/entry.S
arch/blackfin/mach-common/interrupt.S
arch/blackfin/mach-common/ints-priority-dc.c
arch/blackfin/mach-common/ints-priority-sc.c
arch/blackfin/mach-common/lock.S
arch/blackfin/mm/init.c
arch/blackfin/oprofile/op_blackfin.h
arch/i386/Kconfig
arch/i386/Makefile
arch/i386/kernel/Makefile [deleted file]
arch/i386/kernel/early_printk.c [deleted file]
arch/i386/kernel/tsc_sync.c [deleted file]
arch/i386/lib/Makefile [deleted file]
arch/i386/mach-generic/Makefile [deleted file]
arch/i386/mm/Makefile [deleted file]
arch/ia64/ia32/audit.c
arch/um/sys-i386/sys_call_table.S
arch/um/sys-x86_64/syscall_table.c
arch/x86/boot/.gitignore [moved from arch/i386/boot/.gitignore with 100% similarity]
arch/x86/boot/Makefile [moved from arch/i386/boot/Makefile with 99% similarity]
arch/x86/boot/a20.c [moved from arch/i386/boot/a20.c with 100% similarity]
arch/x86/boot/apm.c [moved from arch/i386/boot/apm.c with 100% similarity]
arch/x86/boot/bitops.h [moved from arch/i386/boot/bitops.h with 100% similarity]
arch/x86/boot/boot.h [moved from arch/i386/boot/boot.h with 100% similarity]
arch/x86/boot/cmdline.c [moved from arch/i386/boot/cmdline.c with 100% similarity]
arch/x86/boot/code16gcc.h [moved from arch/i386/boot/code16gcc.h with 100% similarity]
arch/x86/boot/compressed/.gitignore [moved from arch/i386/boot/compressed/.gitignore with 100% similarity]
arch/x86/boot/compressed/Makefile [new file with mode: 0644]
arch/x86/boot/compressed/Makefile_32 [moved from arch/i386/boot/compressed/Makefile with 80% similarity]
arch/x86/boot/compressed/Makefile_64 [moved from arch/x86_64/boot/compressed/Makefile with 68% similarity]
arch/x86/boot/compressed/head_32.S [moved from arch/i386/boot/compressed/head.S with 100% similarity]
arch/x86/boot/compressed/head_64.S [moved from arch/x86_64/boot/compressed/head.S with 99% similarity]
arch/x86/boot/compressed/misc_32.c [moved from arch/i386/boot/compressed/misc.c with 100% similarity]
arch/x86/boot/compressed/misc_64.c [moved from arch/x86_64/boot/compressed/misc.c with 100% similarity]
arch/x86/boot/compressed/relocs.c [moved from arch/i386/boot/compressed/relocs.c with 100% similarity]
arch/x86/boot/compressed/vmlinux_32.lds [moved from arch/i386/boot/compressed/vmlinux.lds with 100% similarity]
arch/x86/boot/compressed/vmlinux_32.scr [moved from arch/i386/boot/compressed/vmlinux.scr with 100% similarity]
arch/x86/boot/compressed/vmlinux_64.lds [moved from arch/x86_64/boot/compressed/vmlinux.lds with 100% similarity]
arch/x86/boot/compressed/vmlinux_64.scr [moved from arch/x86_64/boot/compressed/vmlinux.scr with 100% similarity]
arch/x86/boot/copy.S [moved from arch/i386/boot/copy.S with 100% similarity]
arch/x86/boot/cpu.c [moved from arch/i386/boot/cpu.c with 100% similarity]
arch/x86/boot/cpucheck.c [moved from arch/i386/boot/cpucheck.c with 100% similarity]
arch/x86/boot/edd.c [moved from arch/i386/boot/edd.c with 100% similarity]
arch/x86/boot/header.S [moved from arch/i386/boot/header.S with 100% similarity]
arch/x86/boot/install.sh [moved from arch/i386/boot/install.sh with 100% similarity]
arch/x86/boot/main.c [moved from arch/i386/boot/main.c with 100% similarity]
arch/x86/boot/mca.c [moved from arch/i386/boot/mca.c with 100% similarity]
arch/x86/boot/memory.c [moved from arch/i386/boot/memory.c with 100% similarity]
arch/x86/boot/mtools.conf.in [moved from arch/i386/boot/mtools.conf.in with 100% similarity]
arch/x86/boot/pm.c [moved from arch/i386/boot/pm.c with 100% similarity]
arch/x86/boot/pmjump.S [moved from arch/i386/boot/pmjump.S with 100% similarity]
arch/x86/boot/printf.c [moved from arch/i386/boot/printf.c with 100% similarity]
arch/x86/boot/setup.ld [moved from arch/i386/boot/setup.ld with 100% similarity]
arch/x86/boot/string.c [moved from arch/i386/boot/string.c with 100% similarity]
arch/x86/boot/tools/.gitignore [moved from arch/i386/boot/tools/.gitignore with 100% similarity]
arch/x86/boot/tools/build.c [moved from arch/i386/boot/tools/build.c with 100% similarity]
arch/x86/boot/tty.c [moved from arch/i386/boot/tty.c with 100% similarity]
arch/x86/boot/version.c [moved from arch/i386/boot/version.c with 100% similarity]
arch/x86/boot/vesa.h [moved from arch/i386/boot/vesa.h with 100% similarity]
arch/x86/boot/video-bios.c [moved from arch/i386/boot/video-bios.c with 100% similarity]
arch/x86/boot/video-vesa.c [moved from arch/i386/boot/video-vesa.c with 100% similarity]
arch/x86/boot/video-vga.c [moved from arch/i386/boot/video-vga.c with 100% similarity]
arch/x86/boot/video.c [moved from arch/i386/boot/video.c with 100% similarity]
arch/x86/boot/video.h [moved from arch/i386/boot/video.h with 100% similarity]
arch/x86/boot/voyager.c [moved from arch/i386/boot/voyager.c with 100% similarity]
arch/x86/crypto/Makefile [new file with mode: 0644]
arch/x86/crypto/Makefile_32 [moved from arch/i386/crypto/Makefile with 54% similarity]
arch/x86/crypto/Makefile_64 [moved from arch/x86_64/crypto/Makefile with 54% similarity]
arch/x86/crypto/aes-i586-asm_32.S [moved from arch/i386/crypto/aes-i586-asm.S with 100% similarity]
arch/x86/crypto/aes-x86_64-asm_64.S [moved from arch/x86_64/crypto/aes-x86_64-asm.S with 100% similarity]
arch/x86/crypto/aes_32.c [moved from arch/i386/crypto/aes.c with 100% similarity]
arch/x86/crypto/aes_64.c [moved from arch/x86_64/crypto/aes.c with 100% similarity]
arch/x86/crypto/twofish-i586-asm_32.S [moved from arch/i386/crypto/twofish-i586-asm.S with 100% similarity]
arch/x86/crypto/twofish-x86_64-asm_64.S [moved from arch/x86_64/crypto/twofish-x86_64-asm.S with 100% similarity]
arch/x86/crypto/twofish_32.c [moved from arch/i386/crypto/twofish.c with 100% similarity]
arch/x86/crypto/twofish_64.c [moved from arch/x86_64/crypto/twofish.c with 100% similarity]
arch/x86/ia32/Makefile [moved from arch/x86_64/ia32/Makefile with 100% similarity]
arch/x86/ia32/audit.c [moved from arch/x86_64/ia32/audit.c with 95% similarity]
arch/x86/ia32/fpu32.c [moved from arch/x86_64/ia32/fpu32.c with 100% similarity]
arch/x86/ia32/ia32_aout.c [moved from arch/x86_64/ia32/ia32_aout.c with 100% similarity]
arch/x86/ia32/ia32_binfmt.c [moved from arch/x86_64/ia32/ia32_binfmt.c with 100% similarity]
arch/x86/ia32/ia32_signal.c [moved from arch/x86_64/ia32/ia32_signal.c with 100% similarity]
arch/x86/ia32/ia32entry.S [moved from arch/x86_64/ia32/ia32entry.S with 100% similarity]
arch/x86/ia32/ipc32.c [moved from arch/x86_64/ia32/ipc32.c with 98% similarity]
arch/x86/ia32/mmap32.c [moved from arch/x86_64/ia32/mmap32.c with 100% similarity]
arch/x86/ia32/ptrace32.c [moved from arch/x86_64/ia32/ptrace32.c with 100% similarity]
arch/x86/ia32/sys_ia32.c [moved from arch/x86_64/ia32/sys_ia32.c with 100% similarity]
arch/x86/ia32/syscall32.c [moved from arch/x86_64/ia32/syscall32.c with 100% similarity]
arch/x86/ia32/syscall32_syscall.S [moved from arch/x86_64/ia32/syscall32_syscall.S with 73% similarity]
arch/x86/ia32/tls32.c [moved from arch/x86_64/ia32/tls32.c with 100% similarity]
arch/x86/ia32/vsyscall-sigreturn.S [moved from arch/x86_64/ia32/vsyscall-sigreturn.S with 99% similarity]
arch/x86/ia32/vsyscall-syscall.S [moved from arch/x86_64/ia32/vsyscall-syscall.S with 100% similarity]
arch/x86/ia32/vsyscall-sysenter.S [moved from arch/x86_64/ia32/vsyscall-sysenter.S with 100% similarity]
arch/x86/ia32/vsyscall.lds [moved from arch/x86_64/ia32/vsyscall.lds with 100% similarity]
arch/x86/kernel/.gitignore [moved from arch/i386/kernel/.gitignore with 100% similarity]
arch/x86/kernel/Makefile [new file with mode: 0644]
arch/x86/kernel/Makefile_32 [new file with mode: 0644]
arch/x86/kernel/Makefile_64 [new file with mode: 0644]
arch/x86/kernel/acpi/Makefile [new file with mode: 0644]
arch/x86/kernel/acpi/Makefile_32 [moved from arch/i386/kernel/acpi/Makefile with 58% similarity]
arch/x86/kernel/acpi/Makefile_64 [new file with mode: 0644]
arch/x86/kernel/acpi/boot.c [moved from arch/i386/kernel/acpi/boot.c with 100% similarity]
arch/x86/kernel/acpi/cstate.c [moved from arch/i386/kernel/acpi/cstate.c with 100% similarity]
arch/x86/kernel/acpi/earlyquirk_32.c [moved from arch/i386/kernel/acpi/earlyquirk.c with 100% similarity]
arch/x86/kernel/acpi/processor.c [moved from arch/i386/kernel/acpi/processor.c with 100% similarity]
arch/x86/kernel/acpi/sleep_32.c [moved from arch/i386/kernel/acpi/sleep.c with 100% similarity]
arch/x86/kernel/acpi/sleep_64.c [moved from arch/x86_64/kernel/acpi/sleep.c with 100% similarity]
arch/x86/kernel/acpi/wakeup_32.S [moved from arch/i386/kernel/acpi/wakeup.S with 100% similarity]
arch/x86/kernel/acpi/wakeup_64.S [moved from arch/x86_64/kernel/acpi/wakeup.S with 99% similarity]
arch/x86/kernel/alternative.c [moved from arch/i386/kernel/alternative.c with 100% similarity]
arch/x86/kernel/aperture_64.c [moved from arch/x86_64/kernel/aperture.c with 100% similarity]
arch/x86/kernel/apic_32.c [moved from arch/i386/kernel/apic.c with 100% similarity]
arch/x86/kernel/apic_64.c [moved from arch/x86_64/kernel/apic.c with 100% similarity]
arch/x86/kernel/apm_32.c [moved from arch/i386/kernel/apm.c with 100% similarity]
arch/x86/kernel/asm-offsets.c [new file with mode: 0644]
arch/x86/kernel/asm-offsets_32.c [moved from arch/i386/kernel/asm-offsets.c with 99% similarity]
arch/x86/kernel/asm-offsets_64.c [moved from arch/x86_64/kernel/asm-offsets.c with 100% similarity]
arch/x86/kernel/audit_64.c [moved from arch/x86_64/kernel/audit.c with 100% similarity]
arch/x86/kernel/bootflag.c [moved from arch/i386/kernel/bootflag.c with 100% similarity]
arch/x86/kernel/bugs_64.c [moved from arch/x86_64/kernel/bugs.c with 100% similarity]
arch/x86/kernel/cpu/Makefile [moved from arch/i386/kernel/cpu/Makefile with 100% similarity]
arch/x86/kernel/cpu/addon_cpuid_features.c [moved from arch/i386/kernel/cpu/addon_cpuid_features.c with 100% similarity]
arch/x86/kernel/cpu/amd.c [moved from arch/i386/kernel/cpu/amd.c with 100% similarity]
arch/x86/kernel/cpu/bugs.c [moved from arch/i386/kernel/cpu/bugs.c with 100% similarity]
arch/x86/kernel/cpu/centaur.c [moved from arch/i386/kernel/cpu/centaur.c with 100% similarity]
arch/x86/kernel/cpu/common.c [moved from arch/i386/kernel/cpu/common.c with 100% similarity]
arch/x86/kernel/cpu/cpu.h [moved from arch/i386/kernel/cpu/cpu.h with 100% similarity]
arch/x86/kernel/cpu/cpufreq/Kconfig [moved from arch/i386/kernel/cpu/cpufreq/Kconfig with 100% similarity]
arch/x86/kernel/cpu/cpufreq/Makefile [moved from arch/i386/kernel/cpu/cpufreq/Makefile with 100% similarity]
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c [moved from arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c [moved from arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/e_powersaver.c [moved from arch/i386/kernel/cpu/cpufreq/e_powersaver.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/elanfreq.c [moved from arch/i386/kernel/cpu/cpufreq/elanfreq.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/gx-suspmod.c [moved from arch/i386/kernel/cpu/cpufreq/gx-suspmod.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/longhaul.c [moved from arch/i386/kernel/cpu/cpufreq/longhaul.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/longhaul.h [moved from arch/i386/kernel/cpu/cpufreq/longhaul.h with 100% similarity]
arch/x86/kernel/cpu/cpufreq/longrun.c [moved from arch/i386/kernel/cpu/cpufreq/longrun.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/p4-clockmod.c [moved from arch/i386/kernel/cpu/cpufreq/p4-clockmod.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/powernow-k6.c [moved from arch/i386/kernel/cpu/cpufreq/powernow-k6.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/powernow-k7.c [moved from arch/i386/kernel/cpu/cpufreq/powernow-k7.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/powernow-k7.h [moved from arch/i386/kernel/cpu/cpufreq/powernow-k7.h with 100% similarity]
arch/x86/kernel/cpu/cpufreq/powernow-k8.c [moved from arch/i386/kernel/cpu/cpufreq/powernow-k8.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/powernow-k8.h [moved from arch/i386/kernel/cpu/cpufreq/powernow-k8.h with 100% similarity]
arch/x86/kernel/cpu/cpufreq/sc520_freq.c [moved from arch/i386/kernel/cpu/cpufreq/sc520_freq.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c [moved from arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/speedstep-ich.c [moved from arch/i386/kernel/cpu/cpufreq/speedstep-ich.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/speedstep-lib.c [moved from arch/i386/kernel/cpu/cpufreq/speedstep-lib.c with 100% similarity]
arch/x86/kernel/cpu/cpufreq/speedstep-lib.h [moved from arch/i386/kernel/cpu/cpufreq/speedstep-lib.h with 100% similarity]
arch/x86/kernel/cpu/cpufreq/speedstep-smi.c [moved from arch/i386/kernel/cpu/cpufreq/speedstep-smi.c with 100% similarity]
arch/x86/kernel/cpu/cyrix.c [moved from arch/i386/kernel/cpu/cyrix.c with 100% similarity]
arch/x86/kernel/cpu/intel.c [moved from arch/i386/kernel/cpu/intel.c with 100% similarity]
arch/x86/kernel/cpu/intel_cacheinfo.c [moved from arch/i386/kernel/cpu/intel_cacheinfo.c with 100% similarity]
arch/x86/kernel/cpu/mcheck/Makefile [moved from arch/i386/kernel/cpu/mcheck/Makefile with 100% similarity]
arch/x86/kernel/cpu/mcheck/k7.c [moved from arch/i386/kernel/cpu/mcheck/k7.c with 100% similarity]
arch/x86/kernel/cpu/mcheck/mce.c [moved from arch/i386/kernel/cpu/mcheck/mce.c with 100% similarity]
arch/x86/kernel/cpu/mcheck/mce.h [moved from arch/i386/kernel/cpu/mcheck/mce.h with 100% similarity]
arch/x86/kernel/cpu/mcheck/non-fatal.c [moved from arch/i386/kernel/cpu/mcheck/non-fatal.c with 100% similarity]
arch/x86/kernel/cpu/mcheck/p4.c [moved from arch/i386/kernel/cpu/mcheck/p4.c with 100% similarity]
arch/x86/kernel/cpu/mcheck/p5.c [moved from arch/i386/kernel/cpu/mcheck/p5.c with 100% similarity]
arch/x86/kernel/cpu/mcheck/p6.c [moved from arch/i386/kernel/cpu/mcheck/p6.c with 100% similarity]
arch/x86/kernel/cpu/mcheck/therm_throt.c [moved from arch/i386/kernel/cpu/mcheck/therm_throt.c with 100% similarity]
arch/x86/kernel/cpu/mcheck/winchip.c [moved from arch/i386/kernel/cpu/mcheck/winchip.c with 100% similarity]
arch/x86/kernel/cpu/mtrr/Makefile [moved from arch/i386/kernel/cpu/mtrr/Makefile with 100% similarity]
arch/x86/kernel/cpu/mtrr/amd.c [moved from arch/i386/kernel/cpu/mtrr/amd.c with 100% similarity]
arch/x86/kernel/cpu/mtrr/centaur.c [moved from arch/i386/kernel/cpu/mtrr/centaur.c with 100% similarity]
arch/x86/kernel/cpu/mtrr/cyrix.c [moved from arch/i386/kernel/cpu/mtrr/cyrix.c with 100% similarity]
arch/x86/kernel/cpu/mtrr/generic.c [moved from arch/i386/kernel/cpu/mtrr/generic.c with 100% similarity]
arch/x86/kernel/cpu/mtrr/if.c [moved from arch/i386/kernel/cpu/mtrr/if.c with 100% similarity]
arch/x86/kernel/cpu/mtrr/main.c [moved from arch/i386/kernel/cpu/mtrr/main.c with 100% similarity]
arch/x86/kernel/cpu/mtrr/mtrr.h [moved from arch/i386/kernel/cpu/mtrr/mtrr.h with 100% similarity]
arch/x86/kernel/cpu/mtrr/state.c [moved from arch/i386/kernel/cpu/mtrr/state.c with 98% similarity]
arch/x86/kernel/cpu/nexgen.c [moved from arch/i386/kernel/cpu/nexgen.c with 100% similarity]
arch/x86/kernel/cpu/perfctr-watchdog.c [moved from arch/i386/kernel/cpu/perfctr-watchdog.c with 100% similarity]
arch/x86/kernel/cpu/proc.c [moved from arch/i386/kernel/cpu/proc.c with 100% similarity]
arch/x86/kernel/cpu/transmeta.c [moved from arch/i386/kernel/cpu/transmeta.c with 100% similarity]
arch/x86/kernel/cpu/umc.c [moved from arch/i386/kernel/cpu/umc.c with 100% similarity]
arch/x86/kernel/cpufreq/Kconfig [moved from arch/x86_64/kernel/cpufreq/Kconfig with 100% similarity]
arch/x86/kernel/cpuid.c [moved from arch/i386/kernel/cpuid.c with 100% similarity]
arch/x86/kernel/crash_32.c [moved from arch/i386/kernel/crash.c with 100% similarity]
arch/x86/kernel/crash_64.c [moved from arch/x86_64/kernel/crash.c with 100% similarity]
arch/x86/kernel/crash_dump_32.c [moved from arch/i386/kernel/crash_dump.c with 100% similarity]
arch/x86/kernel/crash_dump_64.c [moved from arch/x86_64/kernel/crash_dump.c with 100% similarity]
arch/x86/kernel/doublefault_32.c [moved from arch/i386/kernel/doublefault.c with 100% similarity]
arch/x86/kernel/e820_32.c [moved from arch/i386/kernel/e820.c with 100% similarity]
arch/x86/kernel/e820_64.c [moved from arch/x86_64/kernel/e820.c with 100% similarity]
arch/x86/kernel/early-quirks_64.c [moved from arch/x86_64/kernel/early-quirks.c with 100% similarity]
arch/x86/kernel/early_printk.c [moved from arch/x86_64/kernel/early_printk.c with 100% similarity]
arch/x86/kernel/efi_32.c [moved from arch/i386/kernel/efi.c with 100% similarity]
arch/x86/kernel/efi_stub_32.S [moved from arch/i386/kernel/efi_stub.S with 100% similarity]
arch/x86/kernel/entry_32.S [moved from arch/i386/kernel/entry.S with 99% similarity]
arch/x86/kernel/entry_64.S [moved from arch/x86_64/kernel/entry.S with 100% similarity]
arch/x86/kernel/genapic_64.c [moved from arch/x86_64/kernel/genapic.c with 100% similarity]
arch/x86/kernel/genapic_flat_64.c [moved from arch/x86_64/kernel/genapic_flat.c with 100% similarity]
arch/x86/kernel/geode_32.c [moved from arch/i386/kernel/geode.c with 100% similarity]
arch/x86/kernel/head64.c [moved from arch/x86_64/kernel/head64.c with 100% similarity]
arch/x86/kernel/head_32.S [moved from arch/i386/kernel/head.S with 99% similarity]
arch/x86/kernel/head_64.S [moved from arch/x86_64/kernel/head.S with 100% similarity]
arch/x86/kernel/hpet_32.c [moved from arch/i386/kernel/hpet.c with 100% similarity]
arch/x86/kernel/hpet_64.c [moved from arch/x86_64/kernel/hpet.c with 100% similarity]
arch/x86/kernel/i386_ksyms_32.c [moved from arch/i386/kernel/i386_ksyms.c with 100% similarity]
arch/x86/kernel/i387_32.c [moved from arch/i386/kernel/i387.c with 100% similarity]
arch/x86/kernel/i387_64.c [moved from arch/x86_64/kernel/i387.c with 100% similarity]
arch/x86/kernel/i8237.c [moved from arch/i386/kernel/i8237.c with 100% similarity]
arch/x86/kernel/i8253_32.c [moved from arch/i386/kernel/i8253.c with 100% similarity]
arch/x86/kernel/i8259_32.c [moved from arch/i386/kernel/i8259.c with 100% similarity]
arch/x86/kernel/i8259_64.c [moved from arch/x86_64/kernel/i8259.c with 100% similarity]
arch/x86/kernel/init_task_32.c [moved from arch/i386/kernel/init_task.c with 100% similarity]
arch/x86/kernel/init_task_64.c [moved from arch/x86_64/kernel/init_task.c with 100% similarity]
arch/x86/kernel/io_apic_32.c [moved from arch/i386/kernel/io_apic.c with 100% similarity]
arch/x86/kernel/io_apic_64.c [moved from arch/x86_64/kernel/io_apic.c with 100% similarity]
arch/x86/kernel/ioport_32.c [moved from arch/i386/kernel/ioport.c with 100% similarity]
arch/x86/kernel/ioport_64.c [moved from arch/x86_64/kernel/ioport.c with 100% similarity]
arch/x86/kernel/irq_32.c [moved from arch/i386/kernel/irq.c with 100% similarity]
arch/x86/kernel/irq_64.c [moved from arch/x86_64/kernel/irq.c with 100% similarity]
arch/x86/kernel/k8.c [moved from arch/x86_64/kernel/k8.c with 100% similarity]
arch/x86/kernel/kprobes_32.c [moved from arch/i386/kernel/kprobes.c with 100% similarity]
arch/x86/kernel/kprobes_64.c [moved from arch/x86_64/kernel/kprobes.c with 100% similarity]
arch/x86/kernel/ldt_32.c [moved from arch/i386/kernel/ldt.c with 100% similarity]
arch/x86/kernel/ldt_64.c [moved from arch/x86_64/kernel/ldt.c with 100% similarity]
arch/x86/kernel/machine_kexec_32.c [moved from arch/i386/kernel/machine_kexec.c with 100% similarity]
arch/x86/kernel/machine_kexec_64.c [moved from arch/x86_64/kernel/machine_kexec.c with 100% similarity]
arch/x86/kernel/mca_32.c [moved from arch/i386/kernel/mca.c with 100% similarity]
arch/x86/kernel/mce_64.c [moved from arch/x86_64/kernel/mce.c with 100% similarity]
arch/x86/kernel/mce_amd_64.c [moved from arch/x86_64/kernel/mce_amd.c with 100% similarity]
arch/x86/kernel/mce_intel_64.c [moved from arch/x86_64/kernel/mce_intel.c with 100% similarity]
arch/x86/kernel/microcode.c [moved from arch/i386/kernel/microcode.c with 100% similarity]
arch/x86/kernel/module_32.c [moved from arch/i386/kernel/module.c with 100% similarity]
arch/x86/kernel/module_64.c [moved from arch/x86_64/kernel/module.c with 100% similarity]
arch/x86/kernel/mpparse_32.c [moved from arch/i386/kernel/mpparse.c with 100% similarity]
arch/x86/kernel/mpparse_64.c [moved from arch/x86_64/kernel/mpparse.c with 100% similarity]
arch/x86/kernel/msr.c [moved from arch/i386/kernel/msr.c with 100% similarity]
arch/x86/kernel/nmi_32.c [moved from arch/i386/kernel/nmi.c with 100% similarity]
arch/x86/kernel/nmi_64.c [moved from arch/x86_64/kernel/nmi.c with 100% similarity]
arch/x86/kernel/numaq_32.c [moved from arch/i386/kernel/numaq.c with 100% similarity]
arch/x86/kernel/paravirt_32.c [moved from arch/i386/kernel/paravirt.c with 100% similarity]
arch/x86/kernel/pci-calgary_64.c [moved from arch/x86_64/kernel/pci-calgary.c with 100% similarity]
arch/x86/kernel/pci-dma_32.c [moved from arch/i386/kernel/pci-dma.c with 100% similarity]
arch/x86/kernel/pci-dma_64.c [moved from arch/x86_64/kernel/pci-dma.c with 100% similarity]
arch/x86/kernel/pci-gart_64.c [moved from arch/x86_64/kernel/pci-gart.c with 100% similarity]
arch/x86/kernel/pci-nommu_64.c [moved from arch/x86_64/kernel/pci-nommu.c with 100% similarity]
arch/x86/kernel/pci-swiotlb_64.c [moved from arch/x86_64/kernel/pci-swiotlb.c with 100% similarity]
arch/x86/kernel/pcspeaker.c [moved from arch/i386/kernel/pcspeaker.c with 100% similarity]
arch/x86/kernel/pmtimer_64.c [moved from arch/x86_64/kernel/pmtimer.c with 100% similarity]
arch/x86/kernel/process_32.c [moved from arch/i386/kernel/process.c with 100% similarity]
arch/x86/kernel/process_64.c [moved from arch/x86_64/kernel/process.c with 100% similarity]
arch/x86/kernel/ptrace_32.c [moved from arch/i386/kernel/ptrace.c with 100% similarity]
arch/x86/kernel/ptrace_64.c [moved from arch/x86_64/kernel/ptrace.c with 100% similarity]
arch/x86/kernel/quirks.c [moved from arch/i386/kernel/quirks.c with 100% similarity]
arch/x86/kernel/reboot_32.c [moved from arch/i386/kernel/reboot.c with 100% similarity]
arch/x86/kernel/reboot_64.c [moved from arch/x86_64/kernel/reboot.c with 100% similarity]
arch/x86/kernel/reboot_fixups_32.c [moved from arch/i386/kernel/reboot_fixups.c with 100% similarity]
arch/x86/kernel/relocate_kernel_32.S [moved from arch/i386/kernel/relocate_kernel.S with 100% similarity]
arch/x86/kernel/relocate_kernel_64.S [moved from arch/x86_64/kernel/relocate_kernel.S with 100% similarity]
arch/x86/kernel/scx200_32.c [moved from arch/i386/kernel/scx200.c with 100% similarity]
arch/x86/kernel/setup64.c [moved from arch/x86_64/kernel/setup64.c with 100% similarity]
arch/x86/kernel/setup_32.c [moved from arch/i386/kernel/setup.c with 100% similarity]
arch/x86/kernel/setup_64.c [moved from arch/x86_64/kernel/setup.c with 100% similarity]
arch/x86/kernel/sigframe_32.h [moved from arch/i386/kernel/sigframe.h with 100% similarity]
arch/x86/kernel/signal_32.c [moved from arch/i386/kernel/signal.c with 99% similarity]
arch/x86/kernel/signal_64.c [moved from arch/x86_64/kernel/signal.c with 100% similarity]
arch/x86/kernel/smp_32.c [moved from arch/i386/kernel/smp.c with 100% similarity]
arch/x86/kernel/smp_64.c [moved from arch/x86_64/kernel/smp.c with 100% similarity]
arch/x86/kernel/smpboot_32.c [moved from arch/i386/kernel/smpboot.c with 100% similarity]
arch/x86/kernel/smpboot_64.c [moved from arch/x86_64/kernel/smpboot.c with 100% similarity]
arch/x86/kernel/smpcommon_32.c [moved from arch/i386/kernel/smpcommon.c with 100% similarity]
arch/x86/kernel/srat_32.c [moved from arch/i386/kernel/srat.c with 100% similarity]
arch/x86/kernel/stacktrace.c [moved from arch/x86_64/kernel/stacktrace.c with 100% similarity]
arch/x86/kernel/summit_32.c [moved from arch/i386/kernel/summit.c with 100% similarity]
arch/x86/kernel/suspend_64.c [moved from arch/x86_64/kernel/suspend.c with 100% similarity]
arch/x86/kernel/suspend_asm_64.S [moved from arch/x86_64/kernel/suspend_asm.S with 100% similarity]
arch/x86/kernel/sys_i386_32.c [moved from arch/i386/kernel/sys_i386.c with 100% similarity]
arch/x86/kernel/sys_x86_64.c [moved from arch/x86_64/kernel/sys_x86_64.c with 100% similarity]
arch/x86/kernel/syscall_64.c [moved from arch/x86_64/kernel/syscall.c with 90% similarity]
arch/x86/kernel/syscall_table_32.S [moved from arch/i386/kernel/syscall_table.S with 100% similarity]
arch/x86/kernel/sysenter_32.c [moved from arch/i386/kernel/sysenter.c with 100% similarity]
arch/x86/kernel/tce_64.c [moved from arch/x86_64/kernel/tce.c with 100% similarity]
arch/x86/kernel/time_32.c [moved from arch/i386/kernel/time.c with 100% similarity]
arch/x86/kernel/time_64.c [moved from arch/x86_64/kernel/time.c with 100% similarity]
arch/x86/kernel/topology.c [moved from arch/i386/kernel/topology.c with 100% similarity]
arch/x86/kernel/trampoline_32.S [moved from arch/i386/kernel/trampoline.S with 100% similarity]
arch/x86/kernel/trampoline_64.S [moved from arch/x86_64/kernel/trampoline.S with 99% similarity]
arch/x86/kernel/traps_32.c [moved from arch/i386/kernel/traps.c with 100% similarity]
arch/x86/kernel/traps_64.c [moved from arch/x86_64/kernel/traps.c with 100% similarity]
arch/x86/kernel/tsc_32.c [moved from arch/i386/kernel/tsc.c with 100% similarity]
arch/x86/kernel/tsc_64.c [moved from arch/x86_64/kernel/tsc.c with 100% similarity]
arch/x86/kernel/tsc_sync.c [moved from arch/x86_64/kernel/tsc_sync.c with 100% similarity]
arch/x86/kernel/verify_cpu_64.S [moved from arch/x86_64/kernel/verify_cpu.S with 100% similarity]
arch/x86/kernel/vm86_32.c [moved from arch/i386/kernel/vm86.c with 100% similarity]
arch/x86/kernel/vmi_32.c [moved from arch/i386/kernel/vmi.c with 100% similarity]
arch/x86/kernel/vmiclock_32.c [moved from arch/i386/kernel/vmiclock.c with 100% similarity]
arch/x86/kernel/vmlinux.lds.S [new file with mode: 0644]
arch/x86/kernel/vmlinux_32.lds.S [moved from arch/i386/kernel/vmlinux.lds.S with 100% similarity]
arch/x86/kernel/vmlinux_64.lds.S [moved from arch/x86_64/kernel/vmlinux.lds.S with 100% similarity]
arch/x86/kernel/vsmp_64.c [moved from arch/x86_64/kernel/vsmp.c with 100% similarity]
arch/x86/kernel/vsyscall-int80_32.S [moved from arch/i386/kernel/vsyscall-int80.S with 97% similarity]
arch/x86/kernel/vsyscall-note_32.S [moved from arch/i386/kernel/vsyscall-note.S with 95% similarity]
arch/x86/kernel/vsyscall-sigreturn_32.S [moved from arch/i386/kernel/vsyscall-sigreturn.S with 100% similarity]
arch/x86/kernel/vsyscall-sysenter_32.S [moved from arch/i386/kernel/vsyscall-sysenter.S with 99% similarity]
arch/x86/kernel/vsyscall_32.S [moved from arch/i386/kernel/vsyscall.S with 70% similarity]
arch/x86/kernel/vsyscall_32.lds.S [moved from arch/i386/kernel/vsyscall.lds.S with 100% similarity]
arch/x86/kernel/vsyscall_64.c [moved from arch/x86_64/kernel/vsyscall.c with 100% similarity]
arch/x86/kernel/x8664_ksyms_64.c [moved from arch/x86_64/kernel/x8664_ksyms.c with 100% similarity]
arch/x86/lib/Makefile [new file with mode: 0644]
arch/x86/lib/Makefile_32 [new file with mode: 0644]
arch/x86/lib/Makefile_64 [new file with mode: 0644]
arch/x86/lib/bitops_32.c [moved from arch/i386/lib/bitops.c with 100% similarity]
arch/x86/lib/bitops_64.c [moved from arch/x86_64/lib/bitops.c with 100% similarity]
arch/x86/lib/bitstr_64.c [moved from arch/x86_64/lib/bitstr.c with 100% similarity]
arch/x86/lib/checksum_32.S [moved from arch/i386/lib/checksum.S with 100% similarity]
arch/x86/lib/clear_page_64.S [moved from arch/x86_64/lib/clear_page.S with 100% similarity]
arch/x86/lib/copy_page_64.S [moved from arch/x86_64/lib/copy_page.S with 100% similarity]
arch/x86/lib/copy_user_64.S [moved from arch/x86_64/lib/copy_user.S with 100% similarity]
arch/x86/lib/copy_user_nocache_64.S [moved from arch/x86_64/lib/copy_user_nocache.S with 100% similarity]
arch/x86/lib/csum-copy_64.S [moved from arch/x86_64/lib/csum-copy.S with 100% similarity]
arch/x86/lib/csum-partial_64.c [moved from arch/x86_64/lib/csum-partial.c with 100% similarity]
arch/x86/lib/csum-wrappers_64.c [moved from arch/x86_64/lib/csum-wrappers.c with 100% similarity]
arch/x86/lib/delay_32.c [moved from arch/i386/lib/delay.c with 100% similarity]
arch/x86/lib/delay_64.c [moved from arch/x86_64/lib/delay.c with 100% similarity]
arch/x86/lib/getuser_32.S [moved from arch/i386/lib/getuser.S with 100% similarity]
arch/x86/lib/getuser_64.S [moved from arch/x86_64/lib/getuser.S with 100% similarity]
arch/x86/lib/io_64.c [moved from arch/x86_64/lib/io.c with 100% similarity]
arch/x86/lib/iomap_copy_64.S [moved from arch/x86_64/lib/iomap_copy.S with 100% similarity]
arch/x86/lib/memcpy_32.c [moved from arch/i386/lib/memcpy.c with 100% similarity]
arch/x86/lib/memcpy_64.S [moved from arch/x86_64/lib/memcpy.S with 100% similarity]
arch/x86/lib/memmove_64.c [moved from arch/x86_64/lib/memmove.c with 100% similarity]
arch/x86/lib/memset_64.S [moved from arch/x86_64/lib/memset.S with 100% similarity]
arch/x86/lib/mmx_32.c [moved from arch/i386/lib/mmx.c with 100% similarity]
arch/x86/lib/msr-on-cpu.c [moved from arch/i386/lib/msr-on-cpu.c with 100% similarity]
arch/x86/lib/putuser_32.S [moved from arch/i386/lib/putuser.S with 100% similarity]
arch/x86/lib/putuser_64.S [moved from arch/x86_64/lib/putuser.S with 100% similarity]
arch/x86/lib/rwlock_64.S [moved from arch/x86_64/lib/rwlock.S with 100% similarity]
arch/x86/lib/semaphore_32.S [moved from arch/i386/lib/semaphore.S with 100% similarity]
arch/x86/lib/string_32.c [moved from arch/i386/lib/string.c with 100% similarity]
arch/x86/lib/strstr_32.c [moved from arch/i386/lib/strstr.c with 100% similarity]
arch/x86/lib/thunk_64.S [moved from arch/x86_64/lib/thunk.S with 100% similarity]
arch/x86/lib/usercopy_32.c [moved from arch/i386/lib/usercopy.c with 100% similarity]
arch/x86/lib/usercopy_64.c [moved from arch/x86_64/lib/usercopy.c with 100% similarity]
arch/x86/mach-default/Makefile [moved from arch/i386/mach-default/Makefile with 100% similarity]
arch/x86/mach-default/setup.c [moved from arch/i386/mach-default/setup.c with 100% similarity]
arch/x86/mach-es7000/Makefile [moved from arch/i386/mach-es7000/Makefile with 100% similarity]
arch/x86/mach-es7000/es7000.h [moved from arch/i386/mach-es7000/es7000.h with 100% similarity]
arch/x86/mach-es7000/es7000plat.c [moved from arch/i386/mach-es7000/es7000plat.c with 100% similarity]
arch/x86/mach-generic/Makefile [new file with mode: 0644]
arch/x86/mach-generic/bigsmp.c [moved from arch/i386/mach-generic/bigsmp.c with 100% similarity]
arch/x86/mach-generic/default.c [moved from arch/i386/mach-generic/default.c with 100% similarity]
arch/x86/mach-generic/es7000.c [moved from arch/i386/mach-generic/es7000.c with 100% similarity]
arch/x86/mach-generic/probe.c [moved from arch/i386/mach-generic/probe.c with 100% similarity]
arch/x86/mach-generic/summit.c [moved from arch/i386/mach-generic/summit.c with 100% similarity]
arch/x86/mach-visws/Makefile [moved from arch/i386/mach-visws/Makefile with 100% similarity]
arch/x86/mach-visws/mpparse.c [moved from arch/i386/mach-visws/mpparse.c with 100% similarity]
arch/x86/mach-visws/reboot.c [moved from arch/i386/mach-visws/reboot.c with 100% similarity]
arch/x86/mach-visws/setup.c [moved from arch/i386/mach-visws/setup.c with 100% similarity]
arch/x86/mach-visws/traps.c [moved from arch/i386/mach-visws/traps.c with 100% similarity]
arch/x86/mach-visws/visws_apic.c [moved from arch/i386/mach-visws/visws_apic.c with 100% similarity]
arch/x86/mach-voyager/Makefile [moved from arch/i386/mach-voyager/Makefile with 80% similarity]
arch/x86/mach-voyager/setup.c [moved from arch/i386/mach-voyager/setup.c with 100% similarity]
arch/x86/mach-voyager/voyager_basic.c [moved from arch/i386/mach-voyager/voyager_basic.c with 100% similarity]
arch/x86/mach-voyager/voyager_cat.c [moved from arch/i386/mach-voyager/voyager_cat.c with 100% similarity]
arch/x86/mach-voyager/voyager_smp.c [moved from arch/i386/mach-voyager/voyager_smp.c with 100% similarity]
arch/x86/mach-voyager/voyager_thread.c [moved from arch/i386/mach-voyager/voyager_thread.c with 100% similarity]
arch/x86/math-emu/Makefile [moved from arch/i386/math-emu/Makefile with 100% similarity]
arch/x86/math-emu/README [moved from arch/i386/math-emu/README with 100% similarity]
arch/x86/math-emu/control_w.h [moved from arch/i386/math-emu/control_w.h with 100% similarity]
arch/x86/math-emu/div_Xsig.S [moved from arch/i386/math-emu/div_Xsig.S with 100% similarity]
arch/x86/math-emu/div_small.S [moved from arch/i386/math-emu/div_small.S with 100% similarity]
arch/x86/math-emu/errors.c [moved from arch/i386/math-emu/errors.c with 100% similarity]
arch/x86/math-emu/exception.h [moved from arch/i386/math-emu/exception.h with 100% similarity]
arch/x86/math-emu/fpu_arith.c [moved from arch/i386/math-emu/fpu_arith.c with 100% similarity]
arch/x86/math-emu/fpu_asm.h [moved from arch/i386/math-emu/fpu_asm.h with 100% similarity]
arch/x86/math-emu/fpu_aux.c [moved from arch/i386/math-emu/fpu_aux.c with 100% similarity]
arch/x86/math-emu/fpu_emu.h [moved from arch/i386/math-emu/fpu_emu.h with 100% similarity]
arch/x86/math-emu/fpu_entry.c [moved from arch/i386/math-emu/fpu_entry.c with 100% similarity]
arch/x86/math-emu/fpu_etc.c [moved from arch/i386/math-emu/fpu_etc.c with 100% similarity]
arch/x86/math-emu/fpu_proto.h [moved from arch/i386/math-emu/fpu_proto.h with 100% similarity]
arch/x86/math-emu/fpu_system.h [moved from arch/i386/math-emu/fpu_system.h with 100% similarity]
arch/x86/math-emu/fpu_tags.c [moved from arch/i386/math-emu/fpu_tags.c with 100% similarity]
arch/x86/math-emu/fpu_trig.c [moved from arch/i386/math-emu/fpu_trig.c with 100% similarity]
arch/x86/math-emu/get_address.c [moved from arch/i386/math-emu/get_address.c with 100% similarity]
arch/x86/math-emu/load_store.c [moved from arch/i386/math-emu/load_store.c with 100% similarity]
arch/x86/math-emu/mul_Xsig.S [moved from arch/i386/math-emu/mul_Xsig.S with 100% similarity]
arch/x86/math-emu/poly.h [moved from arch/i386/math-emu/poly.h with 100% similarity]
arch/x86/math-emu/poly_2xm1.c [moved from arch/i386/math-emu/poly_2xm1.c with 100% similarity]
arch/x86/math-emu/poly_atan.c [moved from arch/i386/math-emu/poly_atan.c with 100% similarity]
arch/x86/math-emu/poly_l2.c [moved from arch/i386/math-emu/poly_l2.c with 100% similarity]
arch/x86/math-emu/poly_sin.c [moved from arch/i386/math-emu/poly_sin.c with 100% similarity]
arch/x86/math-emu/poly_tan.c [moved from arch/i386/math-emu/poly_tan.c with 100% similarity]
arch/x86/math-emu/polynom_Xsig.S [moved from arch/i386/math-emu/polynom_Xsig.S with 100% similarity]
arch/x86/math-emu/reg_add_sub.c [moved from arch/i386/math-emu/reg_add_sub.c with 100% similarity]
arch/x86/math-emu/reg_compare.c [moved from arch/i386/math-emu/reg_compare.c with 100% similarity]
arch/x86/math-emu/reg_constant.c [moved from arch/i386/math-emu/reg_constant.c with 100% similarity]
arch/x86/math-emu/reg_constant.h [moved from arch/i386/math-emu/reg_constant.h with 100% similarity]
arch/x86/math-emu/reg_convert.c [moved from arch/i386/math-emu/reg_convert.c with 100% similarity]
arch/x86/math-emu/reg_divide.c [moved from arch/i386/math-emu/reg_divide.c with 100% similarity]
arch/x86/math-emu/reg_ld_str.c [moved from arch/i386/math-emu/reg_ld_str.c with 100% similarity]
arch/x86/math-emu/reg_mul.c [moved from arch/i386/math-emu/reg_mul.c with 100% similarity]
arch/x86/math-emu/reg_norm.S [moved from arch/i386/math-emu/reg_norm.S with 100% similarity]
arch/x86/math-emu/reg_round.S [moved from arch/i386/math-emu/reg_round.S with 100% similarity]
arch/x86/math-emu/reg_u_add.S [moved from arch/i386/math-emu/reg_u_add.S with 100% similarity]
arch/x86/math-emu/reg_u_div.S [moved from arch/i386/math-emu/reg_u_div.S with 100% similarity]
arch/x86/math-emu/reg_u_mul.S [moved from arch/i386/math-emu/reg_u_mul.S with 100% similarity]
arch/x86/math-emu/reg_u_sub.S [moved from arch/i386/math-emu/reg_u_sub.S with 100% similarity]
arch/x86/math-emu/round_Xsig.S [moved from arch/i386/math-emu/round_Xsig.S with 100% similarity]
arch/x86/math-emu/shr_Xsig.S [moved from arch/i386/math-emu/shr_Xsig.S with 100% similarity]
arch/x86/math-emu/status_w.h [moved from arch/i386/math-emu/status_w.h with 100% similarity]
arch/x86/math-emu/version.h [moved from arch/i386/math-emu/version.h with 100% similarity]
arch/x86/math-emu/wm_shrx.S [moved from arch/i386/math-emu/wm_shrx.S with 100% similarity]
arch/x86/math-emu/wm_sqrt.S [moved from arch/i386/math-emu/wm_sqrt.S with 100% similarity]
arch/x86/mm/Makefile [new file with mode: 0644]
arch/x86/mm/Makefile_32 [new file with mode: 0644]
arch/x86/mm/Makefile_64 [new file with mode: 0644]
arch/x86/mm/boot_ioremap_32.c [moved from arch/i386/mm/boot_ioremap.c with 100% similarity]
arch/x86/mm/discontig_32.c [moved from arch/i386/mm/discontig.c with 100% similarity]
arch/x86/mm/extable_32.c [moved from arch/i386/mm/extable.c with 100% similarity]
arch/x86/mm/extable_64.c [moved from arch/x86_64/mm/extable.c with 100% similarity]
arch/x86/mm/fault_32.c [moved from arch/i386/mm/fault.c with 100% similarity]
arch/x86/mm/fault_64.c [moved from arch/x86_64/mm/fault.c with 100% similarity]
arch/x86/mm/highmem_32.c [moved from arch/i386/mm/highmem.c with 100% similarity]
arch/x86/mm/hugetlbpage.c [moved from arch/i386/mm/hugetlbpage.c with 100% similarity]
arch/x86/mm/init_32.c [moved from arch/i386/mm/init.c with 100% similarity]
arch/x86/mm/init_64.c [moved from arch/x86_64/mm/init.c with 100% similarity]
arch/x86/mm/ioremap_32.c [moved from arch/i386/mm/ioremap.c with 100% similarity]
arch/x86/mm/ioremap_64.c [moved from arch/x86_64/mm/ioremap.c with 100% similarity]
arch/x86/mm/k8topology_64.c [moved from arch/x86_64/mm/k8topology.c with 100% similarity]
arch/x86/mm/mmap_32.c [moved from arch/i386/mm/mmap.c with 100% similarity]
arch/x86/mm/mmap_64.c [moved from arch/x86_64/mm/mmap.c with 100% similarity]
arch/x86/mm/numa_64.c [moved from arch/x86_64/mm/numa.c with 100% similarity]
arch/x86/mm/pageattr_32.c [moved from arch/i386/mm/pageattr.c with 100% similarity]
arch/x86/mm/pageattr_64.c [moved from arch/x86_64/mm/pageattr.c with 100% similarity]
arch/x86/mm/pgtable_32.c [moved from arch/i386/mm/pgtable.c with 100% similarity]
arch/x86/mm/srat_64.c [moved from arch/x86_64/mm/srat.c with 100% similarity]
arch/x86/oprofile/Kconfig [moved from arch/i386/oprofile/Kconfig with 100% similarity]
arch/x86/oprofile/Makefile [moved from arch/i386/oprofile/Makefile with 100% similarity]
arch/x86/oprofile/backtrace.c [moved from arch/i386/oprofile/backtrace.c with 100% similarity]
arch/x86/oprofile/init.c [moved from arch/i386/oprofile/init.c with 100% similarity]
arch/x86/oprofile/nmi_int.c [moved from arch/i386/oprofile/nmi_int.c with 100% similarity]
arch/x86/oprofile/nmi_timer_int.c [moved from arch/i386/oprofile/nmi_timer_int.c with 100% similarity]
arch/x86/oprofile/op_counter.h [moved from arch/i386/oprofile/op_counter.h with 100% similarity]
arch/x86/oprofile/op_model_athlon.c [moved from arch/i386/oprofile/op_model_athlon.c with 100% similarity]
arch/x86/oprofile/op_model_p4.c [moved from arch/i386/oprofile/op_model_p4.c with 100% similarity]
arch/x86/oprofile/op_model_ppro.c [moved from arch/i386/oprofile/op_model_ppro.c with 100% similarity]
arch/x86/oprofile/op_x86_model.h [moved from arch/i386/oprofile/op_x86_model.h with 100% similarity]
arch/x86/pci/Makefile [new file with mode: 0644]
arch/x86/pci/Makefile_32 [moved from arch/i386/pci/Makefile with 81% similarity]
arch/x86/pci/Makefile_64 [new file with mode: 0644]
arch/x86/pci/acpi.c [moved from arch/i386/pci/acpi.c with 100% similarity]
arch/x86/pci/common.c [moved from arch/i386/pci/common.c with 100% similarity]
arch/x86/pci/direct.c [moved from arch/i386/pci/direct.c with 100% similarity]
arch/x86/pci/early.c [moved from arch/i386/pci/early.c with 100% similarity]
arch/x86/pci/fixup.c [moved from arch/i386/pci/fixup.c with 100% similarity]
arch/x86/pci/i386.c [moved from arch/i386/pci/i386.c with 100% similarity]
arch/x86/pci/init.c [moved from arch/i386/pci/init.c with 100% similarity]
arch/x86/pci/irq.c [moved from arch/i386/pci/irq.c with 100% similarity]
arch/x86/pci/k8-bus_64.c [moved from arch/x86_64/pci/k8-bus.c with 100% similarity]
arch/x86/pci/legacy.c [moved from arch/i386/pci/legacy.c with 100% similarity]
arch/x86/pci/mmconfig-shared.c [moved from arch/i386/pci/mmconfig-shared.c with 100% similarity]
arch/x86/pci/mmconfig_32.c [moved from arch/i386/pci/mmconfig.c with 100% similarity]
arch/x86/pci/mmconfig_64.c [moved from arch/x86_64/pci/mmconfig.c with 100% similarity]
arch/x86/pci/numa.c [moved from arch/i386/pci/numa.c with 100% similarity]
arch/x86/pci/pcbios.c [moved from arch/i386/pci/pcbios.c with 100% similarity]
arch/x86/pci/pci.h [moved from arch/i386/pci/pci.h with 100% similarity]
arch/x86/pci/visws.c [moved from arch/i386/pci/visws.c with 100% similarity]
arch/x86/power/Makefile [moved from arch/i386/power/Makefile with 100% similarity]
arch/x86/power/cpu.c [moved from arch/i386/power/cpu.c with 100% similarity]
arch/x86/power/suspend.c [moved from arch/i386/power/suspend.c with 100% similarity]
arch/x86/power/swsusp.S [moved from arch/i386/power/swsusp.S with 100% similarity]
arch/x86/vdso/.gitignore [moved from arch/x86_64/vdso/.gitignore with 100% similarity]
arch/x86/vdso/Makefile [moved from arch/x86_64/vdso/Makefile with 100% similarity]
arch/x86/vdso/vclock_gettime.c [moved from arch/x86_64/vdso/vclock_gettime.c with 100% similarity]
arch/x86/vdso/vdso-note.S [moved from arch/x86_64/vdso/vdso-note.S with 100% similarity]
arch/x86/vdso/vdso-start.S [moved from arch/x86_64/vdso/vdso-start.S with 100% similarity]
arch/x86/vdso/vdso.S [new file with mode: 0644]
arch/x86/vdso/vdso.lds.S [moved from arch/x86_64/vdso/vdso.lds.S with 100% similarity]
arch/x86/vdso/vextern.h [moved from arch/x86_64/vdso/vextern.h with 100% similarity]
arch/x86/vdso/vgetcpu.c [moved from arch/x86_64/vdso/vgetcpu.c with 100% similarity]
arch/x86/vdso/vma.c [moved from arch/x86_64/vdso/vma.c with 100% similarity]
arch/x86/vdso/voffset.h [moved from arch/x86_64/vdso/voffset.h with 100% similarity]
arch/x86/vdso/vvar.c [moved from arch/x86_64/vdso/vvar.c with 100% similarity]
arch/x86/video/Makefile [moved from arch/i386/video/Makefile with 100% similarity]
arch/x86/video/fbdev.c [moved from arch/i386/video/fbdev.c with 100% similarity]
arch/x86/xen/Kconfig [moved from arch/i386/xen/Kconfig with 100% similarity]
arch/x86/xen/Makefile [moved from arch/i386/xen/Makefile with 100% similarity]
arch/x86/xen/enlighten.c [moved from arch/i386/xen/enlighten.c with 100% similarity]
arch/x86/xen/events.c [moved from arch/i386/xen/events.c with 100% similarity]
arch/x86/xen/features.c [moved from arch/i386/xen/features.c with 100% similarity]
arch/x86/xen/manage.c [moved from arch/i386/xen/manage.c with 100% similarity]
arch/x86/xen/mmu.c [moved from arch/i386/xen/mmu.c with 100% similarity]
arch/x86/xen/mmu.h [moved from arch/i386/xen/mmu.h with 100% similarity]
arch/x86/xen/multicalls.c [moved from arch/i386/xen/multicalls.c with 100% similarity]
arch/x86/xen/multicalls.h [moved from arch/i386/xen/multicalls.h with 100% similarity]
arch/x86/xen/setup.c [moved from arch/i386/xen/setup.c with 100% similarity]
arch/x86/xen/smp.c [moved from arch/i386/xen/smp.c with 100% similarity]
arch/x86/xen/time.c [moved from arch/i386/xen/time.c with 100% similarity]
arch/x86/xen/vdso.h [moved from arch/i386/xen/vdso.h with 100% similarity]
arch/x86/xen/xen-asm.S [moved from arch/i386/xen/xen-asm.S with 100% similarity]
arch/x86/xen/xen-head.S [moved from arch/i386/xen/xen-head.S with 100% similarity]
arch/x86/xen/xen-ops.h [moved from arch/i386/xen/xen-ops.h with 100% similarity]
arch/x86_64/Kconfig
arch/x86_64/Makefile
arch/x86_64/boot/.gitignore [deleted file]
arch/x86_64/boot/Makefile [deleted file]
arch/x86_64/boot/tools/.gitignore [deleted file]
arch/x86_64/kernel/Makefile [deleted file]
arch/x86_64/kernel/acpi/Makefile [deleted file]
arch/x86_64/kernel/cpufreq/Makefile [deleted file]
arch/x86_64/lib/Makefile [deleted file]
arch/x86_64/lib/msr-on-cpu.c [deleted file]
arch/x86_64/mm/Makefile [deleted file]
arch/x86_64/oprofile/Kconfig [deleted file]
arch/x86_64/oprofile/Makefile [deleted file]
arch/x86_64/pci/Makefile [deleted file]
arch/x86_64/vdso/vdso.S [deleted file]
drivers/media/Kconfig
drivers/media/common/Kconfig
drivers/media/common/ir-functions.c
drivers/media/common/ir-keymaps.c
drivers/media/common/saa7146_core.c
drivers/media/common/saa7146_fops.c
drivers/media/common/saa7146_i2c.c
drivers/media/common/saa7146_vbi.c
drivers/media/common/saa7146_video.c
drivers/media/dvb/bt8xx/bt878.c
drivers/media/dvb/bt8xx/bt878.h
drivers/media/dvb/bt8xx/dvb-bt8xx.c
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/dvb/dvb-core/dmxdev.c
drivers/media/dvb/dvb-core/dvb_ca_en50221.c
drivers/media/dvb/dvb-core/dvb_demux.c
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-core/dvb_frontend.h
drivers/media/dvb/dvb-core/dvb_net.c
drivers/media/dvb/dvb-core/dvbdev.c
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/dib0700.h
drivers/media/dvb/dvb-usb/dib0700_core.c
drivers/media/dvb/dvb-usb/dib0700_devices.c
drivers/media/dvb/dvb-usb/dtt200u.c
drivers/media/dvb/dvb-usb/dvb-usb-ids.h
drivers/media/dvb/dvb-usb/dvb-usb-init.c
drivers/media/dvb/dvb-usb/gp8psk-fe.c
drivers/media/dvb/dvb-usb/gp8psk.c
drivers/media/dvb/dvb-usb/gp8psk.h
drivers/media/dvb/dvb-usb/vp7045.c
drivers/media/dvb/frontends/Kconfig
drivers/media/dvb/frontends/Makefile
drivers/media/dvb/frontends/bcm3510.c
drivers/media/dvb/frontends/cx22700.c
drivers/media/dvb/frontends/cx24110.c
drivers/media/dvb/frontends/cx24123.c
drivers/media/dvb/frontends/dib0070.c [new file with mode: 0644]
drivers/media/dvb/frontends/dib0070.h [new file with mode: 0644]
drivers/media/dvb/frontends/dib3000mb.c
drivers/media/dvb/frontends/dib3000mc.c
drivers/media/dvb/frontends/dib7000m.c
drivers/media/dvb/frontends/dib7000p.c
drivers/media/dvb/frontends/dib7000p.h
drivers/media/dvb/frontends/dibx000_common.h
drivers/media/dvb/frontends/dvb-pll.c
drivers/media/dvb/frontends/dvb_dummy_fe.c
drivers/media/dvb/frontends/isl6421.c
drivers/media/dvb/frontends/l64781.c
drivers/media/dvb/frontends/lgdt330x.c
drivers/media/dvb/frontends/lnbp21.c
drivers/media/dvb/frontends/mt2060.c
drivers/media/dvb/frontends/mt2131.c [new file with mode: 0644]
drivers/media/dvb/frontends/mt2131.h [new file with mode: 0644]
drivers/media/dvb/frontends/mt2131_priv.h [new file with mode: 0644]
drivers/media/dvb/frontends/mt2266.c [new file with mode: 0644]
drivers/media/dvb/frontends/mt2266.h [new file with mode: 0644]
drivers/media/dvb/frontends/mt312.c
drivers/media/dvb/frontends/mt352.c
drivers/media/dvb/frontends/nxt200x.c
drivers/media/dvb/frontends/or51132.c
drivers/media/dvb/frontends/or51211.c
drivers/media/dvb/frontends/s5h1409.c [new file with mode: 0644]
drivers/media/dvb/frontends/s5h1409.h [new file with mode: 0644]
drivers/media/dvb/frontends/sp8870.c
drivers/media/dvb/frontends/sp887x.c
drivers/media/dvb/frontends/stv0297.c
drivers/media/dvb/frontends/stv0299.c
drivers/media/dvb/frontends/tda10021.c
drivers/media/dvb/frontends/tda10023.c
drivers/media/dvb/frontends/tda1004x.c
drivers/media/dvb/frontends/tda10086.c
drivers/media/dvb/frontends/tda8083.c
drivers/media/dvb/frontends/ves1820.c
drivers/media/dvb/frontends/zl10353.c
drivers/media/dvb/ttpci/av7110.c
drivers/media/dvb/ttpci/av7110_hw.c
drivers/media/dvb/ttpci/av7110_ir.c
drivers/media/dvb/ttpci/av7110_v4l.c
drivers/media/dvb/ttpci/budget-av.c
drivers/media/dvb/ttpci/budget-ci.c
drivers/media/dvb/ttpci/budget-core.c
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/dvb/ttusb-dec/ttusb_dec.c
drivers/media/radio/Kconfig
drivers/media/radio/radio-gemtek.c
drivers/media/radio/radio-terratec.c
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/arv.c
drivers/media/video/bt8xx/Kconfig
drivers/media/video/bt8xx/bttv-cards.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/bt8xx/bttv-gpio.c
drivers/media/video/bt8xx/bttv-i2c.c
drivers/media/video/bt8xx/bttv-input.c
drivers/media/video/bt8xx/bttv-risc.c
drivers/media/video/bt8xx/bttv-vbi.c
drivers/media/video/bt8xx/bttv.h
drivers/media/video/bt8xx/bttvp.h
drivers/media/video/btcx-risc.c
drivers/media/video/bw-qcam.c
drivers/media/video/cafe_ccic.c
drivers/media/video/compat_ioctl32.c
drivers/media/video/cpia.c
drivers/media/video/cpia2/cpia2_v4l.c
drivers/media/video/cx2341x.c
drivers/media/video/cx23885/Kconfig [new file with mode: 0644]
drivers/media/video/cx23885/Makefile [new file with mode: 0644]
drivers/media/video/cx23885/cx23885-cards.c [new file with mode: 0644]
drivers/media/video/cx23885/cx23885-core.c [new file with mode: 0644]
drivers/media/video/cx23885/cx23885-dvb.c [new file with mode: 0644]
drivers/media/video/cx23885/cx23885-i2c.c [new file with mode: 0644]
drivers/media/video/cx23885/cx23885-reg.h [new file with mode: 0644]
drivers/media/video/cx23885/cx23885.h [new file with mode: 0644]
drivers/media/video/cx25840/cx25840-audio.c
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx25840/cx25840-core.h
drivers/media/video/cx88/Kconfig
drivers/media/video/cx88/cx88-alsa.c
drivers/media/video/cx88/cx88-blackbird.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-core.c
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/cx88/cx88-i2c.c
drivers/media/video/cx88/cx88-input.c
drivers/media/video/cx88/cx88-mpeg.c
drivers/media/video/cx88/cx88-reg.h
drivers/media/video/cx88/cx88-tvaudio.c
drivers/media/video/cx88/cx88-vbi.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/cx88/cx88-vp3054-i2c.c
drivers/media/video/cx88/cx88.h
drivers/media/video/dpc7146.c
drivers/media/video/em28xx/em28xx-core.c
drivers/media/video/em28xx/em28xx-input.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/et61x251/et61x251_core.c
drivers/media/video/ir-kbd-i2c.c
drivers/media/video/ivtv/Kconfig
drivers/media/video/ivtv/Makefile
drivers/media/video/ivtv/ivtv-audio.c [deleted file]
drivers/media/video/ivtv/ivtv-cards.c
drivers/media/video/ivtv/ivtv-cards.h
drivers/media/video/ivtv/ivtv-controls.c
drivers/media/video/ivtv/ivtv-controls.h
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-driver.h
drivers/media/video/ivtv/ivtv-fileops.c
drivers/media/video/ivtv/ivtv-fileops.h
drivers/media/video/ivtv/ivtv-firmware.h
drivers/media/video/ivtv/ivtv-gpio.c
drivers/media/video/ivtv/ivtv-gpio.h
drivers/media/video/ivtv/ivtv-i2c.c
drivers/media/video/ivtv/ivtv-i2c.h
drivers/media/video/ivtv/ivtv-ioctl.c
drivers/media/video/ivtv/ivtv-ioctl.h
drivers/media/video/ivtv/ivtv-irq.c
drivers/media/video/ivtv/ivtv-irq.h
drivers/media/video/ivtv/ivtv-mailbox.c
drivers/media/video/ivtv/ivtv-mailbox.h
drivers/media/video/ivtv/ivtv-queue.c
drivers/media/video/ivtv/ivtv-queue.h
drivers/media/video/ivtv/ivtv-routing.c [moved from drivers/media/video/ivtv/ivtv-video.c with 59% similarity]
drivers/media/video/ivtv/ivtv-routing.h [moved from drivers/media/video/ivtv/ivtv-audio.h with 80% similarity]
drivers/media/video/ivtv/ivtv-streams.c
drivers/media/video/ivtv/ivtv-streams.h
drivers/media/video/ivtv/ivtv-udma.c
drivers/media/video/ivtv/ivtv-udma.h
drivers/media/video/ivtv/ivtv-vbi.c
drivers/media/video/ivtv/ivtv-vbi.h
drivers/media/video/ivtv/ivtv-version.h
drivers/media/video/ivtv/ivtv-yuv.c
drivers/media/video/ivtv/ivtv-yuv.h
drivers/media/video/ivtv/ivtvfb.c [new file with mode: 0644]
drivers/media/video/msp3400-driver.c
drivers/media/video/mt20xx.c
drivers/media/video/mt20xx.h [new file with mode: 0644]
drivers/media/video/mxb.c
drivers/media/video/ov511.c
drivers/media/video/ov7670.c
drivers/media/video/ovcamchip/ovcamchip_core.c
drivers/media/video/planb.c
drivers/media/video/pvrusb2/pvrusb2-context.c
drivers/media/video/pvrusb2/pvrusb2-debug.h
drivers/media/video/pvrusb2/pvrusb2-debugifc.c
drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-hdw.h
drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
drivers/media/video/pvrusb2/pvrusb2-main.c
drivers/media/video/pvrusb2/pvrusb2-std.c
drivers/media/video/pvrusb2/pvrusb2-sysfs.c
drivers/media/video/pwc/pwc-ctrl.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/saa6588.c
drivers/media/video/saa7127.c
drivers/media/video/saa7134/Kconfig
drivers/media/video/saa7134/saa7134-alsa.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/saa7134/saa7134-i2c.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/saa7134/saa7134-oss.c
drivers/media/video/saa7134/saa7134-ts.c
drivers/media/video/saa7134/saa7134-tvaudio.c
drivers/media/video/saa7134/saa7134-vbi.c
drivers/media/video/saa7134/saa7134-video.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/sn9c102/sn9c102_core.c
drivers/media/video/stv680.c
drivers/media/video/tcm825x.c [new file with mode: 0644]
drivers/media/video/tcm825x.h [new file with mode: 0644]
drivers/media/video/tda8290.c
drivers/media/video/tda8290.h [new file with mode: 0644]
drivers/media/video/tda9887.c
drivers/media/video/tea5761.c
drivers/media/video/tea5761.h [new file with mode: 0644]
drivers/media/video/tea5767.c
drivers/media/video/tea5767.h [new file with mode: 0644]
drivers/media/video/tuner-core.c
drivers/media/video/tuner-driver.h
drivers/media/video/tuner-i2c.h [new file with mode: 0644]
drivers/media/video/tuner-simple.c
drivers/media/video/tuner-simple.h [new file with mode: 0644]
drivers/media/video/tuner-types.c
drivers/media/video/tvaudio.c
drivers/media/video/tveeprom.c
drivers/media/video/tvmixer.c
drivers/media/video/usbvision/usbvision-core.c
drivers/media/video/usbvision/usbvision-i2c.c
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/v4l1-compat.c
drivers/media/video/v4l2-common.c
drivers/media/video/v4l2-int-device.c [new file with mode: 0644]
drivers/media/video/videobuf-core.c [moved from drivers/media/video/video-buf.c with 52% similarity]
drivers/media/video/videobuf-dma-sg.c [new file with mode: 0644]
drivers/media/video/videobuf-dvb.c [moved from drivers/media/video/video-buf-dvb.c with 97% similarity]
drivers/media/video/videobuf-vmalloc.c [new file with mode: 0644]
drivers/media/video/videodev.c
drivers/media/video/vino.c
drivers/media/video/vivi.c
drivers/media/video/vp27smpx.c [new file with mode: 0644]
drivers/media/video/w9968cf.c
drivers/media/video/zc0301/zc0301_core.c
drivers/media/video/zoran_card.c
drivers/media/video/zoran_card.h
drivers/media/video/zoran_device.c
drivers/media/video/zoran_driver.c
drivers/media/video/zoran_procfs.c
drivers/media/video/zr36016.c
drivers/media/video/zr36050.c
drivers/media/video/zr36060.c
drivers/mmc/card/Kconfig
drivers/mmc/card/Makefile
drivers/mmc/card/block.c
drivers/mmc/card/sdio_uart.c [new file with mode: 0644]
drivers/mmc/core/Makefile
drivers/mmc/core/bus.c
drivers/mmc/core/core.c
drivers/mmc/core/core.h
drivers/mmc/core/host.c
drivers/mmc/core/mmc.c
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/mmc_ops.h
drivers/mmc/core/sd.c
drivers/mmc/core/sd_ops.c
drivers/mmc/core/sdio.c [new file with mode: 0644]
drivers/mmc/core/sdio_bus.c [new file with mode: 0644]
drivers/mmc/core/sdio_bus.h [new file with mode: 0644]
drivers/mmc/core/sdio_cis.c [new file with mode: 0644]
drivers/mmc/core/sdio_cis.h [new file with mode: 0644]
drivers/mmc/core/sdio_io.c [new file with mode: 0644]
drivers/mmc/core/sdio_irq.c [new file with mode: 0644]
drivers/mmc/core/sdio_ops.c [new file with mode: 0644]
drivers/mmc/core/sdio_ops.h [new file with mode: 0644]
drivers/mmc/host/Kconfig
drivers/mmc/host/Makefile
drivers/mmc/host/at91_mci.c
drivers/mmc/host/au1xmmc.c
drivers/mmc/host/imxmmc.c
drivers/mmc/host/mmc_spi.c [new file with mode: 0644]
drivers/mmc/host/mmci.c
drivers/mmc/host/omap.c
drivers/mmc/host/pxamci.c
drivers/mmc/host/pxamci.h
drivers/mmc/host/ricoh_mmc.c [new file with mode: 0644]
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/mmc/host/tifm_sd.c
drivers/mmc/host/wbsd.c
drivers/pci/hotplug/cpqphp_core.c
drivers/pci/hotplug/cpqphp_pci.c
drivers/pci/hotplug/ibmphp_core.c
drivers/serial/bfin_5xx.c
include/asm-arm/arch-imx/mmc.h
include/asm-avr32/arch-at32ap/board.h
include/asm-avr32/arch-at32ap/portmux.h
include/asm-avr32/arch-at32ap/smc.h
include/asm-avr32/dma-mapping.h
include/asm-avr32/system.h
include/asm-avr32/unistd.h
include/asm-blackfin/bfin5xx_spi.h
include/asm-blackfin/blackfin.h
include/asm-blackfin/cacheflush.h
include/asm-blackfin/cplb.h
include/asm-blackfin/dma.h
include/asm-blackfin/early_printk.h [new file with mode: 0644]
include/asm-blackfin/gpio.h
include/asm-blackfin/io.h
include/asm-blackfin/ioctls.h
include/asm-blackfin/irq_handler.h
include/asm-blackfin/kgdb.h
include/asm-blackfin/mach-bf527/anomaly.h [new file with mode: 0644]
include/asm-blackfin/mach-bf527/defBF52x_base.h
include/asm-blackfin/mach-bf533/anomaly.h
include/asm-blackfin/mach-bf533/bf533.h
include/asm-blackfin/mach-bf533/blackfin.h
include/asm-blackfin/mach-bf533/cdefBF532.h
include/asm-blackfin/mach-bf533/defBF532.h
include/asm-blackfin/mach-bf533/irq.h
include/asm-blackfin/mach-bf533/mem_map.h
include/asm-blackfin/mach-bf537/anomaly.h
include/asm-blackfin/mach-bf537/bf537.h
include/asm-blackfin/mach-bf537/blackfin.h
include/asm-blackfin/mach-bf537/cdefBF534.h
include/asm-blackfin/mach-bf537/defBF534.h
include/asm-blackfin/mach-bf537/irq.h
include/asm-blackfin/mach-bf537/mem_map.h
include/asm-blackfin/mach-bf537/portmux.h
include/asm-blackfin/mach-bf548/anomaly.h
include/asm-blackfin/mach-bf548/bf548.h
include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
include/asm-blackfin/mach-bf548/blackfin.h
include/asm-blackfin/mach-bf548/cdefBF54x_base.h
include/asm-blackfin/mach-bf548/defBF544.h
include/asm-blackfin/mach-bf548/defBF548.h
include/asm-blackfin/mach-bf548/defBF549.h
include/asm-blackfin/mach-bf548/defBF54x_base.h
include/asm-blackfin/mach-bf548/gpio.h
include/asm-blackfin/mach-bf548/irq.h
include/asm-blackfin/mach-bf548/mem_map.h
include/asm-blackfin/mach-bf561/anomaly.h
include/asm-blackfin/mach-bf561/bf561.h
include/asm-blackfin/mach-bf561/blackfin.h
include/asm-blackfin/mach-bf561/cdefBF561.h
include/asm-blackfin/mach-bf561/defBF561.h
include/asm-blackfin/mach-bf561/irq.h
include/asm-blackfin/mach-bf561/mem_map.h
include/asm-blackfin/mach-bf561/portmux.h
include/asm-blackfin/mach-common/cdef_LPBlackfin.h
include/asm-blackfin/mach-common/clocks.h [new file with mode: 0644]
include/asm-blackfin/mach-common/def_LPBlackfin.h
include/asm-blackfin/pgtable.h
include/asm-blackfin/reboot.h [new file with mode: 0644]
include/asm-blackfin/system.h
include/asm-blackfin/termbits.h
include/asm-blackfin/termios.h
include/asm-blackfin/trace.h
include/asm-i386/Kbuild [deleted file]
include/asm-i386/k8.h [deleted file]
include/asm-i386/pci-direct.h [deleted file]
include/asm-i386/stacktrace.h [deleted file]
include/asm-sh/mpc1211/mc146818rtc.h
include/asm-x86/8253pit.h [new file with mode: 0644]
include/asm-x86/8253pit_32.h [moved from include/asm-i386/8253pit.h with 100% similarity]
include/asm-x86/8253pit_64.h [moved from include/asm-x86_64/8253pit.h with 100% similarity]
include/asm-x86/Kbuild [new file with mode: 0644]
include/asm-x86/a.out.h [new file with mode: 0644]
include/asm-x86/a.out_32.h [moved from include/asm-i386/a.out.h with 100% similarity]
include/asm-x86/a.out_64.h [moved from include/asm-x86_64/a.out.h with 100% similarity]
include/asm-x86/acpi.h [new file with mode: 0644]
include/asm-x86/acpi_32.h [moved from include/asm-i386/acpi.h with 100% similarity]
include/asm-x86/acpi_64.h [moved from include/asm-x86_64/acpi.h with 100% similarity]
include/asm-x86/agp.h [new file with mode: 0644]
include/asm-x86/agp_32.h [moved from include/asm-i386/agp.h with 100% similarity]
include/asm-x86/agp_64.h [moved from include/asm-x86_64/agp.h with 100% similarity]
include/asm-x86/alternative-asm.i [new file with mode: 0644]
include/asm-x86/alternative-asm_32.i [moved from include/asm-i386/alternative-asm.i with 100% similarity]
include/asm-x86/alternative-asm_64.i [moved from include/asm-x86_64/alternative-asm.i with 100% similarity]
include/asm-x86/alternative.h [new file with mode: 0644]
include/asm-x86/alternative_32.h [moved from include/asm-i386/alternative.h with 100% similarity]
include/asm-x86/alternative_64.h [moved from include/asm-x86_64/alternative.h with 100% similarity]
include/asm-x86/apic.h [new file with mode: 0644]
include/asm-x86/apic_32.h [moved from include/asm-i386/apic.h with 100% similarity]
include/asm-x86/apic_64.h [moved from include/asm-x86_64/apic.h with 100% similarity]
include/asm-x86/apicdef.h [new file with mode: 0644]
include/asm-x86/apicdef_32.h [moved from include/asm-i386/apicdef.h with 100% similarity]
include/asm-x86/apicdef_64.h [moved from include/asm-x86_64/apicdef.h with 100% similarity]
include/asm-x86/arch_hooks.h [moved from include/asm-i386/arch_hooks.h with 100% similarity]
include/asm-x86/atomic.h [new file with mode: 0644]
include/asm-x86/atomic_32.h [moved from include/asm-i386/atomic.h with 100% similarity]
include/asm-x86/atomic_64.h [moved from include/asm-x86_64/atomic.h with 100% similarity]
include/asm-x86/auxvec.h [new file with mode: 0644]
include/asm-x86/auxvec_32.h [moved from include/asm-i386/auxvec.h with 100% similarity]
include/asm-x86/auxvec_64.h [moved from include/asm-x86_64/auxvec.h with 100% similarity]
include/asm-x86/bitops.h [new file with mode: 0644]
include/asm-x86/bitops_32.h [moved from include/asm-i386/bitops.h with 100% similarity]
include/asm-x86/bitops_64.h [moved from include/asm-x86_64/bitops.h with 100% similarity]
include/asm-x86/boot.h [moved from include/asm-i386/boot.h with 100% similarity]
include/asm-x86/bootparam.h [moved from include/asm-i386/bootparam.h with 100% similarity]
include/asm-x86/bootsetup.h [moved from include/asm-x86_64/bootsetup.h with 100% similarity]
include/asm-x86/bug.h [new file with mode: 0644]
include/asm-x86/bug_32.h [moved from include/asm-i386/bug.h with 100% similarity]
include/asm-x86/bug_64.h [moved from include/asm-x86_64/bug.h with 100% similarity]
include/asm-x86/bugs.h [new file with mode: 0644]
include/asm-x86/bugs_32.h [moved from include/asm-i386/bugs.h with 100% similarity]
include/asm-x86/bugs_64.h [moved from include/asm-x86_64/bugs.h with 100% similarity]
include/asm-x86/byteorder.h [new file with mode: 0644]
include/asm-x86/byteorder_32.h [moved from include/asm-i386/byteorder.h with 100% similarity]
include/asm-x86/byteorder_64.h [moved from include/asm-x86_64/byteorder.h with 100% similarity]
include/asm-x86/cache.h [new file with mode: 0644]
include/asm-x86/cache_32.h [moved from include/asm-i386/cache.h with 100% similarity]
include/asm-x86/cache_64.h [moved from include/asm-x86_64/cache.h with 100% similarity]
include/asm-x86/cacheflush.h [new file with mode: 0644]
include/asm-x86/cacheflush_32.h [moved from include/asm-i386/cacheflush.h with 100% similarity]
include/asm-x86/cacheflush_64.h [moved from include/asm-x86_64/cacheflush.h with 100% similarity]
include/asm-x86/calgary.h [moved from include/asm-x86_64/calgary.h with 100% similarity]
include/asm-x86/calling.h [moved from include/asm-x86_64/calling.h with 100% similarity]
include/asm-x86/checksum.h [new file with mode: 0644]
include/asm-x86/checksum_32.h [moved from include/asm-i386/checksum.h with 100% similarity]
include/asm-x86/checksum_64.h [moved from include/asm-x86_64/checksum.h with 100% similarity]
include/asm-x86/cmpxchg.h [new file with mode: 0644]
include/asm-x86/cmpxchg_32.h [moved from include/asm-i386/cmpxchg.h with 100% similarity]
include/asm-x86/cmpxchg_64.h [moved from include/asm-x86_64/cmpxchg.h with 100% similarity]
include/asm-x86/compat.h [moved from include/asm-x86_64/compat.h with 100% similarity]
include/asm-x86/cpu.h [moved from include/asm-i386/cpu.h with 100% similarity]
include/asm-x86/cpufeature.h [new file with mode: 0644]
include/asm-x86/cpufeature_32.h [moved from include/asm-i386/cpufeature.h with 100% similarity]
include/asm-x86/cpufeature_64.h [moved from include/asm-x86_64/cpufeature.h with 91% similarity]
include/asm-x86/cputime.h [new file with mode: 0644]
include/asm-x86/cputime_32.h [moved from include/asm-i386/cputime.h with 100% similarity]
include/asm-x86/cputime_64.h [moved from include/asm-x86_64/cputime.h with 100% similarity]
include/asm-x86/current.h [new file with mode: 0644]
include/asm-x86/current_32.h [moved from include/asm-i386/current.h with 100% similarity]
include/asm-x86/current_64.h [moved from include/asm-x86_64/current.h with 100% similarity]
include/asm-x86/debugreg.h [new file with mode: 0644]
include/asm-x86/debugreg_32.h [moved from include/asm-i386/debugreg.h with 100% similarity]
include/asm-x86/debugreg_64.h [moved from include/asm-x86_64/debugreg.h with 100% similarity]
include/asm-x86/delay.h [new file with mode: 0644]
include/asm-x86/delay_32.h [moved from include/asm-i386/delay.h with 100% similarity]
include/asm-x86/delay_64.h [moved from include/asm-x86_64/delay.h with 100% similarity]
include/asm-x86/desc.h [new file with mode: 0644]
include/asm-x86/desc_32.h [moved from include/asm-i386/desc.h with 100% similarity]
include/asm-x86/desc_64.h [moved from include/asm-x86_64/desc.h with 100% similarity]
include/asm-x86/desc_defs.h [moved from include/asm-x86_64/desc_defs.h with 100% similarity]
include/asm-x86/device.h [new file with mode: 0644]
include/asm-x86/device_32.h [moved from include/asm-i386/device.h with 100% similarity]
include/asm-x86/device_64.h [moved from include/asm-x86_64/device.h with 100% similarity]
include/asm-x86/div64.h [new file with mode: 0644]
include/asm-x86/div64_32.h [moved from include/asm-i386/div64.h with 100% similarity]
include/asm-x86/div64_64.h [moved from include/asm-x86_64/div64.h with 100% similarity]
include/asm-x86/dma-mapping.h [new file with mode: 0644]
include/asm-x86/dma-mapping_32.h [moved from include/asm-i386/dma-mapping.h with 100% similarity]
include/asm-x86/dma-mapping_64.h [moved from include/asm-x86_64/dma-mapping.h with 100% similarity]
include/asm-x86/dma.h [new file with mode: 0644]
include/asm-x86/dma_32.h [moved from include/asm-i386/dma.h with 100% similarity]
include/asm-x86/dma_64.h [moved from include/asm-x86_64/dma.h with 100% similarity]
include/asm-x86/dmi.h [new file with mode: 0644]
include/asm-x86/dmi_32.h [moved from include/asm-i386/dmi.h with 100% similarity]
include/asm-x86/dmi_64.h [moved from include/asm-x86_64/dmi.h with 100% similarity]
include/asm-x86/dwarf2.h [new file with mode: 0644]
include/asm-x86/dwarf2_32.h [moved from include/asm-i386/dwarf2.h with 100% similarity]
include/asm-x86/dwarf2_64.h [moved from include/asm-x86_64/dwarf2.h with 100% similarity]
include/asm-x86/e820.h [new file with mode: 0644]
include/asm-x86/e820_32.h [moved from include/asm-i386/e820.h with 100% similarity]
include/asm-x86/e820_64.h [moved from include/asm-x86_64/e820.h with 100% similarity]
include/asm-x86/edac.h [new file with mode: 0644]
include/asm-x86/edac_32.h [moved from include/asm-i386/edac.h with 100% similarity]
include/asm-x86/edac_64.h [moved from include/asm-x86_64/edac.h with 100% similarity]
include/asm-x86/elf.h [new file with mode: 0644]
include/asm-x86/elf_32.h [moved from include/asm-i386/elf.h with 100% similarity]
include/asm-x86/elf_64.h [moved from include/asm-x86_64/elf.h with 100% similarity]
include/asm-x86/emergency-restart.h [moved from include/asm-i386/emergency-restart.h with 100% similarity]
include/asm-x86/errno.h [new file with mode: 0644]
include/asm-x86/errno_32.h [moved from include/asm-i386/errno.h with 100% similarity]
include/asm-x86/errno_64.h [moved from include/asm-x86_64/errno.h with 100% similarity]
include/asm-x86/fb.h [new file with mode: 0644]
include/asm-x86/fb_32.h [moved from include/asm-i386/fb.h with 100% similarity]
include/asm-x86/fb_64.h [moved from include/asm-x86_64/fb.h with 100% similarity]
include/asm-x86/fcntl.h [moved from include/asm-i386/fcntl.h with 100% similarity]
include/asm-x86/fixmap.h [new file with mode: 0644]
include/asm-x86/fixmap_32.h [moved from include/asm-i386/fixmap.h with 100% similarity]
include/asm-x86/fixmap_64.h [moved from include/asm-x86_64/fixmap.h with 100% similarity]
include/asm-x86/floppy.h [new file with mode: 0644]
include/asm-x86/floppy_32.h [moved from include/asm-i386/floppy.h with 100% similarity]
include/asm-x86/floppy_64.h [moved from include/asm-x86_64/floppy.h with 100% similarity]
include/asm-x86/fpu32.h [moved from include/asm-x86_64/fpu32.h with 100% similarity]
include/asm-x86/frame.i [moved from include/asm-i386/frame.i with 100% similarity]
include/asm-x86/futex.h [new file with mode: 0644]
include/asm-x86/futex_32.h [moved from include/asm-i386/futex.h with 100% similarity]
include/asm-x86/futex_64.h [moved from include/asm-x86_64/futex.h with 100% similarity]
include/asm-x86/genapic.h [new file with mode: 0644]
include/asm-x86/genapic_32.h [moved from include/asm-i386/genapic.h with 100% similarity]
include/asm-x86/genapic_64.h [moved from include/asm-x86_64/genapic.h with 100% similarity]
include/asm-x86/geode.h [moved from include/asm-i386/geode.h with 100% similarity]
include/asm-x86/hardirq.h [new file with mode: 0644]
include/asm-x86/hardirq_32.h [moved from include/asm-i386/hardirq.h with 100% similarity]
include/asm-x86/hardirq_64.h [moved from include/asm-x86_64/hardirq.h with 100% similarity]
include/asm-x86/highmem.h [moved from include/asm-i386/highmem.h with 100% similarity]
include/asm-x86/hpet.h [new file with mode: 0644]
include/asm-x86/hpet_32.h [moved from include/asm-i386/hpet.h with 100% similarity]
include/asm-x86/hpet_64.h [moved from include/asm-x86_64/hpet.h with 93% similarity]
include/asm-x86/hw_irq.h [new file with mode: 0644]
include/asm-x86/hw_irq_32.h [moved from include/asm-i386/hw_irq.h with 100% similarity]
include/asm-x86/hw_irq_64.h [moved from include/asm-x86_64/hw_irq.h with 100% similarity]
include/asm-x86/hypertransport.h [moved from include/asm-i386/hypertransport.h with 100% similarity]
include/asm-x86/i387.h [new file with mode: 0644]
include/asm-x86/i387_32.h [moved from include/asm-i386/i387.h with 100% similarity]
include/asm-x86/i387_64.h [moved from include/asm-x86_64/i387.h with 100% similarity]
include/asm-x86/i8253.h [new file with mode: 0644]
include/asm-x86/i8253_32.h [moved from include/asm-i386/i8253.h with 100% similarity]
include/asm-x86/i8253_64.h [moved from include/asm-x86_64/i8253.h with 100% similarity]
include/asm-x86/i8259.h [moved from include/asm-i386/i8259.h with 100% similarity]
include/asm-x86/ia32.h [moved from include/asm-x86_64/ia32.h with 100% similarity]
include/asm-x86/ia32_unistd.h [moved from include/asm-x86_64/ia32_unistd.h with 100% similarity]
include/asm-x86/ide.h [moved from include/asm-i386/ide.h with 100% similarity]
include/asm-x86/idle.h [moved from include/asm-x86_64/idle.h with 100% similarity]
include/asm-x86/intel_arch_perfmon.h [new file with mode: 0644]
include/asm-x86/intel_arch_perfmon_32.h [moved from include/asm-i386/intel_arch_perfmon.h with 100% similarity]
include/asm-x86/intel_arch_perfmon_64.h [moved from include/asm-x86_64/intel_arch_perfmon.h with 100% similarity]
include/asm-x86/io.h [new file with mode: 0644]
include/asm-x86/io_32.h [moved from include/asm-i386/io.h with 100% similarity]
include/asm-x86/io_64.h [moved from include/asm-x86_64/io.h with 100% similarity]
include/asm-x86/io_apic.h [new file with mode: 0644]
include/asm-x86/io_apic_32.h [moved from include/asm-i386/io_apic.h with 100% similarity]
include/asm-x86/io_apic_64.h [moved from include/asm-x86_64/io_apic.h with 100% similarity]
include/asm-x86/ioctl.h [moved from include/asm-i386/ioctl.h with 100% similarity]
include/asm-x86/ioctls.h [new file with mode: 0644]
include/asm-x86/ioctls_32.h [moved from include/asm-i386/ioctls.h with 100% similarity]
include/asm-x86/ioctls_64.h [moved from include/asm-x86_64/ioctls.h with 100% similarity]
include/asm-x86/iommu.h [moved from include/asm-x86_64/iommu.h with 100% similarity]
include/asm-x86/ipc.h [moved from include/asm-i386/ipc.h with 100% similarity]
include/asm-x86/ipcbuf.h [new file with mode: 0644]
include/asm-x86/ipcbuf_32.h [moved from include/asm-i386/ipcbuf.h with 100% similarity]
include/asm-x86/ipcbuf_64.h [moved from include/asm-x86_64/ipcbuf.h with 100% similarity]
include/asm-x86/ipi.h [moved from include/asm-x86_64/ipi.h with 100% similarity]
include/asm-x86/irq.h [new file with mode: 0644]
include/asm-x86/irq_32.h [moved from include/asm-i386/irq.h with 100% similarity]
include/asm-x86/irq_64.h [moved from include/asm-x86_64/irq.h with 100% similarity]
include/asm-x86/irq_regs.h [new file with mode: 0644]
include/asm-x86/irq_regs_32.h [moved from include/asm-i386/irq_regs.h with 100% similarity]
include/asm-x86/irq_regs_64.h [moved from include/asm-x86_64/irq_regs.h with 100% similarity]
include/asm-x86/irqflags.h [new file with mode: 0644]
include/asm-x86/irqflags_32.h [moved from include/asm-i386/irqflags.h with 100% similarity]
include/asm-x86/irqflags_64.h [moved from include/asm-x86_64/irqflags.h with 100% similarity]
include/asm-x86/ist.h [moved from include/asm-i386/ist.h with 100% similarity]
include/asm-x86/k8.h [moved from include/asm-x86_64/k8.h with 100% similarity]
include/asm-x86/kdebug.h [new file with mode: 0644]
include/asm-x86/kdebug_32.h [moved from include/asm-i386/kdebug.h with 100% similarity]
include/asm-x86/kdebug_64.h [moved from include/asm-x86_64/kdebug.h with 100% similarity]
include/asm-x86/kexec.h [new file with mode: 0644]
include/asm-x86/kexec_32.h [moved from include/asm-i386/kexec.h with 100% similarity]
include/asm-x86/kexec_64.h [moved from include/asm-x86_64/kexec.h with 100% similarity]
include/asm-x86/kmap_types.h [new file with mode: 0644]
include/asm-x86/kmap_types_32.h [moved from include/asm-i386/kmap_types.h with 100% similarity]
include/asm-x86/kmap_types_64.h [moved from include/asm-x86_64/kmap_types.h with 100% similarity]
include/asm-x86/kprobes.h [new file with mode: 0644]
include/asm-x86/kprobes_32.h [moved from include/asm-i386/kprobes.h with 100% similarity]
include/asm-x86/kprobes_64.h [moved from include/asm-x86_64/kprobes.h with 100% similarity]
include/asm-x86/ldt.h [new file with mode: 0644]
include/asm-x86/ldt_32.h [moved from include/asm-i386/ldt.h with 100% similarity]
include/asm-x86/ldt_64.h [moved from include/asm-x86_64/ldt.h with 100% similarity]
include/asm-x86/linkage.h [new file with mode: 0644]
include/asm-x86/linkage_32.h [moved from include/asm-i386/linkage.h with 100% similarity]
include/asm-x86/linkage_64.h [moved from include/asm-x86_64/linkage.h with 100% similarity]
include/asm-x86/local.h [new file with mode: 0644]
include/asm-x86/local_32.h [moved from include/asm-i386/local.h with 100% similarity]
include/asm-x86/local_64.h [moved from include/asm-x86_64/local.h with 100% similarity]
include/asm-x86/mach-bigsmp/mach_apic.h [moved from include/asm-i386/mach-bigsmp/mach_apic.h with 100% similarity]
include/asm-x86/mach-bigsmp/mach_apicdef.h [moved from include/asm-i386/mach-bigsmp/mach_apicdef.h with 100% similarity]
include/asm-x86/mach-bigsmp/mach_ipi.h [moved from include/asm-i386/mach-bigsmp/mach_ipi.h with 100% similarity]
include/asm-x86/mach-bigsmp/mach_mpspec.h [moved from include/asm-i386/mach-bigsmp/mach_mpspec.h with 100% similarity]
include/asm-x86/mach-default/apm.h [moved from include/asm-i386/mach-default/apm.h with 100% similarity]
include/asm-x86/mach-default/bios_ebda.h [moved from include/asm-i386/mach-default/bios_ebda.h with 100% similarity]
include/asm-x86/mach-default/do_timer.h [moved from include/asm-i386/mach-default/do_timer.h with 100% similarity]
include/asm-x86/mach-default/entry_arch.h [moved from include/asm-i386/mach-default/entry_arch.h with 100% similarity]
include/asm-x86/mach-default/io_ports.h [moved from include/asm-i386/mach-default/io_ports.h with 100% similarity]
include/asm-x86/mach-default/irq_vectors.h [moved from include/asm-i386/mach-default/irq_vectors.h with 100% similarity]
include/asm-x86/mach-default/irq_vectors_limits.h [moved from include/asm-i386/mach-default/irq_vectors_limits.h with 100% similarity]
include/asm-x86/mach-default/mach_apic.h [moved from include/asm-i386/mach-default/mach_apic.h with 100% similarity]
include/asm-x86/mach-default/mach_apicdef.h [moved from include/asm-i386/mach-default/mach_apicdef.h with 100% similarity]
include/asm-x86/mach-default/mach_ipi.h [moved from include/asm-i386/mach-default/mach_ipi.h with 100% similarity]
include/asm-x86/mach-default/mach_mpparse.h [moved from include/asm-i386/mach-default/mach_mpparse.h with 100% similarity]
include/asm-x86/mach-default/mach_mpspec.h [moved from include/asm-i386/mach-default/mach_mpspec.h with 100% similarity]
include/asm-x86/mach-default/mach_reboot.h [moved from include/asm-i386/mach-default/mach_reboot.h with 100% similarity]
include/asm-x86/mach-default/mach_time.h [moved from include/asm-i386/mach-default/mach_time.h with 100% similarity]
include/asm-x86/mach-default/mach_timer.h [moved from include/asm-i386/mach-default/mach_timer.h with 100% similarity]
include/asm-x86/mach-default/mach_traps.h [moved from include/asm-i386/mach-default/mach_traps.h with 100% similarity]
include/asm-x86/mach-default/mach_wakecpu.h [moved from include/asm-i386/mach-default/mach_wakecpu.h with 100% similarity]
include/asm-x86/mach-default/pci-functions.h [moved from include/asm-i386/mach-default/pci-functions.h with 100% similarity]
include/asm-x86/mach-default/setup_arch.h [moved from include/asm-i386/mach-default/setup_arch.h with 100% similarity]
include/asm-x86/mach-default/smpboot_hooks.h [moved from include/asm-i386/mach-default/smpboot_hooks.h with 100% similarity]
include/asm-x86/mach-es7000/mach_apic.h [moved from include/asm-i386/mach-es7000/mach_apic.h with 100% similarity]
include/asm-x86/mach-es7000/mach_apicdef.h [moved from include/asm-i386/mach-es7000/mach_apicdef.h with 100% similarity]
include/asm-x86/mach-es7000/mach_ipi.h [moved from include/asm-i386/mach-es7000/mach_ipi.h with 100% similarity]
include/asm-x86/mach-es7000/mach_mpparse.h [moved from include/asm-i386/mach-es7000/mach_mpparse.h with 100% similarity]
include/asm-x86/mach-es7000/mach_mpspec.h [moved from include/asm-i386/mach-es7000/mach_mpspec.h with 100% similarity]
include/asm-x86/mach-es7000/mach_wakecpu.h [moved from include/asm-i386/mach-es7000/mach_wakecpu.h with 100% similarity]
include/asm-x86/mach-generic/irq_vectors_limits.h [moved from include/asm-i386/mach-generic/irq_vectors_limits.h with 100% similarity]
include/asm-x86/mach-generic/mach_apic.h [moved from include/asm-i386/mach-generic/mach_apic.h with 100% similarity]
include/asm-x86/mach-generic/mach_apicdef.h [moved from include/asm-i386/mach-generic/mach_apicdef.h with 100% similarity]
include/asm-x86/mach-generic/mach_ipi.h [moved from include/asm-i386/mach-generic/mach_ipi.h with 100% similarity]
include/asm-x86/mach-generic/mach_mpparse.h [moved from include/asm-i386/mach-generic/mach_mpparse.h with 100% similarity]
include/asm-x86/mach-generic/mach_mpspec.h [moved from include/asm-i386/mach-generic/mach_mpspec.h with 100% similarity]
include/asm-x86/mach-numaq/mach_apic.h [moved from include/asm-i386/mach-numaq/mach_apic.h with 100% similarity]
include/asm-x86/mach-numaq/mach_apicdef.h [moved from include/asm-i386/mach-numaq/mach_apicdef.h with 100% similarity]
include/asm-x86/mach-numaq/mach_ipi.h [moved from include/asm-i386/mach-numaq/mach_ipi.h with 100% similarity]
include/asm-x86/mach-numaq/mach_mpparse.h [moved from include/asm-i386/mach-numaq/mach_mpparse.h with 100% similarity]
include/asm-x86/mach-numaq/mach_mpspec.h [moved from include/asm-i386/mach-numaq/mach_mpspec.h with 100% similarity]
include/asm-x86/mach-numaq/mach_wakecpu.h [moved from include/asm-i386/mach-numaq/mach_wakecpu.h with 100% similarity]
include/asm-x86/mach-summit/irq_vectors_limits.h [moved from include/asm-i386/mach-summit/irq_vectors_limits.h with 100% similarity]
include/asm-x86/mach-summit/mach_apic.h [moved from include/asm-i386/mach-summit/mach_apic.h with 100% similarity]
include/asm-x86/mach-summit/mach_apicdef.h [moved from include/asm-i386/mach-summit/mach_apicdef.h with 100% similarity]
include/asm-x86/mach-summit/mach_ipi.h [moved from include/asm-i386/mach-summit/mach_ipi.h with 100% similarity]
include/asm-x86/mach-summit/mach_mpparse.h [moved from include/asm-i386/mach-summit/mach_mpparse.h with 100% similarity]
include/asm-x86/mach-summit/mach_mpspec.h [moved from include/asm-i386/mach-summit/mach_mpspec.h with 100% similarity]
include/asm-x86/mach-visws/cobalt.h [moved from include/asm-i386/mach-visws/cobalt.h with 100% similarity]
include/asm-x86/mach-visws/entry_arch.h [moved from include/asm-i386/mach-visws/entry_arch.h with 100% similarity]
include/asm-x86/mach-visws/irq_vectors.h [moved from include/asm-i386/mach-visws/irq_vectors.h with 100% similarity]
include/asm-x86/mach-visws/lithium.h [moved from include/asm-i386/mach-visws/lithium.h with 100% similarity]
include/asm-x86/mach-visws/mach_apic.h [moved from include/asm-i386/mach-visws/mach_apic.h with 100% similarity]
include/asm-x86/mach-visws/mach_apicdef.h [moved from include/asm-i386/mach-visws/mach_apicdef.h with 100% similarity]
include/asm-x86/mach-visws/piix4.h [moved from include/asm-i386/mach-visws/piix4.h with 100% similarity]
include/asm-x86/mach-visws/setup_arch.h [moved from include/asm-i386/mach-visws/setup_arch.h with 100% similarity]
include/asm-x86/mach-visws/smpboot_hooks.h [moved from include/asm-i386/mach-visws/smpboot_hooks.h with 100% similarity]
include/asm-x86/mach-voyager/do_timer.h [moved from include/asm-i386/mach-voyager/do_timer.h with 100% similarity]
include/asm-x86/mach-voyager/entry_arch.h [moved from include/asm-i386/mach-voyager/entry_arch.h with 100% similarity]
include/asm-x86/mach-voyager/irq_vectors.h [moved from include/asm-i386/mach-voyager/irq_vectors.h with 100% similarity]
include/asm-x86/mach-voyager/setup_arch.h [moved from include/asm-i386/mach-voyager/setup_arch.h with 100% similarity]
include/asm-x86/mach_apic.h [moved from include/asm-x86_64/mach_apic.h with 100% similarity]
include/asm-x86/math_emu.h [moved from include/asm-i386/math_emu.h with 100% similarity]
include/asm-x86/mc146818rtc.h [new file with mode: 0644]
include/asm-x86/mc146818rtc_32.h [moved from include/asm-i386/mc146818rtc.h with 100% similarity]
include/asm-x86/mc146818rtc_64.h [moved from include/asm-x86_64/mc146818rtc.h with 100% similarity]
include/asm-x86/mca.h [moved from include/asm-i386/mca.h with 100% similarity]
include/asm-x86/mca_dma.h [moved from include/asm-i386/mca_dma.h with 100% similarity]
include/asm-x86/mce.h [new file with mode: 0644]
include/asm-x86/mce_32.h [moved from include/asm-i386/mce.h with 100% similarity]
include/asm-x86/mce_64.h [moved from include/asm-x86_64/mce.h with 100% similarity]
include/asm-x86/mman.h [new file with mode: 0644]
include/asm-x86/mman_32.h [moved from include/asm-i386/mman.h with 100% similarity]
include/asm-x86/mman_64.h [moved from include/asm-x86_64/mman.h with 100% similarity]
include/asm-x86/mmsegment.h [moved from include/asm-x86_64/mmsegment.h with 100% similarity]
include/asm-x86/mmu.h [new file with mode: 0644]
include/asm-x86/mmu_32.h [moved from include/asm-i386/mmu.h with 100% similarity]
include/asm-x86/mmu_64.h [moved from include/asm-x86_64/mmu.h with 100% similarity]
include/asm-x86/mmu_context.h [new file with mode: 0644]
include/asm-x86/mmu_context_32.h [moved from include/asm-i386/mmu_context.h with 100% similarity]
include/asm-x86/mmu_context_64.h [moved from include/asm-x86_64/mmu_context.h with 100% similarity]
include/asm-x86/mmx.h [moved from include/asm-i386/mmx.h with 100% similarity]
include/asm-x86/mmzone.h [new file with mode: 0644]
include/asm-x86/mmzone_32.h [moved from include/asm-i386/mmzone.h with 100% similarity]
include/asm-x86/mmzone_64.h [moved from include/asm-x86_64/mmzone.h with 100% similarity]
include/asm-x86/module.h [new file with mode: 0644]
include/asm-x86/module_32.h [moved from include/asm-i386/module.h with 100% similarity]
include/asm-x86/module_64.h [moved from include/asm-x86_64/module.h with 100% similarity]
include/asm-x86/mpspec.h [new file with mode: 0644]
include/asm-x86/mpspec_32.h [moved from include/asm-i386/mpspec.h with 100% similarity]
include/asm-x86/mpspec_64.h [moved from include/asm-x86_64/mpspec.h with 100% similarity]
include/asm-x86/mpspec_def.h [moved from include/asm-i386/mpspec_def.h with 100% similarity]
include/asm-x86/msgbuf.h [new file with mode: 0644]
include/asm-x86/msgbuf_32.h [moved from include/asm-i386/msgbuf.h with 100% similarity]
include/asm-x86/msgbuf_64.h [moved from include/asm-x86_64/msgbuf.h with 100% similarity]
include/asm-x86/msidef.h [moved from include/asm-i386/msidef.h with 100% similarity]
include/asm-x86/msr-index.h [moved from include/asm-i386/msr-index.h with 100% similarity]
include/asm-x86/msr.h [new file with mode: 0644]
include/asm-x86/msr_32.h [moved from include/asm-i386/msr.h with 100% similarity]
include/asm-x86/msr_64.h [moved from include/asm-x86_64/msr.h with 100% similarity]
include/asm-x86/mtrr.h [new file with mode: 0644]
include/asm-x86/mtrr_32.h [moved from include/asm-i386/mtrr.h with 100% similarity]
include/asm-x86/mtrr_64.h [moved from include/asm-x86_64/mtrr.h with 100% similarity]
include/asm-x86/mutex.h [new file with mode: 0644]
include/asm-x86/mutex_32.h [moved from include/asm-i386/mutex.h with 100% similarity]
include/asm-x86/mutex_64.h [moved from include/asm-x86_64/mutex.h with 100% similarity]
include/asm-x86/namei.h [new file with mode: 0644]
include/asm-x86/namei_32.h [moved from include/asm-i386/namei.h with 100% similarity]
include/asm-x86/namei_64.h [moved from include/asm-x86_64/namei.h with 100% similarity]
include/asm-x86/nmi.h [new file with mode: 0644]
include/asm-x86/nmi_32.h [moved from include/asm-i386/nmi.h with 100% similarity]
include/asm-x86/nmi_64.h [moved from include/asm-x86_64/nmi.h with 100% similarity]
include/asm-x86/numa.h [new file with mode: 0644]
include/asm-x86/numa_32.h [moved from include/asm-i386/numa.h with 100% similarity]
include/asm-x86/numa_64.h [moved from include/asm-x86_64/numa.h with 100% similarity]
include/asm-x86/numaq.h [moved from include/asm-i386/numaq.h with 100% similarity]
include/asm-x86/page.h [new file with mode: 0644]
include/asm-x86/page_32.h [moved from include/asm-i386/page.h with 100% similarity]
include/asm-x86/page_64.h [moved from include/asm-x86_64/page.h with 100% similarity]
include/asm-x86/param.h [new file with mode: 0644]
include/asm-x86/param_32.h [moved from include/asm-i386/param.h with 100% similarity]
include/asm-x86/param_64.h [moved from include/asm-x86_64/param.h with 100% similarity]
include/asm-x86/paravirt.h [moved from include/asm-i386/paravirt.h with 100% similarity]
include/asm-x86/parport.h [new file with mode: 0644]
include/asm-x86/parport_32.h [moved from include/asm-i386/parport.h with 100% similarity]
include/asm-x86/parport_64.h [moved from include/asm-x86_64/parport.h with 100% similarity]
include/asm-x86/pci-direct.h [moved from include/asm-x86_64/pci-direct.h with 100% similarity]
include/asm-x86/pci.h [new file with mode: 0644]
include/asm-x86/pci_32.h [moved from include/asm-i386/pci.h with 100% similarity]
include/asm-x86/pci_64.h [moved from include/asm-x86_64/pci.h with 100% similarity]
include/asm-x86/pda.h [moved from include/asm-x86_64/pda.h with 100% similarity]
include/asm-x86/percpu.h [new file with mode: 0644]
include/asm-x86/percpu_32.h [moved from include/asm-i386/percpu.h with 100% similarity]
include/asm-x86/percpu_64.h [moved from include/asm-x86_64/percpu.h with 100% similarity]
include/asm-x86/pgalloc.h [new file with mode: 0644]
include/asm-x86/pgalloc_32.h [moved from include/asm-i386/pgalloc.h with 100% similarity]
include/asm-x86/pgalloc_64.h [moved from include/asm-x86_64/pgalloc.h with 100% similarity]
include/asm-x86/pgtable-2level-defs.h [moved from include/asm-i386/pgtable-2level-defs.h with 100% similarity]
include/asm-x86/pgtable-2level.h [moved from include/asm-i386/pgtable-2level.h with 100% similarity]
include/asm-x86/pgtable-3level-defs.h [moved from include/asm-i386/pgtable-3level-defs.h with 100% similarity]
include/asm-x86/pgtable-3level.h [moved from include/asm-i386/pgtable-3level.h with 100% similarity]
include/asm-x86/pgtable.h [new file with mode: 0644]
include/asm-x86/pgtable_32.h [moved from include/asm-i386/pgtable.h with 100% similarity]
include/asm-x86/pgtable_64.h [moved from include/asm-x86_64/pgtable.h with 100% similarity]
include/asm-x86/poll.h [moved from include/asm-i386/poll.h with 100% similarity]
include/asm-x86/posix_types.h [new file with mode: 0644]
include/asm-x86/posix_types_32.h [moved from include/asm-i386/posix_types.h with 100% similarity]
include/asm-x86/posix_types_64.h [moved from include/asm-x86_64/posix_types.h with 100% similarity]
include/asm-x86/prctl.h [moved from include/asm-x86_64/prctl.h with 100% similarity]
include/asm-x86/processor-cyrix.h [moved from include/asm-i386/processor-cyrix.h with 100% similarity]
include/asm-x86/processor-flags.h [moved from include/asm-i386/processor-flags.h with 100% similarity]
include/asm-x86/processor.h [new file with mode: 0644]
include/asm-x86/processor_32.h [moved from include/asm-i386/processor.h with 100% similarity]
include/asm-x86/processor_64.h [moved from include/asm-x86_64/processor.h with 100% similarity]
include/asm-x86/proto.h [moved from include/asm-x86_64/proto.h with 100% similarity]
include/asm-x86/ptrace-abi.h [new file with mode: 0644]
include/asm-x86/ptrace-abi_32.h [moved from include/asm-i386/ptrace-abi.h with 100% similarity]
include/asm-x86/ptrace-abi_64.h [moved from include/asm-x86_64/ptrace-abi.h with 100% similarity]
include/asm-x86/ptrace.h [new file with mode: 0644]
include/asm-x86/ptrace_32.h [moved from include/asm-i386/ptrace.h with 100% similarity]
include/asm-x86/ptrace_64.h [moved from include/asm-x86_64/ptrace.h with 100% similarity]
include/asm-x86/reboot.h [moved from include/asm-i386/reboot.h with 100% similarity]
include/asm-x86/reboot_fixups.h [moved from include/asm-i386/reboot_fixups.h with 100% similarity]
include/asm-x86/required-features.h [new file with mode: 0644]
include/asm-x86/required-features_32.h [moved from include/asm-i386/required-features.h with 100% similarity]
include/asm-x86/required-features_64.h [moved from include/asm-x86_64/required-features.h with 100% similarity]
include/asm-x86/resource.h [new file with mode: 0644]
include/asm-x86/resource_32.h [moved from include/asm-i386/resource.h with 100% similarity]
include/asm-x86/resource_64.h [moved from include/asm-x86_64/resource.h with 100% similarity]
include/asm-x86/resume-trace.h [new file with mode: 0644]
include/asm-x86/resume-trace_32.h [moved from include/asm-i386/resume-trace.h with 100% similarity]
include/asm-x86/resume-trace_64.h [moved from include/asm-x86_64/resume-trace.h with 100% similarity]
include/asm-x86/rio.h [moved from include/asm-x86_64/rio.h with 100% similarity]
include/asm-x86/rtc.h [new file with mode: 0644]
include/asm-x86/rtc_32.h [moved from include/asm-i386/rtc.h with 100% similarity]
include/asm-x86/rtc_64.h [moved from include/asm-x86_64/rtc.h with 100% similarity]
include/asm-x86/rwlock.h [new file with mode: 0644]
include/asm-x86/rwlock_32.h [moved from include/asm-i386/rwlock.h with 100% similarity]
include/asm-x86/rwlock_64.h [moved from include/asm-x86_64/rwlock.h with 100% similarity]
include/asm-x86/rwsem.h [moved from include/asm-i386/rwsem.h with 100% similarity]
include/asm-x86/scatterlist.h [new file with mode: 0644]
include/asm-x86/scatterlist_32.h [moved from include/asm-i386/scatterlist.h with 100% similarity]
include/asm-x86/scatterlist_64.h [moved from include/asm-x86_64/scatterlist.h with 100% similarity]
include/asm-x86/seccomp.h [new file with mode: 0644]
include/asm-x86/seccomp_32.h [moved from include/asm-i386/seccomp.h with 100% similarity]
include/asm-x86/seccomp_64.h [moved from include/asm-x86_64/seccomp.h with 100% similarity]
include/asm-x86/sections.h [new file with mode: 0644]
include/asm-x86/sections_32.h [moved from include/asm-i386/sections.h with 100% similarity]
include/asm-x86/sections_64.h [moved from include/asm-x86_64/sections.h with 100% similarity]
include/asm-x86/segment.h [new file with mode: 0644]
include/asm-x86/segment_32.h [moved from include/asm-i386/segment.h with 100% similarity]
include/asm-x86/segment_64.h [moved from include/asm-x86_64/segment.h with 100% similarity]
include/asm-x86/semaphore.h [new file with mode: 0644]
include/asm-x86/semaphore_32.h [moved from include/asm-i386/semaphore.h with 100% similarity]
include/asm-x86/semaphore_64.h [moved from include/asm-x86_64/semaphore.h with 100% similarity]
include/asm-x86/sembuf.h [new file with mode: 0644]
include/asm-x86/sembuf_32.h [moved from include/asm-i386/sembuf.h with 100% similarity]
include/asm-x86/sembuf_64.h [moved from include/asm-x86_64/sembuf.h with 100% similarity]
include/asm-x86/serial.h [new file with mode: 0644]
include/asm-x86/serial_32.h [moved from include/asm-i386/serial.h with 100% similarity]
include/asm-x86/serial_64.h [moved from include/asm-x86_64/serial.h with 100% similarity]
include/asm-x86/setup.h [new file with mode: 0644]
include/asm-x86/setup_32.h [moved from include/asm-i386/setup.h with 100% similarity]
include/asm-x86/setup_64.h [moved from include/asm-x86_64/setup.h with 100% similarity]
include/asm-x86/shmbuf.h [new file with mode: 0644]
include/asm-x86/shmbuf_32.h [moved from include/asm-i386/shmbuf.h with 100% similarity]
include/asm-x86/shmbuf_64.h [moved from include/asm-x86_64/shmbuf.h with 100% similarity]
include/asm-x86/shmparam.h [new file with mode: 0644]
include/asm-x86/shmparam_32.h [moved from include/asm-i386/shmparam.h with 100% similarity]
include/asm-x86/shmparam_64.h [moved from include/asm-x86_64/shmparam.h with 100% similarity]
include/asm-x86/sigcontext.h [new file with mode: 0644]
include/asm-x86/sigcontext32.h [moved from include/asm-x86_64/sigcontext32.h with 100% similarity]
include/asm-x86/sigcontext_32.h [moved from include/asm-i386/sigcontext.h with 100% similarity]
include/asm-x86/sigcontext_64.h [moved from include/asm-x86_64/sigcontext.h with 100% similarity]
include/asm-x86/siginfo.h [new file with mode: 0644]
include/asm-x86/siginfo_32.h [moved from include/asm-i386/siginfo.h with 100% similarity]
include/asm-x86/siginfo_64.h [moved from include/asm-x86_64/siginfo.h with 100% similarity]
include/asm-x86/signal.h [new file with mode: 0644]
include/asm-x86/signal_32.h [moved from include/asm-i386/signal.h with 100% similarity]
include/asm-x86/signal_64.h [moved from include/asm-x86_64/signal.h with 100% similarity]
include/asm-x86/smp.h [new file with mode: 0644]
include/asm-x86/smp_32.h [moved from include/asm-i386/smp.h with 100% similarity]
include/asm-x86/smp_64.h [moved from include/asm-x86_64/smp.h with 100% similarity]
include/asm-x86/socket.h [moved from include/asm-i386/socket.h with 100% similarity]
include/asm-x86/sockios.h [new file with mode: 0644]
include/asm-x86/sockios_32.h [moved from include/asm-i386/sockios.h with 100% similarity]
include/asm-x86/sockios_64.h [moved from include/asm-x86_64/sockios.h with 100% similarity]
include/asm-x86/sparsemem.h [new file with mode: 0644]
include/asm-x86/sparsemem_32.h [moved from include/asm-i386/sparsemem.h with 100% similarity]
include/asm-x86/sparsemem_64.h [moved from include/asm-x86_64/sparsemem.h with 100% similarity]
include/asm-x86/spinlock.h [new file with mode: 0644]
include/asm-x86/spinlock_32.h [moved from include/asm-i386/spinlock.h with 100% similarity]
include/asm-x86/spinlock_64.h [moved from include/asm-x86_64/spinlock.h with 100% similarity]
include/asm-x86/spinlock_types.h [moved from include/asm-i386/spinlock_types.h with 100% similarity]
include/asm-x86/srat.h [moved from include/asm-i386/srat.h with 100% similarity]
include/asm-x86/stacktrace.h [moved from include/asm-x86_64/stacktrace.h with 100% similarity]
include/asm-x86/stat.h [new file with mode: 0644]
include/asm-x86/stat_32.h [moved from include/asm-i386/stat.h with 100% similarity]
include/asm-x86/stat_64.h [moved from include/asm-x86_64/stat.h with 100% similarity]
include/asm-x86/statfs.h [new file with mode: 0644]
include/asm-x86/statfs_32.h [moved from include/asm-i386/statfs.h with 100% similarity]
include/asm-x86/statfs_64.h [moved from include/asm-x86_64/statfs.h with 100% similarity]
include/asm-x86/string.h [new file with mode: 0644]
include/asm-x86/string_32.h [moved from include/asm-i386/string.h with 100% similarity]
include/asm-x86/string_64.h [moved from include/asm-x86_64/string.h with 100% similarity]
include/asm-x86/suspend.h [new file with mode: 0644]
include/asm-x86/suspend_32.h [moved from include/asm-i386/suspend.h with 100% similarity]
include/asm-x86/suspend_64.h [moved from include/asm-x86_64/suspend.h with 100% similarity]
include/asm-x86/swiotlb.h [moved from include/asm-x86_64/swiotlb.h with 100% similarity]
include/asm-x86/sync_bitops.h [moved from include/asm-i386/sync_bitops.h with 100% similarity]
include/asm-x86/system.h [new file with mode: 0644]
include/asm-x86/system_32.h [moved from include/asm-i386/system.h with 100% similarity]
include/asm-x86/system_64.h [moved from include/asm-x86_64/system.h with 100% similarity]
include/asm-x86/tce.h [moved from include/asm-x86_64/tce.h with 100% similarity]
include/asm-x86/termbits.h [new file with mode: 0644]
include/asm-x86/termbits_32.h [moved from include/asm-i386/termbits.h with 100% similarity]
include/asm-x86/termbits_64.h [moved from include/asm-x86_64/termbits.h with 100% similarity]
include/asm-x86/termios.h [new file with mode: 0644]
include/asm-x86/termios_32.h [moved from include/asm-i386/termios.h with 99% similarity]
include/asm-x86/termios_64.h [moved from include/asm-x86_64/termios.h with 100% similarity]
include/asm-x86/therm_throt.h [moved from include/asm-i386/therm_throt.h with 100% similarity]
include/asm-x86/thread_info.h [new file with mode: 0644]
include/asm-x86/thread_info_32.h [moved from include/asm-i386/thread_info.h with 100% similarity]
include/asm-x86/thread_info_64.h [moved from include/asm-x86_64/thread_info.h with 100% similarity]
include/asm-x86/time.h [moved from include/asm-i386/time.h with 100% similarity]
include/asm-x86/timer.h [moved from include/asm-i386/timer.h with 100% similarity]
include/asm-x86/timex.h [new file with mode: 0644]
include/asm-x86/timex_32.h [moved from include/asm-i386/timex.h with 100% similarity]
include/asm-x86/timex_64.h [moved from include/asm-x86_64/timex.h with 100% similarity]
include/asm-x86/tlb.h [new file with mode: 0644]
include/asm-x86/tlb_32.h [moved from include/asm-i386/tlb.h with 100% similarity]
include/asm-x86/tlb_64.h [moved from include/asm-x86_64/tlb.h with 100% similarity]
include/asm-x86/tlbflush.h [new file with mode: 0644]
include/asm-x86/tlbflush_32.h [moved from include/asm-i386/tlbflush.h with 100% similarity]
include/asm-x86/tlbflush_64.h [moved from include/asm-x86_64/tlbflush.h with 100% similarity]
include/asm-x86/topology.h [new file with mode: 0644]
include/asm-x86/topology_32.h [moved from include/asm-i386/topology.h with 100% similarity]
include/asm-x86/topology_64.h [moved from include/asm-x86_64/topology.h with 100% similarity]
include/asm-x86/tsc.h [moved from include/asm-i386/tsc.h with 100% similarity]
include/asm-x86/types.h [new file with mode: 0644]
include/asm-x86/types_32.h [moved from include/asm-i386/types.h with 100% similarity]
include/asm-x86/types_64.h [moved from include/asm-x86_64/types.h with 100% similarity]
include/asm-x86/uaccess.h [new file with mode: 0644]
include/asm-x86/uaccess_32.h [moved from include/asm-i386/uaccess.h with 100% similarity]
include/asm-x86/uaccess_64.h [moved from include/asm-x86_64/uaccess.h with 100% similarity]
include/asm-x86/ucontext.h [new file with mode: 0644]
include/asm-x86/ucontext_32.h [moved from include/asm-i386/ucontext.h with 100% similarity]
include/asm-x86/ucontext_64.h [moved from include/asm-x86_64/ucontext.h with 100% similarity]
include/asm-x86/unaligned.h [new file with mode: 0644]
include/asm-x86/unaligned_32.h [moved from include/asm-i386/unaligned.h with 100% similarity]
include/asm-x86/unaligned_64.h [moved from include/asm-x86_64/unaligned.h with 100% similarity]
include/asm-x86/unistd.h [new file with mode: 0644]
include/asm-x86/unistd_32.h [moved from include/asm-i386/unistd.h with 100% similarity]
include/asm-x86/unistd_64.h [moved from include/asm-x86_64/unistd.h with 100% similarity]
include/asm-x86/unwind.h [new file with mode: 0644]
include/asm-x86/unwind_32.h [moved from include/asm-i386/unwind.h with 100% similarity]
include/asm-x86/unwind_64.h [moved from include/asm-x86_64/unwind.h with 100% similarity]
include/asm-x86/user.h [new file with mode: 0644]
include/asm-x86/user32.h [moved from include/asm-x86_64/user32.h with 100% similarity]
include/asm-x86/user_32.h [moved from include/asm-i386/user.h with 100% similarity]
include/asm-x86/user_64.h [moved from include/asm-x86_64/user.h with 100% similarity]
include/asm-x86/vga.h [moved from include/asm-i386/vga.h with 100% similarity]
include/asm-x86/vgtod.h [moved from include/asm-x86_64/vgtod.h with 100% similarity]
include/asm-x86/vic.h [moved from include/asm-i386/vic.h with 100% similarity]
include/asm-x86/vm86.h [moved from include/asm-i386/vm86.h with 100% similarity]
include/asm-x86/vmi.h [moved from include/asm-i386/vmi.h with 100% similarity]
include/asm-x86/vmi_time.h [moved from include/asm-i386/vmi_time.h with 100% similarity]
include/asm-x86/voyager.h [moved from include/asm-i386/voyager.h with 100% similarity]
include/asm-x86/vsyscall.h [moved from include/asm-x86_64/vsyscall.h with 100% similarity]
include/asm-x86/vsyscall32.h [moved from include/asm-x86_64/vsyscall32.h with 100% similarity]
include/asm-x86/xen/hypercall.h [moved from include/asm-i386/xen/hypercall.h with 100% similarity]
include/asm-x86/xen/hypervisor.h [moved from include/asm-i386/xen/hypervisor.h with 100% similarity]
include/asm-x86/xen/interface.h [moved from include/asm-i386/xen/interface.h with 100% similarity]
include/asm-x86/xor.h [new file with mode: 0644]
include/asm-x86/xor_32.h [moved from include/asm-i386/xor.h with 100% similarity]
include/asm-x86/xor_64.h [moved from include/asm-x86_64/xor.h with 100% similarity]
include/asm-x86_64/Kbuild [deleted file]
include/asm-x86_64/boot.h [deleted file]
include/asm-x86_64/bootparam.h [deleted file]
include/asm-x86_64/cpu.h [deleted file]
include/asm-x86_64/emergency-restart.h [deleted file]
include/asm-x86_64/fcntl.h [deleted file]
include/asm-x86_64/hypertransport.h [deleted file]
include/asm-x86_64/ide.h [deleted file]
include/asm-x86_64/ioctl.h [deleted file]
include/asm-x86_64/ist.h [deleted file]
include/asm-x86_64/msidef.h [deleted file]
include/asm-x86_64/msr-index.h [deleted file]
include/asm-x86_64/node.h [deleted file]
include/asm-x86_64/poll.h [deleted file]
include/asm-x86_64/processor-flags.h [deleted file]
include/asm-x86_64/socket.h [deleted file]
include/asm-x86_64/spinlock_types.h [deleted file]
include/asm-x86_64/therm_throt.h [deleted file]
include/asm-x86_64/tsc.h [deleted file]
include/asm-x86_64/vga.h [deleted file]
include/linux/i2c-id.h
include/linux/ivtv.h [moved from include/media/ivtv.h with 93% similarity]
include/linux/ivtvfb.h [moved from drivers/media/video/ivtv/ivtv-video.h with 56% similarity]
include/linux/mmc/card.h
include/linux/mmc/core.h
include/linux/mmc/host.h
include/linux/mmc/mmc.h
include/linux/mmc/sdio.h [new file with mode: 0644]
include/linux/mmc/sdio_func.h [new file with mode: 0644]
include/linux/mmc/sdio_ids.h [new file with mode: 0644]
include/linux/mod_devicetable.h
include/linux/pci_ids.h
include/linux/spi/mmc_spi.h [new file with mode: 0644]
include/linux/videodev2.h
include/media/cx2341x.h
include/media/ir-common.h
include/media/saa7146.h
include/media/saa7146_vv.h
include/media/tuner-types.h
include/media/tuner.h
include/media/v4l2-chip-ident.h
include/media/v4l2-dev.h
include/media/v4l2-int-device.h [new file with mode: 0644]
include/media/videobuf-core.h [moved from include/media/video-buf.h with 56% similarity]
include/media/videobuf-dma-sg.h [new file with mode: 0644]
include/media/videobuf-dvb.h [moved from include/media/video-buf-dvb.h with 100% similarity]
include/media/videobuf-vmalloc.h [new file with mode: 0644]
scripts/checkstack.pl
scripts/checksyscalls.sh
scripts/mod/file2alias.c
scripts/namespace.pl

index dbcedf5833eea25ce641caec237aae6ddd5cbd09..2511a335abd66a3ef4742592aa4212361bf7ea1f 100644 (file)
@@ -150,7 +150,7 @@ Some very frequently asked questions about linuxtv-dvb
        - saa7146_vv: SAA7146 video and vbi functions. These are only needed
          for full-featured cards.
 
-       - video-buf: capture helper module for the saa7146_vv driver. This
+       - videobuf-dma-sg: capture helper module for the saa7146_vv driver. This
          one is responsible to handle capture buffers.
 
        - dvb-ttpci: The main driver for AV7110 based, full-featured
index 00928d2ecfb229506b574271efdcb59dd105f02a..675f75601ae632a694fe06a0e8658b5039bf586f 100644 (file)
@@ -306,3 +306,11 @@ Why:    In kernel tree version of driver is unmaintained. Sk98lin driver
 Who:    Stephen Hemminger <shemminger@linux-foundation.org>
 
 ---------------------------
+
+What:  i386/x86_64 bzImage symlinks
+When:  April 2008
+
+Why:   The i386/x86_64 merge provides a symlink to the old bzImage
+       location so not yet updated user space tools, e.g. package
+       scripts, do not break.
+Who:   Thomas Gleixner <tglx@linutronix.de>
index 4d175c7512464671e14731239d5bf943b72c5614..a57c1f216b2154d352b6b3fc9b94a1f47d2cf0b1 100644 (file)
@@ -35,6 +35,7 @@ parameter is applicable:
        APIC    APIC support is enabled.
        APM     Advanced Power Management support is enabled.
        AX25    Appropriate AX.25 support is enabled.
+       BLACKFIN Blackfin architecture is enabled.
        DRM     Direct Rendering Management support is enabled.
        EDD     BIOS Enhanced Disk Drive Services (EDD) is enabled
        EFI     EFI Partitioning (GPT) is enabled
@@ -550,7 +551,7 @@ and is between 256 and 4096 characters. It is defined in the file
 
        dtc3181e=       [HW,SCSI]
 
-       earlyprintk=    [X86-32,X86-64,SH]
+       earlyprintk=    [X86-32,X86-64,SH,BLACKFIN]
                        earlyprintk=vga
                        earlyprintk=serial[,ttySn[,baudrate]]
 
index 73c5f1f3d5d2e726c287396224df53cfca1bc65d..103e346c8b6adc0f2f584fe491c55a3cefa82756 100644 (file)
@@ -46,7 +46,7 @@ typedef uint32_t u32;
 typedef uint16_t u16;
 typedef uint8_t u8;
 #include "../../include/linux/lguest_launcher.h"
-#include "../../include/asm-i386/e820.h"
+#include "../../include/asm-x86/e820_32.h"
 /*:*/
 
 #define PAGE_PRESENT 0x7       /* Present, RW, Execute */
index 177159c5f4c420fcb25b651698525d77544e2b7c..d97cf7cc60889e637f2772023e752fda4d44c5a3 100644 (file)
 146 -> SSAI Ultrasound Video Interface                     [414a:5353]
 147 -> VoodooTV 200 (USA)                                  [121a:3000]
 148 -> DViCO FusionHDTV 2                                  [dbc0:d200]
+149 -> Typhoon TV-Tuner PCI (50684)
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
new file mode 100644 (file)
index 0000000..00cb646
--- /dev/null
@@ -0,0 +1,5 @@
+  0 -> UNKNOWN/GENERIC                                     [0070:3400]
+  1 -> Hauppauge WinTV-HVR1800lp                           [0070:7600]
+  2 -> Hauppauge WinTV-HVR1800                             [0070:7800,0070:7801]
+  3 -> Hauppauge WinTV-HVR1250                             [0070:7911]
+  4 -> DViCO FusionHDTV5 Express                           [18ac:d500]
index 3f8aeab50a103b406a5075645aefa4cc740f499a..a14545300e4c84d5916da0af643cf91b370fc4d8 100644 (file)
  87 -> ADS Instant TV Duo Cardbus PTV331        [0331:1421]
  88 -> Tevion/KWorld DVB-T 220RF                [17de:7201]
  89 -> ELSA EX-VISION 700TV                     [1048:226c]
- 90 -> Kworld ATSC110                           [17de:7350]
+ 90 -> Kworld ATSC110/115                       [17de:7350,17de:7352]
  91 -> AVerMedia A169 B                         [1461:7360]
  92 -> AVerMedia A169 B1                        [1461:6360]
  93 -> Medion 7134 Bridge #2                    [16be:0005]
- 94 -> LifeView FlyDVB-T Hybrid Cardbus         [5168:3306,5168:3502]
+ 94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,4e42:3502]
  95 -> LifeView FlyVIDEO3000 (NTSC)             [5169:0138]
  96 -> Medion Md8800 Quadro                     [16be:0007,16be:0008]
  97 -> LifeView FlyDVB-S /Acorp TV134DS         [5168:0300,4e42:0300]
 114 -> KWorld DVB-T 210                         [17de:7250]
 115 -> Sabrent PCMCIA TV-PCB05                  [0919:2003]
 116 -> 10MOONS TM300 TV Card                    [1131:2304]
+117 -> Avermedia Super 007                      [1461:f01d]
diff --git a/Kbuild b/Kbuild
index 56b8edf6a3bc11461fe5512d2663c42e1f43a5d3..1570d248ad9237e4fa6e4d079336b9da62d9ba32 100644 (file)
--- a/Kbuild
+++ b/Kbuild
@@ -8,11 +8,11 @@
 # 1) Generate asm-offsets.h
 #
 
-offsets-file := include/asm-$(ARCH)/asm-offsets.h
+offsets-file := include/asm-$(SRCARCH)/asm-offsets.h
 
 always  := $(offsets-file)
 targets := $(offsets-file)
-targets += arch/$(ARCH)/kernel/asm-offsets.s
+targets += arch/$(SRCARCH)/kernel/asm-offsets.s
 clean-files := $(addprefix $(objtree)/,$(targets))
 
 # Default sed regexp - multiline due to syntax constraints
@@ -40,11 +40,11 @@ define cmd_offsets
 endef
 
 # We use internal kbuild rules to avoid the "is up to date" message from make
-arch/$(ARCH)/kernel/asm-offsets.s: arch/$(ARCH)/kernel/asm-offsets.c FORCE
+arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c FORCE
        $(Q)mkdir -p $(dir $@)
        $(call if_changed_dep,cc_s_c)
 
-$(obj)/$(offsets-file): arch/$(ARCH)/kernel/asm-offsets.s Kbuild
+$(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s Kbuild
        $(Q)mkdir -p $(dir $@)
        $(call cmd,offsets)
 
index 53144f4737ffab4adac59106f1a44b95cfc057db..60162706716fff315fe667aaf3d8394b7f361ca3 100644 (file)
@@ -718,34 +718,8 @@ M: rpurdie@rpsys.net
 S:     Maintained
 
 BLACKFIN ARCHITECTURE
-P:     Aubrey Li
-M:     aubrey.li@analog.com
-P:     Bernd Schmidt
-M:     bernd.schmidt@analog.com
 P:     Bryan Wu
 M:     bryan.wu@analog.com
-P:     Grace Pan
-M:     grace.pan@analog.com
-P:     Marc Hoffman
-M:     marc.hoffman@analog.com
-P:     Michael Hennerich
-M:     michael.hennerich@analog.com
-P:     Mike Frysinger
-M:     michael.frysinger@analog.com
-P:     Jerry Zeng
-M:     jerry.zeng@analog.com
-P:     Jie Zhang
-M:     jie.zhang@analog.com
-P:     Robin Getz
-M:     robin.getz@analog.com
-P:     Roy Huang
-M:     roy.huang@analog.com
-P:     Sonic Zhang
-M:     sonic.zhang@analog.com
-P:     Vivi Li
-M:     vivi.li@analog.com
-P:     Yi Li
-M:     yi.li@analog.com
 L:     uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
 W:     http://blackfin.uclinux.org
 S:     Supported
@@ -2561,12 +2535,18 @@ L:      linux-kernel@vger.kernel.org
 W:     http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html
 S:     Maintained
 
-MULTIMEDIA CARD (MMC) AND SECURE DIGITAL (SD) SUBSYSTEM
+MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
 P:     Pierre Ossman
 M:     drzeus-mmc@drzeus.cx
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
+MULTIMEDIA CARD (MMC) ETC. OVER SPI
+P:     David Brownell
+M:     dbrownell@users.sourceforge.net
+L:     linux-kernel@vger.kernel.org
+S:     Odd fixes
+
 MULTISOUND SOUND DRIVER
 P:     Andrew Veliath
 M:     andrewtv@usa.net
index 4635a64da36c356e70896d3fd78acddd0a29f147..1274084c9090aa92b529c0895a17b10d3313dcca 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -186,7 +186,8 @@ ARCH                ?= $(SUBARCH)
 CROSS_COMPILE  ?=
 
 # Architecture as present in compile.h
-UTS_MACHINE := $(ARCH)
+UTS_MACHINE    := $(ARCH)
+SRCARCH        := $(ARCH)
 
 KCONFIG_CONFIG ?= .config
 
@@ -322,7 +323,7 @@ KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
 KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
 export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
-export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
+export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
 export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
 export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
 
@@ -609,7 +610,7 @@ libs-y              := $(libs-y1) $(libs-y2)
 vmlinux-init := $(head-y) $(init-y)
 vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
 vmlinux-all  := $(vmlinux-init) $(vmlinux-main)
-vmlinux-lds  := arch/$(ARCH)/kernel/vmlinux.lds
+vmlinux-lds  := arch/$(SRCARCH)/kernel/vmlinux.lds
 export KBUILD_VMLINUX_OBJS := $(vmlinux-all)
 
 # Rule to link vmlinux - also used during CONFIG_KALLSYMS
@@ -862,7 +863,7 @@ ifneq ($(KBUILD_SRC),)
                /bin/false; \
        fi;
        $(Q)if [ ! -d include2 ]; then mkdir -p include2; fi;
-       $(Q)ln -fsn $(srctree)/include/asm-$(ARCH) include2/asm
+       $(Q)ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm
 endif
 
 # prepare2 creates a makefile if using a separate output directory
@@ -894,9 +895,9 @@ export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
 # before switching between archs anyway.
 
 include/asm:
-       @echo '  SYMLINK $@ -> include/asm-$(ARCH)'
+       @echo '  SYMLINK $@ -> include/asm-$(SRCARCH)'
        $(Q)if [ ! -d include ]; then mkdir -p include; fi;
-       @ln -fsn asm-$(ARCH) $@
+       @ln -fsn asm-$(SRCARCH) $@
 
 # Generate some files
 # ---------------------------------------------------------------------------
@@ -936,7 +937,8 @@ depend dep:
 INSTALL_HDR_PATH=$(objtree)/usr
 export INSTALL_HDR_PATH
 
-HDRARCHES=$(filter-out generic,$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild)))
+HDRFILTER=generic i386 x86_64
+HDRARCHES=$(filter-out $(HDRFILTER),$(patsubst $(srctree)/include/asm-%/Kbuild,%,$(wildcard $(srctree)/include/asm-*/Kbuild)))
 
 PHONY += headers_install_all
 headers_install_all: include/linux/version.h scripts_basic FORCE
@@ -947,11 +949,11 @@ headers_install_all: include/linux/version.h scripts_basic FORCE
 
 PHONY += headers_install
 headers_install: include/linux/version.h scripts_basic FORCE
-       @if [ ! -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
-         echo '*** Error: Headers not exportable for this architecture ($(ARCH))'; \
+       @if [ ! -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
+         echo '*** Error: Headers not exportable for this architecture ($(SRCARCH))'; \
          exit 1 ; fi
        $(Q)$(MAKE) $(build)=scripts scripts/unifdef
-       $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include
+       $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include
 
 PHONY += headers_check_all
 headers_check_all: headers_install_all
@@ -961,7 +963,7 @@ headers_check_all: headers_install_all
 
 PHONY += headers_check
 headers_check: headers_install
-       $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include HDRCHECK=1
+       $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst ARCH=$(SRCARCH) obj=include HDRCHECK=1
 
 # ---------------------------------------------------------------------------
 # Modules
@@ -1139,7 +1141,7 @@ help:
        @echo  '  cscope          - Generate cscope index'
        @echo  '  kernelrelease   - Output the release version string'
        @echo  '  kernelversion   - Output the version stored in Makefile'
-       @if [ -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
+       @if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
         echo  '  headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \
         echo  '                    (default: $(INSTALL_HDR_PATH))'; \
         fi
@@ -1147,7 +1149,7 @@ help:
        @echo  'Static analysers'
        @echo  '  checkstack      - Generate a list of stack hogs'
        @echo  '  namespacecheck  - Name space analysis on compiled kernel'
-       @if [ -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
+       @if [ -r $(srctree)/include/asm-$(SRCARCH)/Kbuild ]; then \
         echo  '  headers_check   - Sanity check on exported headers'; \
         fi
        @echo  ''
@@ -1292,18 +1294,23 @@ ifeq ($(ALLSOURCE_ARCHS),)
 ifeq ($(ARCH),um)
 ALLINCLUDE_ARCHS := $(ARCH) $(SUBARCH)
 else
-ALLINCLUDE_ARCHS := $(ARCH)
+ALLINCLUDE_ARCHS := $(SRCARCH)
 endif
 else
 #Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behavour.
 ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS)
 endif
 
+# Take care of arch/x86
+ifeq ($(ARCH), $(SRCARCH))
 ALLSOURCE_ARCHS := $(ARCH)
+else
+ALLSOURCE_ARCHS := $(ARCH) $(SRCARCH)
+endif
 
 define find-sources
         ( for ARCH in $(ALLSOURCE_ARCHS) ; do \
-              find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \
+              find $(__srctree)arch/$${SRCARCH} $(RCS_FIND_IGNORE) \
                    -name $1 -print; \
          done ; \
          find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \
@@ -1312,7 +1319,7 @@ define find-sources
               \( -name config -o -name 'asm-*' \) -prune \
               -o -name $1 -print; \
          for ARCH in $(ALLINCLUDE_ARCHS) ; do \
-              find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \
+              find $(__srctree)include/asm-$${SRCARCH} $(RCS_FIND_IGNORE) \
                    -name $1 -print; \
          done ; \
          find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
index da893c80d471550c59a51acbeeb31d97437c730b..a9778c1587abcede102e26aa304e854d4649c4a9 100644 (file)
@@ -116,7 +116,7 @@ static struct platform_device *devices[] __initdata = {
 };
 
 #ifdef CONFIG_MMC_IMX
-static int mx1ads_mmc_card_present(void)
+static int mx1ads_mmc_card_present(struct device *dev)
 {
        /* MMC/SD Card Detect is PB 20 on MX1ADS V1.0.7 */
        return (SSR(1) & (1 << 20) ? 0 : 1);
index f9b32a8eab9b217bfca2db0e7f21c90b2cff5bf7..b07ae63aa54802eaa47b700c009da90c83f31a9a 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <asm/arch/smc.h>
 
-static struct smc_config flash_config __initdata = {
+static struct smc_timing flash_timing __initdata = {
        .ncs_read_setup         = 0,
        .nrd_setup              = 40,
        .ncs_write_setup        = 0,
@@ -28,7 +28,9 @@ static struct smc_config flash_config __initdata = {
 
        .read_cycle             = 120,
        .write_cycle            = 120,
+};
 
+static struct smc_config flash_config __initdata = {
        .bus_width              = 2,
        .nrd_controlled         = 1,
        .nwe_controlled         = 1,
@@ -82,6 +84,7 @@ static int __init atngw100_flash_init(void)
 {
        int ret;
 
+       smc_set_timing(&flash_config, &flash_timing);
        ret = smc_set_configuration(0, &flash_config);
        if (ret < 0) {
                printk(KERN_ERR "atngw100: failed to set NOR flash timing\n");
index ef801563bbf58930cfb90762a345b0d480c99841..52987c81d668d1c5825f3f209058e99080ab462e 100644 (file)
@@ -125,8 +125,11 @@ static struct platform_device ngw_gpio_leds = {
 };
 
 static struct i2c_gpio_platform_data i2c_gpio_data = {
-       .sda_pin        = GPIO_PIN_PA(6),
-       .scl_pin        = GPIO_PIN_PA(7),
+       .sda_pin                = GPIO_PIN_PA(6),
+       .scl_pin                = GPIO_PIN_PA(7),
+       .sda_is_open_drain      = 1,
+       .scl_is_open_drain      = 1,
+       .udelay                 = 2,    /* close to 100 kHz */
 };
 
 static struct platform_device i2c_gpio_device = {
@@ -154,6 +157,7 @@ static int __init atngw100_init(void)
        set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
 
        at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
+       at32_add_device_usba(0, NULL);
 
        for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) {
                at32_select_gpio(ngw_leds[i].gpio,
@@ -161,8 +165,10 @@ static int __init atngw100_init(void)
        }
        platform_device_register(&ngw_gpio_leds);
 
-       at32_select_gpio(i2c_gpio_data.sda_pin, 0);
-       at32_select_gpio(i2c_gpio_data.scl_pin, 0);
+       at32_select_gpio(i2c_gpio_data.sda_pin,
+               AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+       at32_select_gpio(i2c_gpio_data.scl_pin,
+               AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
        platform_device_register(&i2c_gpio_device);
 
        return 0;
index c9981b731efa58e1d20aecee60222081ed813b06..6b9e466104ad04d8c5be831774a937931eb298e3 100644 (file)
@@ -241,6 +241,7 @@ static int __init atstk1002_init(void)
        at32_add_device_lcdc(0, &atstk1000_lcdc_data,
                             fbmem_start, fbmem_size);
 #endif
+       at32_add_device_usba(0, NULL);
 #ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
        at32_add_device_ssc(0, ATMEL_SSC_TX);
 #endif
index aac4300cca125afe112d97ce46a6fafec5acca72..3d0a102ad45ec1e8fd77ad4bd794b4d726a65888 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <asm/arch/smc.h>
 
-static struct smc_config flash_config __initdata = {
+static struct smc_timing flash_timing __initdata = {
        .ncs_read_setup         = 0,
        .nrd_setup              = 40,
        .ncs_write_setup        = 0,
@@ -28,7 +28,9 @@ static struct smc_config flash_config __initdata = {
 
        .read_cycle             = 120,
        .write_cycle            = 120,
+};
 
+static struct smc_config flash_config __initdata = {
        .bus_width              = 2,
        .nrd_controlled         = 1,
        .nwe_controlled         = 1,
@@ -82,6 +84,7 @@ static int __init atstk1000_flash_init(void)
 {
        int ret;
 
+       smc_set_timing(&flash_config, &flash_timing);
        ret = smc_set_configuration(0, &flash_config);
        if (ret < 0) {
                printk(KERN_ERR "atstk1000: failed to set NOR flash timing\n");
index 90e5afff54a2d1d537e0bf202d1effb61244e803..989fcd1fef7ed4fd048096b88b18c98d366d1237 100644 (file)
@@ -11,8 +11,3 @@ obj-y                         += signal.o sys_avr32.o process.o time.o
 obj-y                          += init_task.o switch_to.o cpu.o
 obj-$(CONFIG_MODULES)          += module.o avr32_ksyms.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
-
-USE_STANDARD_AS_RULE           := true
-
-%.lds: %.lds.c FORCE
-       $(call if_changed_dep,cpp_lds_S)
index 42657f1703b2773dc3532eaf3a5bf99efcf7e26a..ccadfd9b438da8a86517b135da8c9a90d24b955d 100644 (file)
@@ -159,11 +159,18 @@ handle_vmalloc_miss:
 
        .section .scall.text,"ax",@progbits
 system_call:
+#ifdef CONFIG_PREEMPT
+       mask_interrupts
+#endif
        pushm   r12             /* r12_orig */
        stmts   --sp, r0-lr
-       zero_fp
+
        mfsr    r0, SYSREG_RAR_SUP
        mfsr    r1, SYSREG_RSR_SUP
+#ifdef CONFIG_PREEMPT
+       unmask_interrupts
+#endif
+       zero_fp
        stm     --sp, r0-r1
 
        /* check for syscall tracing */
@@ -638,6 +645,13 @@ irq_level\level:
        stmts   --sp,r0-lr
        mfsr    r8, rar_int\level
        mfsr    r9, rsr_int\level
+
+#ifdef CONFIG_PREEMPT
+       sub     r11, pc, (. - system_call)
+       cp.w    r11, r8
+       breq    4f
+#endif
+
        pushm   r8-r9
 
        mov     r11, sp
@@ -668,6 +682,16 @@ irq_level\level:
        sub     sp, -4          /* ignore r12_orig */
        rete
 
+#ifdef CONFIG_PREEMPT
+4:     mask_interrupts
+       mfsr    r8, rsr_int\level
+       sbr     r8, 16
+       mtsr    rsr_int\level, r8
+       ldmts   sp++, r0-lr
+       sub     sp, -4          /* ignore r12_orig */
+       rete
+#endif
+
 2:     get_thread_info r0
        ld.w    r1, r0[TI_flags]
        bld     r1, TIF_CPU_GOING_TO_SLEEP
index d08b0bc6b2bbc31338f9f0cbc2f0e2b1da282ee9..4b4c1884e1c5a4c7546eebf9ee39dcdf500e9781 100644 (file)
@@ -248,7 +248,7 @@ static int __init early_parse_fbmem(char *p)
 
        fbmem_size = memparse(p, &p);
        if (*p == '@') {
-               fbmem_start = memparse(p, &p);
+               fbmem_start = memparse(p + 1, &p);
                ret = add_reserved_region(fbmem_start,
                                          fbmem_start + fbmem_size - 1,
                                          "Framebuffer");
similarity index 95%
rename from arch/avr32/kernel/vmlinux.lds.c
rename to arch/avr32/kernel/vmlinux.lds.S
index db0438f35c0066b8776df3c326e8de8ec6402427..ce9ac9659883d0336cbbe0e796f660e1e97173a2 100644 (file)
@@ -9,6 +9,8 @@
  */
 #define LOAD_OFFSET 0x00000000
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
 
 OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32")
 OUTPUT_ARCH(avr32)
@@ -58,11 +60,10 @@ SECTIONS
                        *(.init.ramfs)
                __initramfs_end = .;
 #endif
-               . = ALIGN(4096);
+               . = ALIGN(PAGE_SIZE);
                __init_end = .;
        }
 
-       . = ALIGN(8192);
        .text           : AT(ADDR(.text) - LOAD_OFFSET) {
                _evba = .;
                _text = .;
@@ -96,7 +97,7 @@ SECTIONS
 
        RODATA
 
-       . = ALIGN(8192);
+       . = ALIGN(THREAD_SIZE);
 
        .data           : AT(ADDR(.data) - LOAD_OFFSET) {
                _data = .;
@@ -107,7 +108,7 @@ SECTIONS
                *(.data.init_task)
 
                /* Then, the cacheline aligned data */
-               . = ALIGN(32);
+               . = ALIGN(L1_CACHE_BYTES);
                *(.data.cacheline_aligned)
 
                /* And the rest... */
index 64cc5583ddfb0a5feb89669d00ce853055421a68..f6d154ca4d24ebdd91c2fa1fef37d15a25184777 100644 (file)
 #include "pio.h"
 #include "pm.h"
 
-/*
- * We can reduce the code size a bit by using a constant here. Since
- * this file is completely chip-specific, it's safe to not use
- * ioremap. Generic drivers should of course never do this.
- */
-#define AT32_PM_BASE   0xfff00000
 
 #define PBMEM(base)                                    \
        {                                               \
@@ -1167,6 +1161,72 @@ at32_add_device_ssc(unsigned int id, unsigned int flags)
        return pdev;
 }
 
+/* --------------------------------------------------------------------
+ *  USB Device Controller
+ * -------------------------------------------------------------------- */
+static struct resource usba0_resource[] __initdata = {
+       {
+               .start          = 0xff300000,
+               .end            = 0xff3fffff,
+               .flags          = IORESOURCE_MEM,
+       }, {
+               .start          = 0xfff03000,
+               .end            = 0xfff033ff,
+               .flags          = IORESOURCE_MEM,
+       },
+       IRQ(31),
+};
+static struct clk usba0_pclk = {
+       .name           = "pclk",
+       .parent         = &pbb_clk,
+       .mode           = pbb_clk_mode,
+       .get_rate       = pbb_clk_get_rate,
+       .index          = 12,
+};
+static struct clk usba0_hclk = {
+       .name           = "hclk",
+       .parent         = &hsb_clk,
+       .mode           = hsb_clk_mode,
+       .get_rate       = hsb_clk_get_rate,
+       .index          = 6,
+};
+
+struct platform_device *__init
+at32_add_device_usba(unsigned int id, struct usba_platform_data *data)
+{
+       struct platform_device *pdev;
+
+       if (id != 0)
+               return NULL;
+
+       pdev = platform_device_alloc("atmel_usba_udc", 0);
+       if (!pdev)
+               return NULL;
+
+       if (platform_device_add_resources(pdev, usba0_resource,
+                                         ARRAY_SIZE(usba0_resource)))
+               goto out_free_pdev;
+
+       if (data) {
+               if (platform_device_add_data(pdev, data, sizeof(*data)))
+                       goto out_free_pdev;
+
+               if (data->vbus_pin != GPIO_PIN_NONE)
+                       at32_select_gpio(data->vbus_pin, 0);
+       }
+
+       usba0_pclk.dev = &pdev->dev;
+       usba0_hclk.dev = &pdev->dev;
+
+       platform_device_add(pdev);
+
+       return pdev;
+
+out_free_pdev:
+       platform_device_put(pdev);
+       return NULL;
+}
+
 /* --------------------------------------------------------------------
  *  GCLK
  * -------------------------------------------------------------------- */
@@ -1252,6 +1312,8 @@ struct clk *at32_clock_list[] = {
        &ssc0_pclk,
        &ssc1_pclk,
        &ssc2_pclk,
+       &usba0_hclk,
+       &usba0_pclk,
        &gclk0,
        &gclk1,
        &gclk2,
index 0f8c89c9f83243532c57dded20c5fc1be0893b91..4642117cc9ab8e362f0a07cc8205ab4e81c0c905 100644 (file)
@@ -150,3 +150,119 @@ struct clk *clk_get_parent(struct clk *clk)
        return clk->parent;
 }
 EXPORT_SYMBOL(clk_get_parent);
+
+
+
+#ifdef CONFIG_DEBUG_FS
+
+/* /sys/kernel/debug/at32ap_clk */
+
+#include <linux/io.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include "pm.h"
+
+
+#define        NEST_DELTA      2
+#define        NEST_MAX        6
+
+struct clkinf {
+       struct seq_file *s;
+       unsigned        nest;
+};
+
+static void
+dump_clock(struct clk *parent, struct clkinf *r)
+{
+       unsigned        nest = r->nest;
+       char            buf[16 + NEST_MAX];
+       struct clk      *clk;
+       unsigned        i;
+
+       /* skip clocks coupled to devices that aren't registered */
+       if (parent->dev && !parent->dev->bus_id[0] && !parent->users)
+               return;
+
+       /* <nest spaces> name <pad to end> */
+       memset(buf, ' ', sizeof(buf) - 1);
+       buf[sizeof(buf) - 1] = 0;
+       i = strlen(parent->name);
+       memcpy(buf + nest, parent->name,
+                       min(i, (unsigned)(sizeof(buf) - 1 - nest)));
+
+       seq_printf(r->s, "%s%c users=%2d %-3s %9ld Hz",
+               buf, parent->set_parent ? '*' : ' ',
+               parent->users,
+               parent->users ? "on" : "off",   /* NOTE: not-paranoid!! */
+               clk_get_rate(parent));
+       if (parent->dev)
+               seq_printf(r->s, ", for %s", parent->dev->bus_id);
+       seq_printf(r->s, "\n");
+
+       /* cost of this scan is small, but not linear... */
+       r->nest = nest + NEST_DELTA;
+       for (i = 3; i < at32_nr_clocks; i++) {
+               clk = at32_clock_list[i];
+               if (clk->parent == parent)
+                       dump_clock(clk, r);
+       }
+       r->nest = nest;
+}
+
+static int clk_show(struct seq_file *s, void *unused)
+{
+       struct clkinf   r;
+       int             i;
+
+       /* show all the power manager registers */
+       seq_printf(s, "MCCTRL  = %8x\n", pm_readl(MCCTRL));
+       seq_printf(s, "CKSEL   = %8x\n", pm_readl(CKSEL));
+       seq_printf(s, "CPUMASK = %8x\n", pm_readl(CPU_MASK));
+       seq_printf(s, "HSBMASK = %8x\n", pm_readl(HSB_MASK));
+       seq_printf(s, "PBAMASK = %8x\n", pm_readl(PBA_MASK));
+       seq_printf(s, "PBBMASK = %8x\n", pm_readl(PBB_MASK));
+       seq_printf(s, "PLL0    = %8x\n", pm_readl(PLL0));
+       seq_printf(s, "PLL1    = %8x\n", pm_readl(PLL1));
+       seq_printf(s, "IMR     = %8x\n", pm_readl(IMR));
+       for (i = 0; i < 8; i++) {
+               if (i == 5)
+                       continue;
+               seq_printf(s, "GCCTRL%d = %8x\n", i, pm_readl(GCCTRL(i)));
+       }
+
+       seq_printf(s, "\n");
+
+       /* show clock tree as derived from the three oscillators
+        * we "know" are at the head of the list
+        */
+       r.s = s;
+       r.nest = 0;
+       dump_clock(at32_clock_list[0], &r);
+       dump_clock(at32_clock_list[1], &r);
+       dump_clock(at32_clock_list[2], &r);
+
+       return 0;
+}
+
+static int clk_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, clk_show, NULL);
+}
+
+static const struct file_operations clk_operations = {
+       .open           = clk_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init clk_debugfs_init(void)
+{
+       (void) debugfs_create_file("at32ap_clk", S_IFREG | S_IRUGO,
+                       NULL, NULL, &clk_operations);
+
+       return 0;
+}
+postcore_initcall(clk_debugfs_init);
+
+#endif
index 5e22a750632b78755c24d84d05718c24822b587c..704607fbcc696d2223241ff26103176daa254b46 100644 (file)
@@ -29,16 +29,25 @@ struct hsmc {
 
 static struct hsmc *hsmc;
 
-int smc_set_configuration(int cs, const struct smc_config *config)
+void smc_set_timing(struct smc_config *config,
+                   const struct smc_timing *timing)
 {
+       int recover;
+       int cycle;
+
        unsigned long mul;
-       unsigned long offset;
-       u32 setup, pulse, cycle, mode;
 
-       if (!hsmc)
-               return -ENODEV;
-       if (cs >= NR_CHIP_SELECTS)
-               return -EINVAL;
+       /* Reset all SMC timings */
+       config->ncs_read_setup  = 0;
+       config->nrd_setup       = 0;
+       config->ncs_write_setup = 0;
+       config->nwe_setup       = 0;
+       config->ncs_read_pulse  = 0;
+       config->nrd_pulse       = 0;
+       config->ncs_write_pulse = 0;
+       config->nwe_pulse       = 0;
+       config->read_cycle      = 0;
+       config->write_cycle     = 0;
 
        /*
         * cycles = x / T = x * f
@@ -50,16 +59,102 @@ int smc_set_configuration(int cs, const struct smc_config *config)
 
 #define ns2cyc(x) ((((x) * mul) + 65535) >> 16)
 
-       setup = (HSMC_BF(NWE_SETUP, ns2cyc(config->nwe_setup))
-                | HSMC_BF(NCS_WR_SETUP, ns2cyc(config->ncs_write_setup))
-                | HSMC_BF(NRD_SETUP, ns2cyc(config->nrd_setup))
-                | HSMC_BF(NCS_RD_SETUP, ns2cyc(config->ncs_read_setup)));
-       pulse = (HSMC_BF(NWE_PULSE, ns2cyc(config->nwe_pulse))
-                | HSMC_BF(NCS_WR_PULSE, ns2cyc(config->ncs_write_pulse))
-                | HSMC_BF(NRD_PULSE, ns2cyc(config->nrd_pulse))
-                | HSMC_BF(NCS_RD_PULSE, ns2cyc(config->ncs_read_pulse)));
-       cycle = (HSMC_BF(NWE_CYCLE, ns2cyc(config->write_cycle))
-                | HSMC_BF(NRD_CYCLE, ns2cyc(config->read_cycle)));
+       if (timing->ncs_read_setup > 0)
+               config->ncs_read_setup = ns2cyc(timing->ncs_read_setup);
+
+       if (timing->nrd_setup > 0)
+               config->nrd_setup = ns2cyc(timing->nrd_setup);
+
+       if (timing->ncs_write_setup > 0)
+               config->ncs_write_setup = ns2cyc(timing->ncs_write_setup);
+
+       if (timing->nwe_setup > 0)
+               config->nwe_setup = ns2cyc(timing->nwe_setup);
+
+       if (timing->ncs_read_pulse > 0)
+               config->ncs_read_pulse = ns2cyc(timing->ncs_read_pulse);
+
+       if (timing->nrd_pulse > 0)
+               config->nrd_pulse = ns2cyc(timing->nrd_pulse);
+
+       if (timing->ncs_write_pulse > 0)
+               config->ncs_write_pulse = ns2cyc(timing->ncs_write_pulse);
+
+       if (timing->nwe_pulse > 0)
+               config->nwe_pulse = ns2cyc(timing->nwe_pulse);
+
+       if (timing->read_cycle > 0)
+               config->read_cycle = ns2cyc(timing->read_cycle);
+
+       if (timing->write_cycle > 0)
+               config->write_cycle = ns2cyc(timing->write_cycle);
+
+       /* Extend read cycle in needed */
+       if (timing->ncs_read_recover > 0)
+               recover = ns2cyc(timing->ncs_read_recover);
+       else
+               recover = 1;
+
+       cycle = config->ncs_read_setup + config->ncs_read_pulse + recover;
+
+       if (config->read_cycle < cycle)
+               config->read_cycle = cycle;
+
+       /* Extend read cycle in needed */
+       if (timing->nrd_recover > 0)
+               recover = ns2cyc(timing->nrd_recover);
+       else
+               recover = 1;
+
+       cycle = config->nrd_setup + config->nrd_pulse + recover;
+
+       if (config->read_cycle < cycle)
+               config->read_cycle = cycle;
+
+       /* Extend write cycle in needed */
+       if (timing->ncs_write_recover > 0)
+               recover = ns2cyc(timing->ncs_write_recover);
+       else
+               recover = 1;
+
+       cycle = config->ncs_write_setup + config->ncs_write_pulse + recover;
+
+       if (config->write_cycle < cycle)
+               config->write_cycle = cycle;
+
+       /* Extend write cycle in needed */
+       if (timing->nwe_recover > 0)
+               recover = ns2cyc(timing->nwe_recover);
+       else
+               recover = 1;
+
+       cycle = config->nwe_setup + config->nwe_pulse + recover;
+
+       if (config->write_cycle < cycle)
+               config->write_cycle = cycle;
+}
+EXPORT_SYMBOL(smc_set_timing);
+
+int smc_set_configuration(int cs, const struct smc_config *config)
+{
+       unsigned long offset;
+       u32 setup, pulse, cycle, mode;
+
+       if (!hsmc)
+               return -ENODEV;
+       if (cs >= NR_CHIP_SELECTS)
+               return -EINVAL;
+
+       setup = (HSMC_BF(NWE_SETUP, config->nwe_setup)
+                | HSMC_BF(NCS_WR_SETUP, config->ncs_write_setup)
+                | HSMC_BF(NRD_SETUP, config->nrd_setup)
+                | HSMC_BF(NCS_RD_SETUP, config->ncs_read_setup));
+       pulse = (HSMC_BF(NWE_PULSE, config->nwe_pulse)
+                | HSMC_BF(NCS_WR_PULSE, config->ncs_write_pulse)
+                | HSMC_BF(NRD_PULSE, config->nrd_pulse)
+                | HSMC_BF(NCS_RD_PULSE, config->ncs_read_pulse));
+       cycle = (HSMC_BF(NWE_CYCLE, config->write_cycle)
+                | HSMC_BF(NRD_CYCLE, config->read_cycle));
 
        switch (config->bus_width) {
        case 1:
index 1eb99b814f5bcaf021f06ef46ea26c3cc96fa67f..d61a02da898cd68bd08316474ee2c2762dfd8036 100644 (file)
@@ -110,6 +110,10 @@ void __init at32_select_gpio(unsigned int pin, unsigned long flags)
                        pio_writel(pio, SODR, mask);
                else
                        pio_writel(pio, CODR, mask);
+               if (flags & AT32_GPIOF_MULTIDRV)
+                       pio_writel(pio, MDER, mask);
+               else
+                       pio_writel(pio, MDDR, mask);
                pio_writel(pio, PUDR, mask);
                pio_writel(pio, OER, mask);
        } else {
index a1f8aced0a8c8dd2ff862c4e240ddfd6a351e658..47efd0d1951f41d86c21ddaae1c4c318a75efa08 100644 (file)
@@ -4,6 +4,14 @@
 #ifndef __ARCH_AVR32_MACH_AT32AP_PM_H__
 #define __ARCH_AVR32_MACH_AT32AP_PM_H__
 
+/*
+ * We can reduce the code size a bit by using a constant here. Since
+ * this file is only used on AVR32 AP CPUs with segmentation enabled,
+ * it's safe to not use ioremap. Generic drivers should of course
+ * never do this.
+ */
+#define AT32_PM_BASE   0xfff00000
+
 /* PM register offsets */
 #define PM_MCCTRL                              0x0000
 #define PM_CKSEL                               0x0004
index 82cf70854b90d3999e0672b6f8a2fa1c2601129c..480760bde63f9d2f342c5d32364ffa078800349a 100644 (file)
@@ -224,19 +224,9 @@ void free_initmem(void)
 
 #ifdef CONFIG_BLK_DEV_INITRD
 
-static int keep_initrd;
-
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-       if (!keep_initrd)
-               free_area(start, end, "initrd");
-}
-
-static int __init keepinitrd_setup(char *__unused)
-{
-       keep_initrd = 1;
-       return 1;
+       free_area(start, end, "initrd");
 }
 
-__setup("keepinitrd", keepinitrd_setup);
 #endif
index 017defaa525b2b8981889437824df7ae4220c246..b24f4535ffe036133bf2d9d3bc7cc7e538e2e27f 100644 (file)
@@ -57,7 +57,7 @@ config GENERIC_TIME
        bool
        default n
 
-config GENERIC_CALIBRATE_DELAY
+config GENERIC_GPIO
        bool
        default y
 
@@ -323,7 +323,7 @@ config CMDLINE
          to the kernel, you may specify one here. As a minimum, you should specify
          the memory size and the root device (e.g., mem=8M, root=/dev/nfs).
 
-comment "Board Setup"
+comment "Clock/PLL Setup"
 
 config CLKIN_HZ
        int "Crystal Frequency in Hz"
@@ -335,6 +335,118 @@ config CLKIN_HZ
        help
          The frequency of CLKIN crystal oscillator on the board in Hz.
 
+config BFIN_KERNEL_CLOCK
+       bool "Re-program Clocks while Kernel boots?"
+       default n
+       help
+         This option decides if kernel clocks are re-programed from the
+         bootloader settings. If the clocks are not set, the SDRAM settings
+         are also not changed, and the Bootloader does 100% of the hardware
+         configuration.
+
+config PLL_BYPASS
+        bool "Bypass PLL"
+        depends on BFIN_KERNEL_CLOCK
+        default n
+
+config CLKIN_HALF
+       bool "Half Clock In"
+       depends on BFIN_KERNEL_CLOCK && (! PLL_BYPASS)
+       default n
+       help
+         If this is set the clock will be divided by 2, before it goes to the PLL.
+
+config VCO_MULT
+       int "VCO Multiplier"
+       depends on BFIN_KERNEL_CLOCK && (! PLL_BYPASS)
+       range 1 64
+       default "22" if BFIN533_EZKIT
+       default "45" if BFIN533_STAMP
+       default "20" if BFIN537_STAMP
+       default "22" if BFIN533_BLUETECHNIX_CM
+       default "20" if BFIN537_BLUETECHNIX_CM
+       default "20" if BFIN561_BLUETECHNIX_CM
+       default "20" if BFIN561_EZKIT
+       help
+         This controls the frequency of the on-chip PLL. This can be between 1 and 64.
+         PLL Frequency = (Crystal Frequency) * (this setting)
+
+choice
+       prompt "Core Clock Divider"
+       depends on BFIN_KERNEL_CLOCK
+       default CCLK_DIV_1
+       help
+         This sets the frequency of the core. It can be 1, 2, 4 or 8
+         Core Frequency = (PLL frequency) / (this setting)
+
+config CCLK_DIV_1
+       bool "1"
+
+config CCLK_DIV_2
+       bool "2"
+
+config CCLK_DIV_4
+       bool "4"
+
+config CCLK_DIV_8
+       bool "8"
+endchoice
+
+config SCLK_DIV
+       int "System Clock Divider"
+       depends on BFIN_KERNEL_CLOCK
+       range 1 15
+       default 5 if BFIN533_EZKIT
+       default 5 if BFIN533_STAMP
+       default 4 if BFIN537_STAMP
+       default 5 if BFIN533_BLUETECHNIX_CM
+       default 4 if BFIN537_BLUETECHNIX_CM
+       default 4 if BFIN561_BLUETECHNIX_CM
+       default 5 if BFIN561_EZKIT
+       help
+         This sets the frequency of the system clock (including SDRAM or DDR).
+         This can be between 1 and 15
+         System Clock = (PLL frequency) / (this setting)
+
+#
+# Max & Min Speeds for various Chips
+#
+config MAX_VCO_HZ
+       int
+       default 600000000 if BF522
+       default 600000000 if BF525
+       default 600000000 if BF527
+       default 400000000 if BF531
+       default 400000000 if BF532
+       default 750000000 if BF533
+       default 500000000 if BF534
+       default 400000000 if BF536
+       default 600000000 if BF537
+       default 533000000 if BF538
+       default 533000000 if BF539
+       default 600000000 if BF542
+       default 533000000 if BF544
+       default 533000000 if BF549
+       default 600000000 if BF561
+
+config MIN_VCO_HZ
+       int
+       default 50000000
+
+config MAX_SCLK_HZ
+       int
+       default 133000000
+
+config MIN_SCLK_HZ
+       int
+       default 27000000
+
+comment "Kernel Timer/Scheduler"
+
+source kernel/Kconfig.hz
+
+comment "Memory Setup"
+
 config MEM_SIZE
        int "SDRAM Memory Size in MBytes"
        default  32 if BFIN533_EZKIT
@@ -364,15 +476,16 @@ config ENET_FLASH_PIN
 config BOOT_LOAD
        hex "Kernel load address for booting"
        default "0x1000"
+       range 0x1000 0x20000000
        help
          This option allows you to set the load address of the kernel.
          This can be useful if you are on a board which has a small amount
          of memory or you wish to reserve some memory at the beginning of
          the address space.
 
-         Note that you generally want to keep this value at or above 4k
-         (0x1000) as this will allow the kernel to capture NULL pointer
-         references.
+         Note that you need to keep this value above 4k (0x1000) as this
+         memory region is used to capture NULL pointer references as well
+         as some core kernel functions.
 
 comment "LED Status Indicators"
        depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM)
@@ -408,6 +521,52 @@ config BFIN_IDLE_LED_NUM
        help
          Select the LED (marked on the board) for you to blink.
 
+choice
+       prompt "Blackfin Exception Scratch Register"
+       default BFIN_SCRATCH_REG_RETN
+       help
+         Select the resource to reserve for the Exception handler:
+           - RETN: Non-Maskable Interrupt (NMI)
+           - RETE: Exception Return (JTAG/ICE)
+           - CYCLES: Performance counter
+
+         If you are unsure, please select "RETN".
+
+config BFIN_SCRATCH_REG_RETN
+       bool "RETN"
+       help
+         Use the RETN register in the Blackfin exception handler
+         as a stack scratch register.  This means you cannot
+         safely use NMI on the Blackfin while running Linux, but
+         you can debug the system with a JTAG ICE and use the
+         CYCLES performance registers.
+
+         If you are unsure, please select "RETN".
+
+config BFIN_SCRATCH_REG_RETE
+       bool "RETE"
+       help
+         Use the RETE register in the Blackfin exception handler
+         as a stack scratch register.  This means you cannot
+         safely use a JTAG ICE while debugging a Blackfin board,
+         but you can safely use the CYCLES performance registers
+         and the NMI.
+
+         If you are unsure, please select "RETN".
+
+config BFIN_SCRATCH_REG_CYCLES
+       bool "CYCLES"
+       help
+         Use the CYCLES register in the Blackfin exception handler
+         as a stack scratch register.  This means you cannot
+         safely use the CYCLES performance registers on a Blackfin
+         board at anytime, but you can debug the system with a JTAG
+         ICE and use the NMI.
+
+         If you are unsure, please select "RETN".
+
+endchoice
+
 #
 # Sorry - but you need to put the hex address here -
 #
@@ -448,10 +607,6 @@ endmenu
 
 menu "Blackfin Kernel Optimizations"
 
-comment "Timer Tick"
-
-source kernel/Kconfig.hz
-
 comment "Memory Optimizations"
 
 config I_ENTRY_L1
@@ -614,22 +769,22 @@ endchoice
 
 
 comment "Cache Support"
-config BLKFIN_CACHE
+config BFIN_ICACHE
        bool "Enable ICACHE"
-config BLKFIN_DCACHE
+config BFIN_DCACHE
        bool "Enable DCACHE"
-config BLKFIN_DCACHE_BANKA
+config BFIN_DCACHE_BANKA
        bool "Enable only 16k BankA DCACHE - BankB is SRAM"
-       depends on BLKFIN_DCACHE && !BF531
+       depends on BFIN_DCACHE && !BF531
        default n
-config BLKFIN_CACHE_LOCK
-       bool "Enable Cache Locking"
+config BFIN_ICACHE_LOCK
+       bool "Enable Instruction Cache Locking"
 
 choice
        prompt "Policy"
-       depends on BLKFIN_DCACHE
-       default BLKFIN_WB
-config BLKFIN_WB
+       depends on BFIN_DCACHE
+       default BFIN_WB
+config BFIN_WB
        bool "Write back"
        help
          Write Back Policy:
@@ -646,7 +801,7 @@ config BLKFIN_WB
          If you are unsure of the options and you want to be safe,
          then go with Write Through.
 
-config BLKFIN_WT
+config BFIN_WT
        bool "Write through"
        help
          Write Back Policy:
@@ -672,66 +827,9 @@ config L1_MAX_PIECE
          Set the max memory pieces for the L1 SRAM allocation algorithm.
          Min value is 16. Max value is 1024.
 
-menu "Clock Settings"
-
-
-config BFIN_KERNEL_CLOCK
-       bool "Re-program Clocks while Kernel boots?"
-       default n
-       help
-         This option decides if kernel clocks are re-programed from the
-         bootloader settings. If the clocks are not set, the SDRAM settings
-         are also not changed, and the Bootloader does 100% of the hardware
-         configuration.
-
-config VCO_MULT
-       int "VCO Multiplier"
-       depends on BFIN_KERNEL_CLOCK
-       default "22" if BFIN533_EZKIT
-       default "45" if BFIN533_STAMP
-       default "20" if BFIN537_STAMP
-       default "22" if BFIN533_BLUETECHNIX_CM
-       default "20" if BFIN537_BLUETECHNIX_CM
-       default "20" if BFIN561_BLUETECHNIX_CM
-       default "20" if BFIN561_EZKIT
-
-config CCLK_DIV
-       int "Core Clock Divider"
-       depends on BFIN_KERNEL_CLOCK
-       default 1 if BFIN533_EZKIT
-       default 1 if BFIN533_STAMP
-       default 1 if BFIN537_STAMP
-       default 1 if BFIN533_BLUETECHNIX_CM
-       default 1 if BFIN537_BLUETECHNIX_CM
-       default 1 if BFIN561_BLUETECHNIX_CM
-       default 1 if BFIN561_EZKIT
-
-config SCLK_DIV
-       int "System Clock Divider"
-       depends on BFIN_KERNEL_CLOCK
-       default 5 if BFIN533_EZKIT
-       default 5 if BFIN533_STAMP
-       default 4 if BFIN537_STAMP
-       default 5 if BFIN533_BLUETECHNIX_CM
-       default 4 if BFIN537_BLUETECHNIX_CM
-       default 4 if BFIN561_BLUETECHNIX_CM
-       default 5 if BFIN561_EZKIT
-
-config CLKIN_HALF
-       bool "Half ClockIn"
-       depends on BFIN_KERNEL_CLOCK
-       default n
-
-config PLL_BYPASS
-       bool "Bypass PLL"
-       depends on BFIN_KERNEL_CLOCK
-       default n
-
-endmenu
-
 comment "Asynchonous Memory Configuration"
 
-menu "EBIU_AMBCTL Global Control"
+menu "EBIU_AMGCTL Global Control"
 config C_AMCKEN
        bool "Enable CLKOUT"
        default y
@@ -941,24 +1039,6 @@ config DEBUG_ICACHE_CHECK
          also relocates the irq_panic() function to L1 memory, (which is
          un-cached).
 
-config DEBUG_KERNEL_START
-       bool "Debug Kernel Startup"
-       depends on DEBUG_KERNEL
-       help
-         Say Y here to put in an mini-execption handler before the kernel
-         replaces the bootloader exception handler. This will stop kernels
-         from dieing at startup with no visible error messages.
-
-config DEBUG_SERIAL_EARLY_INIT
-       bool "Initialize serial driver early"
-       default n
-       depends on SERIAL_BFIN
-       help
-         Say Y here if you want to get kernel output early when kernel
-         crashes before the normal console initialization. If this option
-         is enable, console output will always go to the ttyBF0, no matter
-         what kernel boot paramters you set.
-
 config DEBUG_HUNT_FOR_ZERO
        bool "Catch NULL pointer reads/writes"
        default y
@@ -973,8 +1053,89 @@ config DEBUG_HUNT_FOR_ZERO
          Enabling this option will take up an extra entry in CPLB table.
          Otherwise, there is no extra overhead.
 
+config DEBUG_BFIN_HWTRACE_ON
+       bool "Turn on Blackfin's Hardware Trace"
+       default y
+       help
+         All Blackfins include a Trace Unit which stores a history of the last
+         16 changes in program flow taken by the program sequencer. The history
+         allows the user to recreate the program sequencer’s recent path. This
+         can be handy when an application dies - we print out the execution
+         path of how it got to the offending instruction.
+
+         By turning this off, you may save a tiny amount of power.
+
+choice
+       prompt "Omit loop Tracing"
+       default DEBUG_BFIN_HWTRACE_COMPRESSION_OFF
+       depends on DEBUG_BFIN_HWTRACE_ON
+       help
+         The trace buffer can be configured to omit recording of changes in
+         program flow that match either the last entry or one of the last
+         two entries. Omitting one of these entries from the record prevents
+         the trace buffer from overflowing because of any sort of loop (for, do
+         while, etc) in the program.
+
+         Because zero-overhead Hardware loops are not recorded in the trace buffer,
+         this feature can be used to prevent trace overflow from loops that
+         are nested four deep.
+
+config DEBUG_BFIN_HWTRACE_COMPRESSION_OFF
+       bool "Trace all Loops"
+       help
+         The trace buffer records all changes of flow 
+
+config DEBUG_BFIN_HWTRACE_COMPRESSION_ONE
+       bool "Compress single-level loops"
+       help
+         The trace buffer does not record single loops - helpful if trace 
+         is spinning on a while or do loop.
+
+config DEBUG_BFIN_HWTRACE_COMPRESSION_TWO
+       bool "Compress two-level loops"
+       help
+         The trace buffer does not record loops two levels deep. Helpful if
+         the trace is spinning in a nested loop
+
+endchoice
+
+config DEBUG_BFIN_HWTRACE_COMPRESSION
+       int
+       depends on DEBUG_BFIN_HWTRACE_ON
+       default 0 if DEBUG_BFIN_HWTRACE_COMPRESSION_OFF
+       default 1 if DEBUG_BFIN_HWTRACE_COMPRESSION_ONE
+       default 2 if DEBUG_BFIN_HWTRACE_COMPRESSION_TWO
+
+
+config DEBUG_BFIN_HWTRACE_EXPAND
+       bool "Expand Trace Buffer greater than 16 entries"
+       depends on DEBUG_BFIN_HWTRACE_ON
+       default n
+       help
+         By selecting this option, every time the 16 hardware entries in
+         the Blackfin's HW Trace buffer are full, the kernel will move them
+         into a software buffer, for dumping when there is an issue. This 
+         has a great impact on performance, (an interrupt every 16 change of 
+         flows) and should normally be turned off, except in those nasty
+         debugging sessions
+
+config DEBUG_BFIN_HWTRACE_EXPAND_LEN
+       int "Size of Trace buffer (in power of 2k)"
+       range 0 4
+       depends on DEBUG_BFIN_HWTRACE_EXPAND
+       default 1
+       help
+         This sets the size of the software buffer that the trace information
+         is kept in.
+         0 for (2^0)  1k, or 256 entries,
+         1 for (2^1)  2k, or 512 entries,
+         2 for (2^2)  4k, or 1024 entries,
+         3 for (2^3)  8k, or 2048 entries,
+         4 for (2^4) 16k, or 4096 entries
+
 config DEBUG_BFIN_NO_KERN_HWTRACE
        bool "Trace user apps (turn off hwtrace in kernel)"
+       depends on DEBUG_BFIN_HWTRACE_ON
        default n
        help
          Some pieces of the kernel contain a lot of flow changes which can
@@ -985,6 +1146,20 @@ config DEBUG_BFIN_NO_KERN_HWTRACE
          Say Y here to disable hardware tracing in some known "jumpy" pieces
          of code so that the trace buffer will extend further back.
 
+config EARLY_PRINTK
+       bool "Early printk" 
+       default n
+       help
+         This option enables special console drivers which allow the kernel
+         to print messages very early in the bootup process.
+
+         This is useful for kernel debugging when your machine crashes very
+         early before the console code is initialized. After enabling this
+         feature, you must add "earlyprintk=serial,uart0,57600" to the
+         command line (bootargs). It is safe to say Y here in all cases, as
+         all of this lives in the init section and is thrown away after the
+         kernel boots completely.
+
 config DUAL_CORE_TEST_MODULE
        tristate "Dual Core Test Module"
        depends on (BF561)
index 1cf1ab28dc66b98a288b1616211ca03a41daec7b..57f58d5cd47a14e5a088a541d86e9a680c678956 100644 (file)
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21.5
+# Linux kernel version: 2.6.22.6
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -15,8 +15,9 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 # CONFIG_GENERIC_TIME is not set
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_IRQCHIP_DEMUX_GPIO=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -40,7 +41,9 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_TASKSTATS is not set
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -58,15 +61,20 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
-CONFIG_BUDDY=y
 # CONFIG_NP2 is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -184,19 +192,17 @@ CONFIG_WDTIMER=13
 # CONFIG_CMDLINE_BOOL is not set
 
 #
-# Board Setup
+# Clock/PLL Setup
 #
 CONFIG_CLKIN_HZ=27000000
-CONFIG_MEM_SIZE=32
-CONFIG_MEM_ADD_WIDTH=9
-CONFIG_BOOT_LOAD=0x1000
-
-#
-# Blackfin Kernel Optimizations
-#
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=750000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133000000
+CONFIG_MIN_SCLK_HZ=27000000
 
 #
-# Timer Tick
+# Kernel Timer/Scheduler
 #
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
@@ -204,6 +210,20 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 
+#
+# Memory Setup
+#
+CONFIG_MEM_SIZE=32
+CONFIG_MEM_ADD_WIDTH=9
+CONFIG_BOOT_LOAD=0x1000
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
 #
 # Memory Optimizations
 #
@@ -243,19 +263,14 @@ CONFIG_DMA_UNCACHED_1M=y
 #
 # Cache Support
 #
-CONFIG_BLKFIN_CACHE=y
-CONFIG_BLKFIN_DCACHE=y
-# CONFIG_BLKFIN_DCACHE_BANKA is not set
-# CONFIG_BLKFIN_CACHE_LOCK is not set
-# CONFIG_BLKFIN_WB is not set
-CONFIG_BLKFIN_WT=y
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+# CONFIG_BFIN_ICACHE_LOCK is not set
+# CONFIG_BFIN_WB is not set
+CONFIG_BFIN_WT=y
 CONFIG_L1_MAX_PIECE=16
 
-#
-# Clock Settings
-#
-# CONFIG_BFIN_KERNEL_CLOCK is not set
-
 #
 # Asynchonous Memory Configuration
 #
@@ -277,22 +292,19 @@ CONFIG_C_AMBEN_ALL=y
 CONFIG_BANK_0=0x7BB0
 CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
-CONFIG_BANK_3=0x99B3
+CONFIG_BANK_3=0xAAC3
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PCI Hotplug Support
-#
-
 #
 # Executable file formats
 #
@@ -327,7 +339,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -368,20 +379,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -448,7 +447,16 @@ CONFIG_IRTTY_SIR=m
 # FIR device drivers
 #
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
 
 #
 # Device Drivers
@@ -466,10 +474,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # Connector - unified userspace <-> kernelspace linker
 #
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
@@ -513,7 +517,6 @@ CONFIG_MTD_MW320D=m
 CONFIG_MTD_RAM=y
 CONFIG_MTD_ROM=m
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -550,16 +553,13 @@ CONFIG_BFIN_FLASH_BANK_3=0x7BB0
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
 
 #
-# OneNAND Flash Device Drivers
+# UBI - Unsorted block images
 #
-# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_UBI is not set
 
 #
 # Parallel port support
@@ -587,10 +587,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # Misc devices
 #
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
 # CONFIG_IDE is not set
 
 #
@@ -599,10 +595,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
 
 #
@@ -610,19 +602,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # CONFIG_MD is not set
 
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
 #
 # Network device support
 #
@@ -631,10 +610,6 @@ CONFIG_NETDEVICES=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
 
 #
@@ -644,27 +619,15 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_SMC91X=y
 # CONFIG_SMSC911X is not set
+# CONFIG_DM9000 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -688,6 +651,7 @@ CONFIG_SMC91X=y
 #
 CONFIG_INPUT=m
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -704,6 +668,7 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -718,7 +683,7 @@ CONFIG_INPUT_EVDEV=m
 #
 # CONFIG_AD9960 is not set
 # CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PFLAGS is not set
+# CONFIG_BFIN_PFLAGS is not set
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BF5xx_TIMERS is not set
 # CONFIG_BF5xx_PPI is not set
@@ -758,10 +723,6 @@ CONFIG_UNIX98_PTYS=y
 # IPMI
 #
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -773,7 +734,6 @@ CONFIG_BFIN_WDT=y
 CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 CONFIG_BLACKFIN_DPMC=y
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -781,10 +741,6 @@ CONFIG_BLACKFIN_DPMC=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
 
 #
@@ -803,22 +759,22 @@ CONFIG_SPI_BFIN=y
 # SPI Protocol Masters
 #
 # CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
 
 #
 # Dallas's 1-wire bus
 #
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_LM70 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83627HF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
@@ -830,16 +786,19 @@ CONFIG_HWMON=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Graphics support
+# Display device support
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
 # CONFIG_FB is not set
 
 #
@@ -862,18 +821,17 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
-# CONFIG_USB_GADGET is not set
 
 #
-# MMC/SD Card support
+# USB Gadget Support
 #
-# CONFIG_SPI_MMC is not set
+# CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 
 #
@@ -913,17 +871,29 @@ CONFIG_RTC_INTF_SYSFS=y
 CONFIG_RTC_INTF_PROC=y
 CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
 
 #
-# RTC drivers
+# Platform RTC drivers
 #
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
-# CONFIG_RTC_DRV_RS5C348 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_TEST is not set
-# CONFIG_RTC_DRV_MAX6902 is not set
 # CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
 CONFIG_RTC_DRV_BFIN=y
 
 #
@@ -939,14 +909,6 @@ CONFIG_RTC_DRV_BFIN=y
 # DMA Devices
 #
 
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
 #
 # PBX support
 #
@@ -1047,6 +1009,7 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
+# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1124,14 +1087,20 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_SERIAL_EARLY_INIT is not set
+CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
 
@@ -1154,6 +1123,7 @@ CONFIG_SECURITY_CAPABILITIES=m
 CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
@@ -1161,3 +1131,4 @@ CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 64b7f1b3b2afe46beb295868f8ae45cedf1606ee..306302baff06c4fba06c1e2cd91643482dec6cde 100644 (file)
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21.5
+# Linux kernel version: 2.6.22.6
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -15,8 +15,9 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 # CONFIG_GENERIC_TIME is not set
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_IRQCHIP_DEMUX_GPIO=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -40,7 +41,9 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_TASKSTATS is not set
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -58,15 +61,20 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
-CONFIG_BUDDY=y
 # CONFIG_NP2 is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -185,9 +193,27 @@ CONFIG_WDTIMER=13
 # CONFIG_CMDLINE_BOOL is not set
 
 #
-# Board Setup
+# Clock/PLL Setup
 #
 CONFIG_CLKIN_HZ=11059200
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=750000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133000000
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+
+#
+# Memory Setup
+#
 CONFIG_MEM_SIZE=128
 CONFIG_MEM_ADD_WIDTH=11
 CONFIG_ENET_FLASH_PIN=0
@@ -198,6 +224,9 @@ CONFIG_BOOT_LOAD=0x1000
 #
 # CONFIG_BFIN_ALIVE_LED is not set
 # CONFIG_BFIN_IDLE_LED is not set
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
 CONFIG_BFIN_ALIVE_LED_PORT=0xFFC00700
 CONFIG_BFIN_ALIVE_LED_DPORT=0xFFC00730
 CONFIG_BFIN_IDLE_LED_PORT=0xFFC00700
@@ -207,15 +236,6 @@ CONFIG_BFIN_IDLE_LED_DPORT=0xFFC00730
 # Blackfin Kernel Optimizations
 #
 
-#
-# Timer Tick
-#
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-
 #
 # Memory Optimizations
 #
@@ -255,19 +275,14 @@ CONFIG_DMA_UNCACHED_1M=y
 #
 # Cache Support
 #
-CONFIG_BLKFIN_CACHE=y
-CONFIG_BLKFIN_DCACHE=y
-# CONFIG_BLKFIN_DCACHE_BANKA is not set
-# CONFIG_BLKFIN_CACHE_LOCK is not set
-# CONFIG_BLKFIN_WB is not set
-CONFIG_BLKFIN_WT=y
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+# CONFIG_BFIN_ICACHE_LOCK is not set
+# CONFIG_BFIN_WB is not set
+CONFIG_BFIN_WT=y
 CONFIG_L1_MAX_PIECE=16
 
-#
-# Clock Settings
-#
-# CONFIG_BFIN_KERNEL_CLOCK is not set
-
 #
 # Asynchonous Memory Configuration
 #
@@ -289,22 +304,19 @@ CONFIG_C_AMBEN_ALL=y
 CONFIG_BANK_0=0x7BB0
 CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
-CONFIG_BANK_3=0x99B3
+CONFIG_BANK_3=0xAAC3
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PCI Hotplug Support
-#
-
 #
 # Executable file formats
 #
@@ -339,7 +351,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -380,20 +391,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -460,7 +459,16 @@ CONFIG_IRTTY_SIR=m
 # FIR device drivers
 #
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
 
 #
 # Device Drivers
@@ -478,10 +486,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # Connector - unified userspace <-> kernelspace linker
 #
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
@@ -525,7 +529,6 @@ CONFIG_MTD_MW320D=m
 CONFIG_MTD_RAM=y
 CONFIG_MTD_ROM=m
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -562,16 +565,13 @@ CONFIG_BFIN_FLASH_BANK_3=0x7BB0
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
 
 #
-# OneNAND Flash Device Drivers
+# UBI - Unsorted block images
 #
-# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_UBI is not set
 
 #
 # Parallel port support
@@ -599,10 +599,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # Misc devices
 #
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
 # CONFIG_IDE is not set
 
 #
@@ -611,10 +607,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
 
 #
@@ -622,19 +614,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # CONFIG_MD is not set
 
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
 #
 # Network device support
 #
@@ -643,10 +622,6 @@ CONFIG_NETDEVICES=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
 
 #
@@ -656,27 +631,15 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_SMC91X=y
 # CONFIG_SMSC911X is not set
+# CONFIG_DM9000 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -700,6 +663,7 @@ CONFIG_SMC91X=y
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -716,8 +680,14 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
 # CONFIG_INPUT_UINPUT is not set
 # CONFIG_BF53X_PFBUTTONS is not set
 CONFIG_TWI_KEYPAD=m
@@ -734,7 +704,7 @@ CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=39
 #
 # CONFIG_AD9960 is not set
 # CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PFLAGS is not set
+# CONFIG_BFIN_PFLAGS is not set
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BF5xx_TIMERS is not set
 # CONFIG_BF5xx_PPI is not set
@@ -777,10 +747,6 @@ CONFIG_UNIX98_PTYS=y
 # IPMI
 #
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -792,7 +758,6 @@ CONFIG_BFIN_WDT=y
 CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 CONFIG_BLACKFIN_DPMC=y
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -800,11 +765,8 @@ CONFIG_BLACKFIN_DPMC=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
 CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=m
 
 #
@@ -818,10 +780,11 @@ CONFIG_I2C_ALGOBIT=m
 # I2C Hardware Bus support
 #
 # CONFIG_I2C_BLACKFIN_GPIO is not set
+# CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_STUB is not set
-# CONFIG_I2C_PCA_ISA is not set
 
 #
 # Miscellaneous I2C Chip support
@@ -857,18 +820,16 @@ CONFIG_SPI_BFIN=y
 # SPI Protocol Masters
 #
 # CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
 
 #
 # Dallas's 1-wire bus
 #
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
@@ -896,6 +857,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -920,22 +882,30 @@ CONFIG_HWMON=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Graphics support
+# Display device support
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
 CONFIG_FB=m
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB_DDC is not set
 CONFIG_FB_CFB_FILLRECT=m
 CONFIG_FB_CFB_COPYAREA=m
 CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -957,10 +927,6 @@ CONFIG_ADV7393_1XMEM=y
 # CONFIG_ADV7393_2XMEM is not set
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
-
-#
-# Logo configuration
-#
 # CONFIG_LOGO is not set
 
 #
@@ -1001,7 +967,6 @@ CONFIG_SND_BLACKFIN_AD1836_TDM=y
 # CONFIG_SND_BLACKFIN_AD1836_I2S is not set
 CONFIG_SND_BLACKFIN_AD1836_MULSUB=y
 # CONFIG_SND_BLACKFIN_AD1836_5P1 is not set
-CONFIG_SND_BLACKFIN_AD1981B=m
 CONFIG_SND_BLACKFIN_SPORT=0
 CONFIG_SND_BLACKFIN_SPI_PFBIT=4
 CONFIG_SND_BFIN_AD73311=m
@@ -1009,10 +974,15 @@ CONFIG_SND_BFIN_SPORT=0
 CONFIG_SND_BFIN_AD73311_SE=4
 
 #
-# SoC audio support
+# System on Chip audio support
 #
 # CONFIG_SND_SOC is not set
 
+#
+# SoC Audio for the ADI Blackfin
+#
+# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+
 #
 # Open Sound System
 #
@@ -1033,18 +1003,17 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
-# CONFIG_USB_GADGET is not set
 
 #
-# MMC/SD Card support
+# USB Gadget Support
 #
-# CONFIG_SPI_MMC is not set
+# CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 
 #
@@ -1084,44 +1053,50 @@ CONFIG_RTC_INTF_SYSFS=y
 CONFIG_RTC_INTF_PROC=y
 CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# RTC drivers
+# I2C RTC drivers
 #
-# CONFIG_RTC_DRV_X1205 is not set
 # CONFIG_RTC_DRV_DS1307 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
 # CONFIG_RTC_DRV_DS1672 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
 # CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+
+#
+# SPI RTC drivers
+#
 # CONFIG_RTC_DRV_RS5C348 is not set
-# CONFIG_RTC_DRV_RS5C372 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_TEST is not set
 # CONFIG_RTC_DRV_MAX6902 is not set
-# CONFIG_RTC_DRV_V3020 is not set
-CONFIG_RTC_DRV_BFIN=y
 
 #
-# DMA Engine support
+# Platform RTC drivers
 #
-# CONFIG_DMA_ENGINE is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# DMA Clients
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_BFIN=y
 
 #
-# DMA Devices
+# DMA Engine support
 #
+# CONFIG_DMA_ENGINE is not set
 
 #
-# Auxiliary Display support
+# DMA Clients
 #
 
 #
-# Virtualization
+# DMA Devices
 #
 
 #
@@ -1224,6 +1199,7 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
+# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1301,14 +1277,20 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_SERIAL_EARLY_INIT is not set
+CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
 
@@ -1331,6 +1313,7 @@ CONFIG_SECURITY_CAPABILITIES=m
 CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
@@ -1338,3 +1321,4 @@ CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index ccf09dc09a18303b9cff0c0f1f00527974dc3c98..828b604438eb153ebb861c8849823ee0bb698681 100644 (file)
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21.5
+# Linux kernel version: 2.6.22.6
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -15,8 +15,9 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 # CONFIG_GENERIC_TIME is not set
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_IRQCHIP_DEMUX_GPIO=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -40,7 +41,9 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_TASKSTATS is not set
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -58,15 +61,20 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
-CONFIG_BUDDY=y
 # CONFIG_NP2 is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -147,13 +155,6 @@ CONFIG_IRQ_PLL_WAKEUP=7
 # BF537 Specific Configuration
 #
 
-#
-# PORT F/G Selection
-#
-CONFIG_BF537_PORT_F=y
-# CONFIG_BF537_PORT_G is not set
-# CONFIG_BF537_PORT_H is not set
-
 #
 # Interrupt Priority Assignment
 #
@@ -199,19 +200,17 @@ CONFIG_IRQ_WATCH=13
 # CONFIG_CMDLINE_BOOL is not set
 
 #
-# Board Setup
+# Clock/PLL Setup
 #
 CONFIG_CLKIN_HZ=25000000
-CONFIG_MEM_SIZE=64
-CONFIG_MEM_ADD_WIDTH=10
-CONFIG_BOOT_LOAD=0x1000
-
-#
-# Blackfin Kernel Optimizations
-#
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=600000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133000000
+CONFIG_MIN_SCLK_HZ=27000000
 
 #
-# Timer Tick
+# Kernel Timer/Scheduler
 #
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
@@ -219,6 +218,20 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 
+#
+# Memory Setup
+#
+CONFIG_MEM_SIZE=64
+CONFIG_MEM_ADD_WIDTH=10
+CONFIG_BOOT_LOAD=0x1000
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
 #
 # Memory Optimizations
 #
@@ -258,19 +271,14 @@ CONFIG_DMA_UNCACHED_1M=y
 #
 # Cache Support
 #
-CONFIG_BLKFIN_CACHE=y
-CONFIG_BLKFIN_DCACHE=y
-# CONFIG_BLKFIN_DCACHE_BANKA is not set
-# CONFIG_BLKFIN_CACHE_LOCK is not set
-# CONFIG_BLKFIN_WB is not set
-CONFIG_BLKFIN_WT=y
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+# CONFIG_BFIN_ICACHE_LOCK is not set
+# CONFIG_BFIN_WB is not set
+CONFIG_BFIN_WT=y
 CONFIG_L1_MAX_PIECE=16
 
-#
-# Clock Settings
-#
-# CONFIG_BFIN_KERNEL_CLOCK is not set
-
 #
 # Asynchonous Memory Configuration
 #
@@ -298,16 +306,13 @@ CONFIG_BANK_3=0x99B3
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PCI Hotplug Support
-#
-
 #
 # Executable file formats
 #
@@ -342,7 +347,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -383,20 +387,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -463,7 +455,16 @@ CONFIG_IRTTY_SIR=m
 # FIR device drivers
 #
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
 
 #
 # Device Drivers
@@ -481,10 +482,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # Connector - unified userspace <-> kernelspace linker
 #
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
@@ -528,7 +525,6 @@ CONFIG_MTD_MW320D=m
 CONFIG_MTD_RAM=y
 CONFIG_MTD_ROM=m
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -565,13 +561,10 @@ CONFIG_BFIN_FLASH_BANK_3=0x7BB0
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 CONFIG_MTD_NAND=m
 # CONFIG_MTD_NAND_VERIFY_WRITE is not set
 # CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
 CONFIG_MTD_NAND_BFIN=m
 CONFIG_BFIN_NAND_BASE=0x20212000
 CONFIG_BFIN_NAND_CLE=2
@@ -580,11 +573,13 @@ CONFIG_BFIN_NAND_READY=3
 CONFIG_MTD_NAND_IDS=m
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
 
 #
-# OneNAND Flash Device Drivers
+# UBI - Unsorted block images
 #
-# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_UBI is not set
 
 #
 # Parallel port support
@@ -612,10 +607,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # Misc devices
 #
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
 # CONFIG_IDE is not set
 
 #
@@ -624,10 +615,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
 
 #
@@ -635,19 +622,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # CONFIG_MD is not set
 
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
 #
 # Network device support
 #
@@ -656,11 +630,20 @@ CONFIG_NETDEVICES=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+CONFIG_PHYLIB=y
 
 #
-# PHY device support
+# MII PHY device drivers
 #
-# CONFIG_PHYLIB is not set
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -674,27 +657,15 @@ CONFIG_BFIN_TX_DESC_NUM=10
 CONFIG_BFIN_RX_DESC_NUM=20
 # CONFIG_BFIN_MAC_RMII is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DM9000 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -718,6 +689,7 @@ CONFIG_BFIN_RX_DESC_NUM=20
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -734,8 +706,14 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
 # CONFIG_INPUT_UINPUT is not set
 # CONFIG_BF53X_PFBUTTONS is not set
 CONFIG_TWI_KEYPAD=m
@@ -752,7 +730,7 @@ CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72
 #
 # CONFIG_AD9960 is not set
 # CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PFLAGS is not set
+# CONFIG_BFIN_PFLAGS is not set
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BF5xx_TIMERS is not set
 # CONFIG_BF5xx_PPI is not set
@@ -803,10 +781,6 @@ CONFIG_CAN_BLACKFIN=m
 # IPMI
 #
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -818,7 +792,6 @@ CONFIG_BFIN_WDT=y
 CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
 CONFIG_BLACKFIN_DPMC=y
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -826,11 +799,8 @@ CONFIG_BLACKFIN_DPMC=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
 CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=m
 
 #
@@ -846,10 +816,11 @@ CONFIG_I2C_CHARDEV=m
 # CONFIG_I2C_BLACKFIN_GPIO is not set
 CONFIG_I2C_BLACKFIN_TWI=m
 CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
+# CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_STUB is not set
-# CONFIG_I2C_PCA_ISA is not set
 
 #
 # Miscellaneous I2C Chip support
@@ -885,18 +856,16 @@ CONFIG_SPI_BFIN=y
 # SPI Protocol Masters
 #
 # CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
 
 #
 # Dallas's 1-wire bus
 #
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
@@ -924,6 +893,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -948,11 +918,8 @@ CONFIG_HWMON=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
 
 #
 # Graphics support
@@ -960,12 +927,23 @@ CONFIG_HWMON=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=m
 CONFIG_LCD_CLASS_DEVICE=m
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
 CONFIG_FB=m
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB_DDC is not set
 CONFIG_FB_CFB_FILLRECT=m
 CONFIG_FB_CFB_COPYAREA=m
 CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -991,10 +969,6 @@ CONFIG_LQ035_SLAVE_ADDR=0x58
 # CONFIG_FB_BFIN_BGR is not set
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
-
-#
-# Logo configuration
-#
 # CONFIG_LOGO is not set
 
 #
@@ -1035,7 +1009,6 @@ CONFIG_SND_BLACKFIN_AD1836_TDM=y
 # CONFIG_SND_BLACKFIN_AD1836_I2S is not set
 CONFIG_SND_BLACKFIN_AD1836_MULSUB=y
 # CONFIG_SND_BLACKFIN_AD1836_5P1 is not set
-CONFIG_SND_BLACKFIN_AD1981B=m
 CONFIG_SND_BLACKFIN_SPORT=0
 CONFIG_SND_BLACKFIN_SPI_PFBIT=4
 CONFIG_SND_BFIN_AD73311=m
@@ -1043,10 +1016,15 @@ CONFIG_SND_BFIN_SPORT=0
 CONFIG_SND_BFIN_AD73311_SE=4
 
 #
-# SoC audio support
+# System on Chip audio support
 #
 # CONFIG_SND_SOC is not set
 
+#
+# SoC Audio for the ADI Blackfin
+#
+# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+
 #
 # Open Sound System
 #
@@ -1067,18 +1045,17 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
-# CONFIG_USB_GADGET is not set
 
 #
-# MMC/SD Card support
+# USB Gadget Support
 #
-# CONFIG_SPI_MMC is not set
+# CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 
 #
@@ -1118,44 +1095,50 @@ CONFIG_RTC_INTF_SYSFS=y
 CONFIG_RTC_INTF_PROC=y
 CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# RTC drivers
+# I2C RTC drivers
 #
-# CONFIG_RTC_DRV_X1205 is not set
 # CONFIG_RTC_DRV_DS1307 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
 # CONFIG_RTC_DRV_DS1672 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
 # CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+
+#
+# SPI RTC drivers
+#
 # CONFIG_RTC_DRV_RS5C348 is not set
-# CONFIG_RTC_DRV_RS5C372 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_TEST is not set
 # CONFIG_RTC_DRV_MAX6902 is not set
-# CONFIG_RTC_DRV_V3020 is not set
-CONFIG_RTC_DRV_BFIN=y
 
 #
-# DMA Engine support
+# Platform RTC drivers
 #
-# CONFIG_DMA_ENGINE is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# DMA Clients
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_BFIN=y
 
 #
-# DMA Devices
+# DMA Engine support
 #
+# CONFIG_DMA_ENGINE is not set
 
 #
-# Auxiliary Display support
+# DMA Clients
 #
 
 #
-# Virtualization
+# DMA Devices
 #
 
 #
@@ -1258,6 +1241,7 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
+# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1335,14 +1319,20 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_SERIAL_EARLY_INIT is not set
+CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
 
@@ -1365,6 +1355,7 @@ CONFIG_SECURITY_CAPABILITIES=m
 CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
@@ -1372,3 +1363,4 @@ CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index ac8390fafa9cd759a1d9e6d3a823f3f1be9ee6fd..e80f3d59c2837de2481d1407b322b148d736c494 100644 (file)
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21.5
+# Linux kernel version: 2.6.22.6
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -15,8 +15,9 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 # CONFIG_GENERIC_TIME is not set
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_IRQCHIP_DEMUX_GPIO=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -40,7 +41,9 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_TASKSTATS is not set
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -51,7 +54,6 @@ CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
@@ -59,14 +61,20 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
 # CONFIG_NP2 is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -165,6 +173,7 @@ CONFIG_IRQ_UART1_TX=10
 #
 # BF548 Specific Configuration
 #
+# CONFIG_DEB_DMA_URGENT is not set
 
 #
 # Interrupt Priority Assignment
@@ -242,24 +251,35 @@ CONFIG_IRQ_PINT2=11
 CONFIG_IRQ_PINT3=11
 
 #
-# Board customizations
+# Pin Interrupt to Port Assignment
 #
-# CONFIG_CMDLINE_BOOL is not set
 
 #
-# Board Setup
+# Assignment
 #
-CONFIG_CLKIN_HZ=25000000
-CONFIG_MEM_SIZE=64
-CONFIG_MEM_ADD_WIDTH=10
-CONFIG_BOOT_LOAD=0x1000
+CONFIG_PINTx_REASSIGN=y
+CONFIG_PINT0_ASSIGN=0x00000101
+CONFIG_PINT1_ASSIGN=0x01010000
+CONFIG_PINT2_ASSIGN=0x07000101
+CONFIG_PINT3_ASSIGN=0x02020303
 
 #
-# Blackfin Kernel Optimizations
+# Board customizations
 #
+# CONFIG_CMDLINE_BOOL is not set
 
 #
-# Timer Tick
+# Clock/PLL Setup
+#
+CONFIG_CLKIN_HZ=25000000
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=533000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133000000
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
 #
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
@@ -267,6 +287,20 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 
+#
+# Memory Setup
+#
+CONFIG_MEM_SIZE=64
+CONFIG_MEM_ADD_WIDTH=10
+CONFIG_BOOT_LOAD=0x1000
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
 #
 # Memory Optimizations
 #
@@ -275,12 +309,12 @@ CONFIG_EXCPT_IRQ_SYSC_L1=y
 CONFIG_DO_IRQ_L1=y
 CONFIG_CORE_TIMER_IRQ_L1=y
 CONFIG_IDLE_L1=y
-CONFIG_SCHEDULE_L1=y
+# CONFIG_SCHEDULE_L1 is not set
 CONFIG_ARITHMETIC_OPS_L1=y
 CONFIG_ACCESS_OK_L1=y
-CONFIG_MEMSET_L1=y
-CONFIG_MEMCPY_L1=y
-CONFIG_SYS_BFIN_SPINLOCK_L1=y
+# CONFIG_MEMSET_L1 is not set
+# CONFIG_MEMCPY_L1 is not set
+# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set
 # CONFIG_IP_CHECKSUM_L1 is not set
 CONFIG_CACHELINE_ALIGNED_L1=y
 # CONFIG_SYSCALL_TAB_L1 is not set
@@ -306,19 +340,14 @@ CONFIG_DMA_UNCACHED_1M=y
 #
 # Cache Support
 #
-CONFIG_BLKFIN_CACHE=y
-CONFIG_BLKFIN_DCACHE=y
-# CONFIG_BLKFIN_DCACHE_BANKA is not set
-# CONFIG_BLKFIN_CACHE_LOCK is not set
-# CONFIG_BLKFIN_WB is not set
-CONFIG_BLKFIN_WT=y
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+# CONFIG_BFIN_ICACHE_LOCK is not set
+# CONFIG_BFIN_WB is not set
+CONFIG_BFIN_WT=y
 CONFIG_L1_MAX_PIECE=16
 
-#
-# Clock Settings
-#
-# CONFIG_BFIN_KERNEL_CLOCK is not set
-
 #
 # Asynchonous Memory Configuration
 #
@@ -327,7 +356,6 @@ CONFIG_L1_MAX_PIECE=16
 # EBIU_AMBCTL Global Control
 #
 CONFIG_C_AMCKEN=y
-CONFIG_C_CDPRIO=y
 # CONFIG_C_AMBEN is not set
 # CONFIG_C_AMBEN_B0 is not set
 # CONFIG_C_AMBEN_B0_B1 is not set
@@ -338,7 +366,7 @@ CONFIG_C_AMBEN_ALL=y
 # EBIU_AMBCTL Control
 #
 CONFIG_BANK_0=0x7BB0
-CONFIG_BANK_1=0x7BB0
+CONFIG_BANK_1=0x5554
 CONFIG_BANK_2=0x7BB0
 CONFIG_BANK_3=0x99B3
 
@@ -346,16 +374,13 @@ CONFIG_BANK_3=0x99B3
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PCI Hotplug Support
-#
-
 #
 # Executable file formats
 #
@@ -383,7 +408,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -424,20 +448,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -463,7 +475,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
 
 #
 # Device Drivers
@@ -475,29 +496,23 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 
 #
 # Connector - unified userspace <-> kernelspace linker
 #
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
 
 #
 # User Modules And Translation Layers
 #
-# CONFIG_MTD_CHAR is not set
+CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLKDEVS=y
 CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
@@ -509,8 +524,10 @@ CONFIG_MTD_BLOCK=y
 #
 # RAM/ROM/Flash chip drivers
 #
-# CONFIG_MTD_CFI is not set
+CONFIG_MTD_CFI=y
 # CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
 CONFIG_MTD_MAP_BANK_WIDTH_1=y
 CONFIG_MTD_MAP_BANK_WIDTH_2=y
 CONFIG_MTD_MAP_BANK_WIDTH_4=y
@@ -521,22 +538,32 @@ CONFIG_MTD_CFI_I1=y
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_MW320D is not set
+CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
 #
 CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x20000000
+CONFIG_MTD_PHYSMAP_LEN=0x400000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
 # CONFIG_MTD_BF5xx is not set
-CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_UCLINUX is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -548,16 +575,23 @@ CONFIG_MTD_UCLINUX=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_BFIN is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_BF5XX=y
+CONFIG_MTD_NAND_BF5XX_HWECC=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
 
 #
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
+# UBI - Unsorted block images
 #
-# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_UBI is not set
 
 #
 # Parallel port support
@@ -585,41 +619,61 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # Misc devices
 #
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
 # CONFIG_IDE is not set
 
 #
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
 
 #
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
+# SCSI support type (disk, tape, CD-ROM)
 #
-# CONFIG_ATA is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
 
 #
-# Multi-device support (RAID and LVM)
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
-# CONFIG_MD is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
 
 #
-# Fusion MPT device support
+# SCSI Transports
 #
-# CONFIG_FUSION is not set
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
 
 #
-# IEEE 1394 (FireWire) support
+# SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_PATA_PLATFORM is not set
+CONFIG_PATA_BF54X=y
+CONFIG_PATA_BF54X_DMA=y
 
 #
-# I2O device support
+# Multi-device support (RAID and LVM)
 #
+# CONFIG_MD is not set
 
 #
 # Network device support
@@ -629,10 +683,6 @@ CONFIG_NETDEVICES=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
 
 #
@@ -641,28 +691,16 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_SMC91X is not set
-# CONFIG_SMSC911X is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
+CONFIG_SMSC911X=y
+# CONFIG_DM9000 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
 
 #
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -686,6 +724,7 @@ CONFIG_MII=y
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -702,10 +741,17 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
 # CONFIG_INPUT_UINPUT is not set
 # CONFIG_BF53X_PFBUTTONS is not set
+# CONFIG_TWI_KEYPAD is not set
 
 #
 # Hardware I/O ports
@@ -718,12 +764,15 @@ CONFIG_INPUT_MISC=y
 #
 # CONFIG_AD9960 is not set
 # CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PFLAGS is not set
+# CONFIG_BFIN_PFLAGS is not set
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BF5xx_TIMERS is not set
 # CONFIG_BF5xx_PPI is not set
 # CONFIG_BFIN_SPORT is not set
 # CONFIG_BFIN_TIMER_LATENCY is not set
+# CONFIG_TWI_LCD is not set
+# CONFIG_AD5304 is not set
+# CONFIG_BF5xx_TEA5764 is not set
 # CONFIG_BF5xx_FBDMA is not set
 # CONFIG_VT is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
@@ -760,14 +809,9 @@ CONFIG_UNIX98_PTYS=y
 # IPMI
 #
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -775,32 +819,114 @@ CONFIG_HW_RANDOM=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C support
+# I2C Hardware Bus support
 #
-# CONFIG_I2C is not set
+# CONFIG_I2C_BLACKFIN_GPIO is not set
+CONFIG_I2C_BLACKFIN_TWI=y
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_AD5252 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCF8575 is not set
+# CONFIG_SENSORS_PCA9543 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
 
 #
 # SPI support
 #
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
 
 #
-# Dallas's 1-wire bus
+# SPI Master Controller Drivers
 #
-# CONFIG_W1 is not set
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
 
 #
-# Hardware Monitoring support
+# Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
@@ -812,16 +938,19 @@ CONFIG_HWMON=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Graphics support
+# Display device support
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
 # CONFIG_FB is not set
 
 #
@@ -843,6 +972,10 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_EHCI is not set
 # CONFIG_USB is not set
 
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
@@ -851,11 +984,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=m
 
 #
-# MMC/SD Card support
+# MMC/SD Host Controller Drivers
 #
-# CONFIG_MMC is not set
+CONFIG_SDH_BFIN=m
+# CONFIG_SPI_MMC is not set
 
 #
 # LED devices
@@ -894,15 +1036,37 @@ CONFIG_RTC_INTF_SYSFS=y
 CONFIG_RTC_INTF_PROC=y
 CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# RTC drivers
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+
+#
+# Platform RTC drivers
 #
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_TEST is not set
 # CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
 CONFIG_RTC_DRV_BFIN=y
 
 #
@@ -918,14 +1082,6 @@ CONFIG_RTC_DRV_BFIN=y
 # DMA Devices
 #
 
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
 #
 # PBX support
 #
@@ -991,8 +1147,25 @@ CONFIG_RAMFS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_YAFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_YAFFS_FS=m
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
@@ -1040,36 +1213,20 @@ CONFIG_MSDOS_PARTITION=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_LIST is not set
-CONFIG_FRAME_POINTER=y
-CONFIG_FORCED_INLINING=y
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_FAULT_INJECTION is not set
-CONFIG_DEBUG_HWERR=y
-# CONFIG_DEBUG_ICACHE_CHECK is not set
-# CONFIG_DEBUG_KERNEL_START is not set
-# CONFIG_DEBUG_SERIAL_EARLY_INIT is not set
+CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
 
@@ -1092,9 +1249,12 @@ CONFIG_SECURITY_CAPABILITIES=y
 CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 51c0b6f97798940450c96c3b64f3deae2262680b..85e647f877590de234fb67f94b46d775620f407a 100644 (file)
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21.5
+# Linux kernel version: 2.6.22.6
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -15,8 +15,9 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 # CONFIG_GENERIC_TIME is not set
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_IRQCHIP_DEMUX_GPIO=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -40,7 +41,9 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_TASKSTATS is not set
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -58,15 +61,20 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
-CONFIG_BUDDY=y
 # CONFIG_NP2 is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -229,19 +237,17 @@ CONFIG_IRQ_WDTIMER=13
 # CONFIG_CMDLINE_BOOL is not set
 
 #
-# Board Setup
+# Clock/PLL Setup
 #
 CONFIG_CLKIN_HZ=30000000
-CONFIG_MEM_SIZE=64
-CONFIG_MEM_ADD_WIDTH=9
-CONFIG_BOOT_LOAD=0x1000
-
-#
-# Blackfin Kernel Optimizations
-#
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=600000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133000000
+CONFIG_MIN_SCLK_HZ=27000000
 
 #
-# Timer Tick
+# Kernel Timer/Scheduler
 #
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
@@ -249,6 +255,20 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 
+#
+# Memory Setup
+#
+CONFIG_MEM_SIZE=64
+CONFIG_MEM_ADD_WIDTH=9
+CONFIG_BOOT_LOAD=0x1000
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
 #
 # Memory Optimizations
 #
@@ -288,19 +308,14 @@ CONFIG_DMA_UNCACHED_1M=y
 #
 # Cache Support
 #
-CONFIG_BLKFIN_CACHE=y
-CONFIG_BLKFIN_DCACHE=y
-# CONFIG_BLKFIN_DCACHE_BANKA is not set
-# CONFIG_BLKFIN_CACHE_LOCK is not set
-# CONFIG_BLKFIN_WB is not set
-CONFIG_BLKFIN_WT=y
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+# CONFIG_BFIN_ICACHE_LOCK is not set
+# CONFIG_BFIN_WB is not set
+CONFIG_BFIN_WT=y
 CONFIG_L1_MAX_PIECE=16
 
-#
-# Clock Settings
-#
-# CONFIG_BFIN_KERNEL_CLOCK is not set
-
 #
 # Asynchonous Memory Configuration
 #
@@ -326,22 +341,19 @@ CONFIG_C_AMBEN_ALL=y
 CONFIG_BANK_0=0x7BB0
 CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
-CONFIG_BANK_3=0x99B3
+CONFIG_BANK_3=0xAAC3
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PCI Hotplug Support
-#
-
 #
 # Executable file formats
 #
@@ -364,7 +376,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -405,20 +416,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -485,7 +484,16 @@ CONFIG_IRTTY_SIR=m
 # FIR device drivers
 #
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
 
 #
 # Device Drivers
@@ -503,10 +511,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # Connector - unified userspace <-> kernelspace linker
 #
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
@@ -550,7 +554,6 @@ CONFIG_MTD_MW320D=m
 CONFIG_MTD_RAM=y
 CONFIG_MTD_ROM=m
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -588,16 +591,13 @@ CONFIG_BFIN_FLASH_BANK_3=0x7BB0
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
 
 #
-# OneNAND Flash Device Drivers
+# UBI - Unsorted block images
 #
-# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_UBI is not set
 
 #
 # Parallel port support
@@ -625,10 +625,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # Misc devices
 #
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
 # CONFIG_IDE is not set
 
 #
@@ -637,10 +633,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
 
 #
@@ -648,19 +640,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # CONFIG_MD is not set
 
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
 #
 # Network device support
 #
@@ -669,10 +648,6 @@ CONFIG_NETDEVICES=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-
-#
-# PHY device support
-#
 # CONFIG_PHYLIB is not set
 
 #
@@ -682,27 +657,15 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_SMC91X=y
 # CONFIG_SMSC911X is not set
+# CONFIG_DM9000 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -726,6 +689,7 @@ CONFIG_SMC91X=y
 #
 CONFIG_INPUT=m
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -742,6 +706,7 @@ CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 
@@ -756,7 +721,7 @@ CONFIG_INPUT_EVDEV=m
 #
 # CONFIG_AD9960 is not set
 # CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PFLAGS is not set
+# CONFIG_BFIN_PFLAGS is not set
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BF5xx_TIMERS is not set
 # CONFIG_BF5xx_PPI is not set
@@ -796,10 +761,6 @@ CONFIG_UNIX98_PTYS=y
 # IPMI
 #
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -810,7 +771,6 @@ CONFIG_WATCHDOG=y
 CONFIG_BFIN_WDT=y
 CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -818,10 +778,6 @@ CONFIG_HW_RANDOM=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
 # CONFIG_I2C is not set
 
 #
@@ -840,22 +796,22 @@ CONFIG_SPI_BFIN=y
 # SPI Protocol Masters
 #
 # CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
 
 #
 # Dallas's 1-wire bus
 #
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_LM70 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83627HF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
@@ -867,16 +823,19 @@ CONFIG_HWMON=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
 
 #
-# Digital Video Broadcasting Devices
+# Graphics support
 #
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
-# Graphics support
+# Display device support
 #
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
 # CONFIG_FB is not set
 
 #
@@ -899,18 +858,17 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
-# CONFIG_USB_GADGET is not set
 
 #
-# MMC/SD Card support
+# USB Gadget Support
 #
-# CONFIG_SPI_MMC is not set
+# CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 
 #
@@ -952,14 +910,6 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # DMA Devices
 #
 
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-
 #
 # PBX support
 #
@@ -1060,6 +1010,7 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
+# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1137,14 +1088,20 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_SERIAL_EARLY_INIT is not set
+CONFIG_DEBUG_MMRS=y
 CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_DUAL_CORE_TEST_MODULE is not set
 CONFIG_CPLB_INFO=y
 CONFIG_ACCESS_CHECK=y
@@ -1168,6 +1125,7 @@ CONFIG_SECURITY_CAPABILITIES=m
 CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
@@ -1175,3 +1133,4 @@ CONFIG_ZLIB_DEFLATE=m
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 983ed181c896fa7aec05d481370546f2d2b70228..15e36aaf21865d49e24cbf30aa1dfcd6761a842f 100644 (file)
@@ -1,6 +1,6 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21.5
+# Linux kernel version: 2.6.22.6
 #
 # CONFIG_MMU is not set
 # CONFIG_FPU is not set
@@ -15,8 +15,9 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 # CONFIG_GENERIC_TIME is not set
-CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_GPIO=y
 CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_IRQCHIP_DEMUX_GPIO=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -41,6 +42,7 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_UTS_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED=y
 # CONFIG_RELAY is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -57,15 +59,20 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=9
-CONFIG_BUDDY=y
 # CONFIG_NP2 is not set
 CONFIG_SLAB=y
-CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
 CONFIG_RT_MUTEXES=y
 CONFIG_TINY_SHMEM=y
 CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
 
 #
 # Loadable module support
@@ -146,13 +153,6 @@ CONFIG_IRQ_PLL_WAKEUP=7
 # BF537 Specific Configuration
 #
 
-#
-# PORT F/G Selection
-#
-CONFIG_BF537_PORT_F=y
-# CONFIG_BF537_PORT_G is not set
-# CONFIG_BF537_PORT_H is not set
-
 #
 # Interrupt Priority Assignment
 #
@@ -198,19 +198,17 @@ CONFIG_IRQ_WATCH=13
 # CONFIG_CMDLINE_BOOL is not set
 
 #
-# Board Setup
+# Clock/PLL Setup
 #
 CONFIG_CLKIN_HZ=24576000
-CONFIG_MEM_SIZE=64
-CONFIG_MEM_ADD_WIDTH=10
-CONFIG_BOOT_LOAD=0x1000
-
-#
-# Blackfin Kernel Optimizations
-#
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=600000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133000000
+CONFIG_MIN_SCLK_HZ=27000000
 
 #
-# Timer Tick
+# Kernel Timer/Scheduler
 #
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
@@ -218,6 +216,20 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 
+#
+# Memory Setup
+#
+CONFIG_MEM_SIZE=64
+CONFIG_MEM_ADD_WIDTH=10
+CONFIG_BOOT_LOAD=0x1000
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
 #
 # Memory Optimizations
 #
@@ -257,19 +269,14 @@ CONFIG_DMA_UNCACHED_1M=y
 #
 # Cache Support
 #
-CONFIG_BLKFIN_CACHE=y
-CONFIG_BLKFIN_DCACHE=y
-# CONFIG_BLKFIN_DCACHE_BANKA is not set
-# CONFIG_BLKFIN_CACHE_LOCK is not set
-CONFIG_BLKFIN_WB=y
-# CONFIG_BLKFIN_WT is not set
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+# CONFIG_BFIN_ICACHE_LOCK is not set
+CONFIG_BFIN_WB=y
+# CONFIG_BFIN_WT is not set
 CONFIG_L1_MAX_PIECE=16
 
-#
-# Clock Settings
-#
-# CONFIG_BFIN_KERNEL_CLOCK is not set
-
 #
 # Asynchonous Memory Configuration
 #
@@ -297,16 +304,13 @@ CONFIG_BANK_3=0x99B3
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
 #
 # CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
 
-#
-# PCI Hotplug Support
-#
-
 #
 # Executable file formats
 #
@@ -334,7 +338,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -375,20 +378,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETLABEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -414,7 +405,16 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
 
 #
 # Device Drivers
@@ -432,10 +432,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # Connector - unified userspace <-> kernelspace linker
 #
 # CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
@@ -473,7 +469,6 @@ CONFIG_MTD_CFI_I2=y
 CONFIG_MTD_RAM=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
 
 #
 # Mapping drivers for chip access
@@ -499,13 +494,10 @@ CONFIG_MTD_UCLINUX=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
 CONFIG_MTD_NAND=y
 # CONFIG_MTD_NAND_VERIFY_WRITE is not set
 # CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
 CONFIG_MTD_NAND_BFIN=y
 CONFIG_BFIN_NAND_BASE=0x20100000
 CONFIG_BFIN_NAND_CLE=2
@@ -514,11 +506,13 @@ CONFIG_BFIN_NAND_READY=44
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
 
 #
-# OneNAND Flash Device Drivers
+# UBI - Unsorted block images
 #
-# CONFIG_MTD_ONENAND is not set
+# CONFIG_MTD_UBI is not set
 
 #
 # Parallel port support
@@ -546,10 +540,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # Misc devices
 #
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
 # CONFIG_IDE is not set
 
 #
@@ -558,10 +548,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
 # CONFIG_ATA is not set
 
 #
@@ -569,19 +555,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 #
 # CONFIG_MD is not set
 
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
 #
 # Network device support
 #
@@ -590,11 +563,20 @@ CONFIG_NETDEVICES=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+CONFIG_PHYLIB=y
 
 #
-# PHY device support
+# MII PHY device drivers
 #
-# CONFIG_PHYLIB is not set
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -608,27 +590,15 @@ CONFIG_BFIN_TX_DESC_NUM=100
 CONFIG_BFIN_RX_DESC_NUM=100
 CONFIG_BFIN_MAC_RMII=y
 # CONFIG_SMSC911X is not set
+# CONFIG_DM9000 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
 
 #
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
 #
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -652,6 +622,7 @@ CONFIG_BFIN_MAC_RMII=y
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -670,6 +641,7 @@ CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_ADS7846 is not set
 CONFIG_TOUCHSCREEN_AD7877=y
@@ -681,7 +653,13 @@ CONFIG_TOUCHSCREEN_AD7877=y
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
 # CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
 CONFIG_INPUT_UINPUT=y
 # CONFIG_BF53X_PFBUTTONS is not set
 # CONFIG_TWI_KEYPAD is not set
@@ -697,7 +675,7 @@ CONFIG_INPUT_UINPUT=y
 #
 # CONFIG_AD9960 is not set
 # CONFIG_SPI_ADC_BF533 is not set
-# CONFIG_BF5xx_PFLAGS is not set
+# CONFIG_BFIN_PFLAGS is not set
 # CONFIG_BF5xx_PPIFCD is not set
 # CONFIG_BF5xx_TIMERS is not set
 # CONFIG_BF5xx_PPI is not set
@@ -749,14 +727,9 @@ CONFIG_CAN_BLACKFIN=m
 # IPMI
 #
 # CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
 # CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -764,11 +737,8 @@ CONFIG_HW_RANDOM=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
 CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=y
 
 #
@@ -784,10 +754,11 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_BLACKFIN_GPIO is not set
 CONFIG_I2C_BLACKFIN_TWI=y
 CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
+# CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_STUB is not set
-# CONFIG_I2C_PCA_ISA is not set
 
 #
 # Miscellaneous I2C Chip support
@@ -823,18 +794,16 @@ CONFIG_SPI_BFIN=y
 # SPI Protocol Masters
 #
 # CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
 
 #
 # Dallas's 1-wire bus
 #
 # CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
 # CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
@@ -862,6 +831,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -886,11 +856,8 @@ CONFIG_HWMON=y
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
 
 #
 # Graphics support
@@ -898,12 +865,23 @@ CONFIG_HWMON=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_LCD_CLASS_DEVICE=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
 CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB_DDC is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -921,10 +899,6 @@ CONFIG_FB_BFIN_LANDSCAPE=y
 # CONFIG_FB_BFIN_BGR is not set
 # CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
-
-#
-# Logo configuration
-#
 # CONFIG_LOGO is not set
 
 #
@@ -936,8 +910,6 @@ CONFIG_SOUND=y
 # Advanced Linux Sound Architecture
 #
 CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
 # CONFIG_SND_PCM_OSS is not set
@@ -959,19 +931,23 @@ CONFIG_SND_PCM=m
 # ALSA Blackfin devices
 #
 # CONFIG_SND_BLACKFIN_AD1836 is not set
-CONFIG_SND_BLACKFIN_AD1981B=m
 # CONFIG_SND_BFIN_AD73311 is not set
 
 #
-# SoC audio support
+# System on Chip audio support
 #
 # CONFIG_SND_SOC is not set
 
+#
+# SoC Audio for the ADI Blackfin
+#
+# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
+
 #
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=y
-# CONFIG_OBSOLETE_OSS is not set
+# CONFIG_OSS_OBSOLETE is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 
@@ -989,18 +965,17 @@ CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
 #
 
 #
-# USB Gadget Support
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
-# CONFIG_USB_GADGET is not set
 
 #
-# MMC/SD Card support
+# USB Gadget Support
 #
-# CONFIG_SPI_MMC is not set
+# CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 
 #
@@ -1040,44 +1015,50 @@ CONFIG_RTC_INTF_SYSFS=y
 CONFIG_RTC_INTF_PROC=y
 CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
 
 #
-# RTC drivers
+# I2C RTC drivers
 #
-# CONFIG_RTC_DRV_X1205 is not set
 # CONFIG_RTC_DRV_DS1307 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
 # CONFIG_RTC_DRV_DS1672 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
 # CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+
+#
+# SPI RTC drivers
+#
 # CONFIG_RTC_DRV_RS5C348 is not set
-# CONFIG_RTC_DRV_RS5C372 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_TEST is not set
 # CONFIG_RTC_DRV_MAX6902 is not set
-# CONFIG_RTC_DRV_V3020 is not set
-CONFIG_RTC_DRV_BFIN=y
 
 #
-# DMA Engine support
+# Platform RTC drivers
 #
-# CONFIG_DMA_ENGINE is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
-# DMA Clients
+# on-CPU RTC drivers
 #
+CONFIG_RTC_DRV_BFIN=y
 
 #
-# DMA Devices
+# DMA Engine support
 #
+# CONFIG_DMA_ENGINE is not set
 
 #
-# Auxiliary Display support
+# DMA Clients
 #
 
 #
-# Virtualization
+# DMA Devices
 #
 
 #
@@ -1176,6 +1157,7 @@ CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
+# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1256,11 +1238,17 @@ CONFIG_ENABLE_MUST_CHECK=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_SERIAL_EARLY_INIT is not set
+# CONFIG_DEBUG_MMRS is not set
 # CONFIG_DEBUG_HUNT_FOR_ZERO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
 # CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+# CONFIG_EARLY_PRINTK is not set
 # CONFIG_CPLB_INFO is not set
 # CONFIG_ACCESS_CHECK is not set
 
@@ -1283,9 +1271,11 @@ CONFIG_SECURITY_CAPABILITIES=y
 CONFIG_BITREVERSE=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index f429ebc3a9613ff8d263a4d46cbba4cdb01aa108..8aeb6066b19b06ffb875d7b1ff75cdb0ece34d86 100644 (file)
@@ -7,11 +7,10 @@ extra-y := init_task.o vmlinux.lds
 obj-y := \
        entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
        sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
-       fixed_code.o cplbinit.o cacheinit.o
+       fixed_code.o cplbinit.o cacheinit.o reboot.o bfin_gpio.o
 
-obj-$(CONFIG_BF53x)                 += bfin_gpio.o
-obj-$(CONFIG_BF561)                 += bfin_gpio.o
 obj-$(CONFIG_MODULES)                += module.o
 obj-$(CONFIG_BFIN_DMA_5XX)           += bfin_dma_5xx.o
 obj-$(CONFIG_DUAL_CORE_TEST_MODULE)  += dualcore_test.o
 obj-$(CONFIG_KGDB)                   += kgdb.o
+obj-$(CONFIG_EARLY_PRINTK)           += early_printk.o
index 7cf02f02a1dbed0243cfda428d9768687f0ab808..e19164fb4cd1dfe1de064e201643d72416ff6c53 100644 (file)
@@ -73,6 +73,11 @@ static int __init blackfin_dma_init(void)
        /* Mark MEMDMA Channel 0 as requested since we're using it internally */
        dma_ch[CH_MEM_STREAM0_DEST].chan_status = DMA_CHANNEL_REQUESTED;
        dma_ch[CH_MEM_STREAM0_SRC].chan_status = DMA_CHANNEL_REQUESTED;
+
+#if defined(CONFIG_DEB_DMA_URGENT)
+       bfin_write_EBIU_DDRQUE(bfin_read_EBIU_DDRQUE()
+                        | DEB1_URGENT | DEB2_URGENT | DEB3_URGENT);
+#endif
        return 0;
 }
 
@@ -265,10 +270,23 @@ void set_dma_next_desc_addr(unsigned int channel, unsigned long addr)
 
        dma_ch[channel].regs->next_desc_ptr = addr;
        SSYNC();
-       pr_debug("set_dma_start_addr() : END\n");
+       pr_debug("set_dma_next_desc_addr() : END\n");
 }
 EXPORT_SYMBOL(set_dma_next_desc_addr);
 
+void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr)
+{
+       pr_debug("set_dma_curr_desc_addr() : BEGIN \n");
+
+       BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+              && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+       dma_ch[channel].regs->curr_desc_ptr = addr;
+       SSYNC();
+       pr_debug("set_dma_curr_desc_addr() : END\n");
+}
+EXPORT_SYMBOL(set_dma_curr_desc_addr);
+
 void set_dma_x_count(unsigned int channel, unsigned short x_count)
 {
        BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
@@ -345,6 +363,16 @@ void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg)
 }
 EXPORT_SYMBOL(set_dma_sg);
 
+void set_dma_curr_addr(unsigned int channel, unsigned long addr)
+{
+       BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+              && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+       dma_ch[channel].regs->curr_addr_ptr = addr;
+       SSYNC();
+}
+EXPORT_SYMBOL(set_dma_curr_addr);
+
 /*------------------------------------------------------------------------------
  *     Get the DMA status of a specific DMA channel from the system.
  *-----------------------------------------------------------------------------*/
@@ -408,6 +436,10 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
                blackfin_dcache_flush_range((unsigned int)src,
                                            (unsigned int)(src + size));
 
+       if ((unsigned long)dest < memory_end)
+               blackfin_dcache_invalidate_range((unsigned int)dest,
+                                                (unsigned int)(dest + size));
+
        bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
 
        if ((unsigned long)src < (unsigned long)dest)
@@ -515,6 +547,8 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
                }
        }
 
+       SSYNC();
+
        while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE))
                ;
 
@@ -524,9 +558,6 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
        bfin_write_MDMA_S0_CONFIG(0);
        bfin_write_MDMA_D0_CONFIG(0);
 
-       if ((unsigned long)dest < memory_end)
-               blackfin_dcache_invalidate_range((unsigned int)dest,
-                                                (unsigned int)(dest + size));
        local_irq_restore(flags);
 
        return dest;
@@ -555,13 +586,14 @@ void *safe_dma_memcpy(void *dest, const void *src, size_t size)
 }
 EXPORT_SYMBOL(safe_dma_memcpy);
 
-void dma_outsb(void __iomem *addr, const void *buf, unsigned short len)
+void dma_outsb(unsigned long addr, const void *buf, unsigned short len)
 {
        unsigned long flags;
 
        local_irq_save(flags);
 
-       blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+       blackfin_dcache_flush_range((unsigned int)buf,
+                        (unsigned int)(buf) + len);
 
        bfin_write_MDMA_D0_START_ADDR(addr);
        bfin_write_MDMA_D0_X_COUNT(len);
@@ -576,6 +608,8 @@ void dma_outsb(void __iomem *addr, const void *buf, unsigned short len)
        bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8);
        bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8);
 
+       SSYNC();
+
        while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
 
        bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -588,10 +622,13 @@ void dma_outsb(void __iomem *addr, const void *buf, unsigned short len)
 EXPORT_SYMBOL(dma_outsb);
 
 
-void dma_insb(const void __iomem *addr, void *buf, unsigned short len)
+void dma_insb(unsigned long addr, void *buf, unsigned short len)
 {
        unsigned long flags;
 
+       blackfin_dcache_invalidate_range((unsigned int)buf,
+                        (unsigned int)(buf) + len);
+
        local_irq_save(flags);
        bfin_write_MDMA_D0_START_ADDR(buf);
        bfin_write_MDMA_D0_X_COUNT(len);
@@ -606,7 +643,7 @@ void dma_insb(const void __iomem *addr, void *buf, unsigned short len)
        bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8);
        bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8);
 
-       blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len);
+       SSYNC();
 
        while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
 
@@ -619,13 +656,14 @@ void dma_insb(const void __iomem *addr, void *buf, unsigned short len)
 }
 EXPORT_SYMBOL(dma_insb);
 
-void dma_outsw(void __iomem *addr, const void  *buf, unsigned short len)
+void dma_outsw(unsigned long addr, const void  *buf, unsigned short len)
 {
        unsigned long flags;
 
        local_irq_save(flags);
 
-       blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+       blackfin_dcache_flush_range((unsigned int)buf,
+                        (unsigned int)(buf) + len * sizeof(short));
 
        bfin_write_MDMA_D0_START_ADDR(addr);
        bfin_write_MDMA_D0_X_COUNT(len);
@@ -640,6 +678,8 @@ void dma_outsw(void __iomem *addr, const void  *buf, unsigned short len)
        bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16);
        bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16);
 
+       SSYNC();
+
        while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
 
        bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -651,10 +691,13 @@ void dma_outsw(void __iomem *addr, const void  *buf, unsigned short len)
 }
 EXPORT_SYMBOL(dma_outsw);
 
-void dma_insw(const void __iomem *addr, void *buf, unsigned short len)
+void dma_insw(unsigned long addr, void *buf, unsigned short len)
 {
        unsigned long flags;
 
+       blackfin_dcache_invalidate_range((unsigned int)buf,
+                        (unsigned int)(buf) + len * sizeof(short));
+
        local_irq_save(flags);
 
        bfin_write_MDMA_D0_START_ADDR(buf);
@@ -670,7 +713,7 @@ void dma_insw(const void __iomem *addr, void *buf, unsigned short len)
        bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16);
        bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16);
 
-       blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len);
+       SSYNC();
 
        while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
 
@@ -683,13 +726,14 @@ void dma_insw(const void __iomem *addr, void *buf, unsigned short len)
 }
 EXPORT_SYMBOL(dma_insw);
 
-void dma_outsl(void __iomem *addr, const void *buf, unsigned short len)
+void dma_outsl(unsigned long addr, const void *buf, unsigned short len)
 {
        unsigned long flags;
 
        local_irq_save(flags);
 
-       blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
+       blackfin_dcache_flush_range((unsigned int)buf,
+                        (unsigned int)(buf) + len * sizeof(long));
 
        bfin_write_MDMA_D0_START_ADDR(addr);
        bfin_write_MDMA_D0_X_COUNT(len);
@@ -704,6 +748,8 @@ void dma_outsl(void __iomem *addr, const void *buf, unsigned short len)
        bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32);
        bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32);
 
+       SSYNC();
+
        while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
 
        bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -715,10 +761,13 @@ void dma_outsl(void __iomem *addr, const void *buf, unsigned short len)
 }
 EXPORT_SYMBOL(dma_outsl);
 
-void dma_insl(const void __iomem *addr, void *buf, unsigned short len)
+void dma_insl(unsigned long addr, void *buf, unsigned short len)
 {
        unsigned long flags;
 
+       blackfin_dcache_invalidate_range((unsigned int)buf,
+                        (unsigned int)(buf) + len * sizeof(long));
+
        local_irq_save(flags);
 
        bfin_write_MDMA_D0_START_ADDR(buf);
@@ -734,7 +783,7 @@ void dma_insl(const void __iomem *addr, void *buf, unsigned short len)
        bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32);
        bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32);
 
-       blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len);
+       SSYNC();
 
        while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
 
index 5d488ef965ce771a95e6db2567752f10c806f052..3fe0cd49e8db51736620acd924f1457c88b02e42 100644 (file)
@@ -7,7 +7,7 @@
  * Description:  GPIO Abstraction Layer
  *
  * Modified:
- *               Copyright 2006 Analog Devices Inc.
+ *               Copyright 2007 Analog Devices Inc.
  *
  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
  *
@@ -28,9 +28,9 @@
  */
 
 /*
-*  Number     BF537/6/4    BF561    BF533/2/1
+*  Number     BF537/6/4    BF561    BF533/2/1     BF549/8/4/2
 *
-*  GPIO_0       PF0         PF0        PF0
+*  GPIO_0       PF0         PF0        PF0        PA0...PJ13
 *  GPIO_1       PF1         PF1        PF1
 *  GPIO_2       PF2         PF2        PF2
 *  GPIO_3       PF3         PF3        PF3
@@ -80,6 +80,7 @@
 *  GPIO_47      PH15        PF47
 */
 
+#include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/err.h>
 #include <asm/blackfin.h>
 #include <asm/portmux.h>
 #include <linux/irq.h>
 
+#if ANOMALY_05000311 || ANOMALY_05000323
+enum {
+       AWA_data = SYSCR,
+       AWA_data_clear = SYSCR,
+       AWA_data_set = SYSCR,
+       AWA_toggle = SYSCR,
+       AWA_maska = UART_SCR,
+       AWA_maska_clear = UART_SCR,
+       AWA_maska_set = UART_SCR,
+       AWA_maska_toggle = UART_SCR,
+       AWA_maskb = UART_GCTL,
+       AWA_maskb_clear = UART_GCTL,
+       AWA_maskb_set = UART_GCTL,
+       AWA_maskb_toggle = UART_GCTL,
+       AWA_dir = SPORT1_STAT,
+       AWA_polar = SPORT1_STAT,
+       AWA_edge = SPORT1_STAT,
+       AWA_both = SPORT1_STAT,
+#if ANOMALY_05000311
+       AWA_inen = TIMER_ENABLE,
+#elif ANOMALY_05000323
+       AWA_inen = DMA1_1_CONFIG,
+#endif
+};
+       /* Anomaly Workaround */
+#define AWA_DUMMY_READ(name) bfin_read16(AWA_ ## name)
+#else
+#define AWA_DUMMY_READ(...)  do { } while (0)
+#endif
+
 #ifdef BF533_FAMILY
 static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
        (struct gpio_port_t *) FIO_FLAG_D,
@@ -116,11 +147,31 @@ static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
 };
 #endif
 
+#ifdef BF548_FAMILY
+static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+       (struct gpio_port_t *)PORTA_FER,
+       (struct gpio_port_t *)PORTB_FER,
+       (struct gpio_port_t *)PORTC_FER,
+       (struct gpio_port_t *)PORTD_FER,
+       (struct gpio_port_t *)PORTE_FER,
+       (struct gpio_port_t *)PORTF_FER,
+       (struct gpio_port_t *)PORTG_FER,
+       (struct gpio_port_t *)PORTH_FER,
+       (struct gpio_port_t *)PORTI_FER,
+       (struct gpio_port_t *)PORTJ_FER,
+};
+#endif
+
 static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
 static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS + 16)];
-char *str_ident = NULL;
 
-#define RESOURCE_LABEL_SIZE 16
+#define MAX_RESOURCES          256
+#define RESOURCE_LABEL_SIZE    16
+
+struct str_ident {
+       char name[RESOURCE_LABEL_SIZE];
+} *str_ident;
+
 
 #ifdef CONFIG_PM
 static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
@@ -141,21 +192,32 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INT
 
 #endif /* CONFIG_PM */
 
+#if defined(BF548_FAMILY)
+inline int check_gpio(unsigned short gpio)
+{
+       if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
+           || gpio == GPIO_PH14 || gpio == GPIO_PH15
+           || gpio == GPIO_PJ14 || gpio == GPIO_PJ15
+           || gpio > MAX_BLACKFIN_GPIOS)
+               return -EINVAL;
+       return 0;
+}
+#else
 inline int check_gpio(unsigned short gpio)
 {
        if (gpio >= MAX_BLACKFIN_GPIOS)
                return -EINVAL;
        return 0;
 }
+#endif
 
 static void set_label(unsigned short ident, const char *label)
 {
 
        if (label && str_ident) {
-               strncpy(str_ident + ident * RESOURCE_LABEL_SIZE, label,
+               strncpy(str_ident[ident].name, label,
                         RESOURCE_LABEL_SIZE);
-               str_ident[ident * RESOURCE_LABEL_SIZE +
-                        RESOURCE_LABEL_SIZE - 1] = 0;
+               str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0;
        }
 }
 
@@ -164,14 +226,13 @@ static char *get_label(unsigned short ident)
        if (!str_ident)
                return "UNKNOWN";
 
-       return (str_ident[ident * RESOURCE_LABEL_SIZE] ?
-               (str_ident + ident * RESOURCE_LABEL_SIZE) : "UNKNOWN");
+       return (*str_ident[ident].name ? str_ident[ident].name : "UNKNOWN");
 }
 
 static int cmp_label(unsigned short ident, const char *label)
 {
        if (label && str_ident)
-               return strncmp(str_ident + ident * RESOURCE_LABEL_SIZE,
+               return strncmp(str_ident[ident].name,
                                 label, strlen(label));
        else
                return -EINVAL;
@@ -181,50 +242,84 @@ static int cmp_label(unsigned short ident, const char *label)
 static void port_setup(unsigned short gpio, unsigned short usage)
 {
        if (!check_gpio(gpio)) {
-               if (usage == GPIO_USAGE) {
+               if (usage == GPIO_USAGE)
                        *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
-               else
+               else
                        *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
                SSYNC();
        }
 }
+#elif defined(BF548_FAMILY)
+static void port_setup(unsigned short gpio, unsigned short usage)
+{
+       if (usage == GPIO_USAGE)
+               gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
+       else
+               gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
+       SSYNC();
+}
 #else
 # define port_setup(...)  do { } while (0)
 #endif
 
 #ifdef BF537_FAMILY
-
-#define PMUX_LUT_RES           0
-#define PMUX_LUT_OFFSET                1
-#define PMUX_LUT_ENTRIES       41
-#define PMUX_LUT_SIZE          2
-
-static unsigned short port_mux_lut[PMUX_LUT_ENTRIES][PMUX_LUT_SIZE] = {
-       {P_PPI0_D13, 11}, {P_PPI0_D14, 11}, {P_PPI0_D15, 11},
-       {P_SPORT1_TFS, 11}, {P_SPORT1_TSCLK, 11}, {P_SPORT1_DTPRI, 11},
-       {P_PPI0_D10, 10}, {P_PPI0_D11, 10}, {P_PPI0_D12, 10},
-       {P_SPORT1_RSCLK, 10}, {P_SPORT1_RFS, 10}, {P_SPORT1_DRPRI, 10},
-       {P_PPI0_D8, 9}, {P_PPI0_D9, 9}, {P_SPORT1_DRSEC, 9},
-       {P_SPORT1_DTSEC, 9}, {P_TMR2, 8}, {P_PPI0_FS3, 8}, {P_TMR3, 7},
-       {P_SPI0_SSEL4, 7}, {P_TMR4, 6}, {P_SPI0_SSEL5, 6}, {P_TMR5, 5},
-       {P_SPI0_SSEL6, 5}, {P_UART1_RX, 4}, {P_UART1_TX, 4}, {P_TMR6, 4},
-       {P_TMR7, 4}, {P_UART0_RX, 3}, {P_UART0_TX, 3}, {P_DMAR0, 3},
-       {P_DMAR1, 3}, {P_SPORT0_DTSEC, 1}, {P_SPORT0_DRSEC, 1},
-       {P_CAN0_RX, 1}, {P_CAN0_TX, 1}, {P_SPI0_SSEL7, 1},
-       {P_SPORT0_TFS, 0}, {P_SPORT0_DTPRI, 0}, {P_SPI0_SSEL2, 0},
-       {P_SPI0_SSEL3, 0}
+static struct {
+       unsigned short res;
+       unsigned short offset;
+} port_mux_lut[] = {
+       {.res = P_PPI0_D13, .offset = 11},
+       {.res = P_PPI0_D14, .offset = 11},
+       {.res = P_PPI0_D15, .offset = 11},
+       {.res = P_SPORT1_TFS, .offset = 11},
+       {.res = P_SPORT1_TSCLK, .offset = 11},
+       {.res = P_SPORT1_DTPRI, .offset = 11},
+       {.res = P_PPI0_D10, .offset = 10},
+       {.res = P_PPI0_D11, .offset = 10},
+       {.res = P_PPI0_D12, .offset = 10},
+       {.res = P_SPORT1_RSCLK, .offset = 10},
+       {.res = P_SPORT1_RFS, .offset = 10},
+       {.res = P_SPORT1_DRPRI, .offset = 10},
+       {.res = P_PPI0_D8, .offset = 9},
+       {.res = P_PPI0_D9, .offset = 9},
+       {.res = P_SPORT1_DRSEC, .offset = 9},
+       {.res = P_SPORT1_DTSEC, .offset = 9},
+       {.res = P_TMR2, .offset = 8},
+       {.res = P_PPI0_FS3, .offset = 8},
+       {.res = P_TMR3, .offset = 7},
+       {.res = P_SPI0_SSEL4, .offset = 7},
+       {.res = P_TMR4, .offset = 6},
+       {.res = P_SPI0_SSEL5, .offset = 6},
+       {.res = P_TMR5, .offset = 5},
+       {.res = P_SPI0_SSEL6, .offset = 5},
+       {.res = P_UART1_RX, .offset = 4},
+       {.res = P_UART1_TX, .offset = 4},
+       {.res = P_TMR6, .offset = 4},
+       {.res = P_TMR7, .offset = 4},
+       {.res = P_UART0_RX, .offset = 3},
+       {.res = P_UART0_TX, .offset = 3},
+       {.res = P_DMAR0, .offset = 3},
+       {.res = P_DMAR1, .offset = 3},
+       {.res = P_SPORT0_DTSEC, .offset = 1},
+       {.res = P_SPORT0_DRSEC, .offset = 1},
+       {.res = P_CAN0_RX, .offset = 1},
+       {.res = P_CAN0_TX, .offset = 1},
+       {.res = P_SPI0_SSEL7, .offset = 1},
+       {.res = P_SPORT0_TFS, .offset = 0},
+       {.res = P_SPORT0_DTPRI, .offset = 0},
+       {.res = P_SPI0_SSEL2, .offset = 0},
+       {.res = P_SPI0_SSEL3, .offset = 0},
 };
 
 static void portmux_setup(unsigned short per, unsigned short function)
 {
-       u16 y, muxreg, offset;
+       u16 y, offset, muxreg;
 
-       for (y = 0; y < PMUX_LUT_ENTRIES; y++) {
-               if (port_mux_lut[y][PMUX_LUT_RES] == per) {
+       for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) {
+               if (port_mux_lut[y].res == per) {
 
                        /* SET PORTMUX REG */
 
-                       offset = port_mux_lut[y][PMUX_LUT_OFFSET];
+                       offset = port_mux_lut[y].offset;
                        muxreg = bfin_read_PORT_MUX();
 
                        if (offset != 1) {
@@ -238,18 +333,42 @@ static void portmux_setup(unsigned short per, unsigned short function)
                }
        }
 }
+#elif defined(BF548_FAMILY)
+inline void portmux_setup(unsigned short portno, unsigned short function)
+{
+       u32 pmux;
+
+       pmux = gpio_array[gpio_bank(portno)]->port_mux;
+
+       pmux &= ~(0x3 << (2 * gpio_sub_n(portno)));
+       pmux |= (function & 0x3) << (2 * gpio_sub_n(portno));
 
+       gpio_array[gpio_bank(portno)]->port_mux = pmux;
+}
+
+inline u16 get_portmux(unsigned short portno)
+{
+       u32 pmux;
+
+       pmux = gpio_array[gpio_bank(portno)]->port_mux;
+
+       return (pmux >> (2 * gpio_sub_n(portno)) & 0x3);
+}
 #else
 # define portmux_setup(...)  do { } while (0)
 #endif
 
+#ifndef BF548_FAMILY
 static void default_gpio(unsigned short gpio)
 {
        unsigned short bank, bitmask;
+       unsigned long flags;
 
        bank = gpio_bank(gpio);
        bitmask = gpio_bit(gpio);
 
+       local_irq_save(flags);
+
        gpio_bankb[bank]->maska_clear = bitmask;
        gpio_bankb[bank]->maskb_clear = bitmask;
        SSYNC();
@@ -258,24 +377,32 @@ static void default_gpio(unsigned short gpio)
        gpio_bankb[bank]->polar &= ~bitmask;
        gpio_bankb[bank]->both &= ~bitmask;
        gpio_bankb[bank]->edge &= ~bitmask;
+       AWA_DUMMY_READ(edge);
+       local_irq_restore(flags);
+
 }
+#else
+# define default_gpio(...)  do { } while (0)
+#endif
 
 static int __init bfin_gpio_init(void)
 {
-
-       str_ident = kzalloc(RESOURCE_LABEL_SIZE * 256, GFP_KERNEL);
-       if (!str_ident)
+       str_ident = kcalloc(MAX_RESOURCES,
+                                sizeof(struct str_ident), GFP_KERNEL);
+       if (str_ident == NULL)
                return -ENOMEM;
 
+       memset(str_ident, 0, MAX_RESOURCES * sizeof(struct str_ident));
+
        printk(KERN_INFO "Blackfin GPIO Controller\n");
 
        return 0;
 
 }
-
 arch_initcall(bfin_gpio_init);
 
 
+#ifndef BF548_FAMILY
 /***********************************************************
 *
 * FUNCTIONS: Blackfin General Purpose Ports Access Functions
@@ -305,6 +432,7 @@ void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
                gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
        else \
                gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
+       AWA_DUMMY_READ(name); \
        local_irq_restore(flags); \
 } \
 EXPORT_SYMBOL(set_gpio_ ## name);
@@ -316,6 +444,22 @@ SET_GPIO(edge)
 SET_GPIO(both)
 
 
+#if ANOMALY_05000311 || ANOMALY_05000323
+#define SET_GPIO_SC(name) \
+void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
+{ \
+       unsigned long flags; \
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
+       local_irq_save(flags); \
+       if (arg) \
+               gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
+       else \
+               gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
+       AWA_DUMMY_READ(name); \
+       local_irq_restore(flags); \
+} \
+EXPORT_SYMBOL(set_gpio_ ## name);
+#else
 #define SET_GPIO_SC(name) \
 void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
 { \
@@ -326,37 +470,20 @@ void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
                gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
 } \
 EXPORT_SYMBOL(set_gpio_ ## name);
+#endif
 
 SET_GPIO_SC(maska)
 SET_GPIO_SC(maskb)
-
-#if defined(ANOMALY_05000311)
-void set_gpio_data(unsigned short gpio, unsigned short arg)
-{
-       unsigned long flags;
-       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
-       local_irq_save(flags);
-       if (arg)
-               gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
-       else
-               gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
-       bfin_read_CHIPID();
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL(set_gpio_data);
-#else
 SET_GPIO_SC(data)
-#endif
-
 
-#if defined(ANOMALY_05000311)
+#if ANOMALY_05000311 || ANOMALY_05000323
 void set_gpio_toggle(unsigned short gpio)
 {
        unsigned long flags;
        BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
        local_irq_save(flags);
        gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
-       bfin_read_CHIPID();
+       AWA_DUMMY_READ(toggle);
        local_irq_restore(flags);
 }
 #else
@@ -371,13 +498,27 @@ EXPORT_SYMBOL(set_gpio_toggle);
 
 /*Set current PORT date (16-bit word)*/
 
+#if ANOMALY_05000311 || ANOMALY_05000323
 #define SET_GPIO_P(name) \
 void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \
 { \
+       unsigned long flags; \
+       local_irq_save(flags); \
        gpio_bankb[gpio_bank(gpio)]->name = arg; \
+       AWA_DUMMY_READ(name); \
+       local_irq_restore(flags); \
 } \
 EXPORT_SYMBOL(set_gpiop_ ## name);
+#else
+#define SET_GPIO_P(name) \
+void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \
+{ \
+       gpio_bankb[gpio_bank(gpio)]->name = arg; \
+} \
+EXPORT_SYMBOL(set_gpiop_ ## name);
+#endif
 
+SET_GPIO_P(data)
 SET_GPIO_P(dir)
 SET_GPIO_P(inen)
 SET_GPIO_P(polar)
@@ -387,31 +528,30 @@ SET_GPIO_P(maska)
 SET_GPIO_P(maskb)
 
 
-#if defined(ANOMALY_05000311)
-void set_gpiop_data(unsigned short gpio, unsigned short arg)
-{
-       unsigned long flags;
-       local_irq_save(flags);
-       gpio_bankb[gpio_bank(gpio)]->data = arg;
-       bfin_read_CHIPID();
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL(set_gpiop_data);
-#else
-SET_GPIO_P(data)
-#endif
-
-
-
 /* Get a specific bit */
-
+#if ANOMALY_05000311 || ANOMALY_05000323
+#define GET_GPIO(name) \
+unsigned short get_gpio_ ## name(unsigned short gpio) \
+{ \
+       unsigned long flags; \
+       unsigned short ret; \
+       local_irq_save(flags); \
+       ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \
+       AWA_DUMMY_READ(name); \
+       local_irq_restore(flags); \
+       return ret; \
+} \
+EXPORT_SYMBOL(get_gpio_ ## name);
+#else
 #define GET_GPIO(name) \
 unsigned short get_gpio_ ## name(unsigned short gpio) \
 { \
        return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \
 } \
 EXPORT_SYMBOL(get_gpio_ ## name);
+#endif
 
+GET_GPIO(data)
 GET_GPIO(dir)
 GET_GPIO(inen)
 GET_GPIO(polar)
@@ -420,33 +560,31 @@ GET_GPIO(both)
 GET_GPIO(maska)
 GET_GPIO(maskb)
 
-
-#if defined(ANOMALY_05000311)
-unsigned short get_gpio_data(unsigned short gpio)
-{
-       unsigned long flags;
-       unsigned short ret;
-       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
-       local_irq_save(flags);
-       ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >> gpio_sub_n(gpio));
-       bfin_read_CHIPID();
-       local_irq_restore(flags);
-       return ret;
-}
-EXPORT_SYMBOL(get_gpio_data);
-#else
-GET_GPIO(data)
-#endif
-
 /*Get current PORT date (16-bit word)*/
 
+#if ANOMALY_05000311 || ANOMALY_05000323
+#define GET_GPIO_P(name) \
+unsigned short get_gpiop_ ## name(unsigned short gpio) \
+{ \
+       unsigned long flags; \
+       unsigned short ret; \
+       local_irq_save(flags); \
+       ret = (gpio_bankb[gpio_bank(gpio)]->name); \
+       AWA_DUMMY_READ(name); \
+       local_irq_restore(flags); \
+       return ret; \
+} \
+EXPORT_SYMBOL(get_gpiop_ ## name);
+#else
 #define GET_GPIO_P(name) \
 unsigned short get_gpiop_ ## name(unsigned short gpio) \
 { \
        return (gpio_bankb[gpio_bank(gpio)]->name);\
 } \
 EXPORT_SYMBOL(get_gpiop_ ## name);
+#endif
 
+GET_GPIO_P(data)
 GET_GPIO_P(dir)
 GET_GPIO_P(inen)
 GET_GPIO_P(polar)
@@ -455,21 +593,6 @@ GET_GPIO_P(both)
 GET_GPIO_P(maska)
 GET_GPIO_P(maskb)
 
-#if defined(ANOMALY_05000311)
-unsigned short get_gpiop_data(unsigned short gpio)
-{
-       unsigned long flags;
-       unsigned short ret;
-       local_irq_save(flags);
-       ret = gpio_bankb[gpio_bank(gpio)]->data;
-       bfin_read_CHIPID();
-       local_irq_restore(flags);
-       return ret;
-}
-EXPORT_SYMBOL(get_gpiop_data);
-#else
-GET_GPIO_P(data)
-#endif
 
 #ifdef CONFIG_PM
 /***********************************************************
@@ -593,6 +716,8 @@ u32 gpio_pm_setup(void)
                }
        }
 
+       AWA_DUMMY_READ(maskb_set);
+
        if (sic_iwr)
                return sic_iwr;
        else
@@ -624,12 +749,99 @@ void gpio_pm_restore(void)
 
                gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb;
        }
+       AWA_DUMMY_READ(maskb);
 }
 
 #endif
+#endif /* BF548_FAMILY */
 
+/***********************************************************
+*
+* FUNCTIONS:   Blackfin Peripheral Resource Allocation
+*              and PortMux Setup
+*
+* INPUTS/OUTPUTS:
+* per  Peripheral Identifier
+* label        String
+*
+* DESCRIPTION: Blackfin Peripheral Resource Allocation and Setup API
+*
+* CAUTION:
+*************************************************************
+* MODIFICATION HISTORY :
+**************************************************************/
+
+#ifdef BF548_FAMILY
+int peripheral_request(unsigned short per, const char *label)
+{
+       unsigned long flags;
+       unsigned short ident = P_IDENT(per);
+
+       /*
+        * Don't cares are pins with only one dedicated function
+        */
+
+       if (per & P_DONTCARE)
+               return 0;
+
+       if (!(per & P_DEFINED))
+               return -ENODEV;
+
+       if (check_gpio(ident) < 0)
+               return -EINVAL;
+
+       local_irq_save(flags);
+
+       if (unlikely(reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
+               printk(KERN_ERR
+                   "%s: Peripheral %d is already reserved as GPIO by %s !\n",
+                      __FUNCTION__, ident, get_label(ident));
+               dump_stack();
+               local_irq_restore(flags);
+               return -EBUSY;
+       }
+
+       if (unlikely(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident))) {
+
+               u16 funct = get_portmux(ident);
+
+       /*
+        * Pin functions like AMC address strobes my
+        * be requested and used by several drivers
+        */
+
+               if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) {
+
+               /*
+                * Allow that the identical pin function can
+                * be requested from the same driver twice
+                */
+
+               if (cmp_label(ident, label) == 0)
+                       goto anyway;
 
+                       printk(KERN_ERR
+                              "%s: Peripheral %d function %d is already reserved by %s !\n",
+                              __FUNCTION__, ident, P_FUNCT2MUX(per), get_label(ident));
+                       dump_stack();
+                       local_irq_restore(flags);
+                       return -EBUSY;
+               }
+       }
 
+anyway:
+       reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident);
+
+       portmux_setup(ident, P_FUNCT2MUX(per));
+       port_setup(ident, PERIPHERAL_USAGE);
+
+       local_irq_restore(flags);
+       set_label(ident, label);
+
+       return 0;
+}
+EXPORT_SYMBOL(peripheral_request);
+#else
 
 int peripheral_request(unsigned short per, const char *label)
 {
@@ -680,7 +892,7 @@ int peripheral_request(unsigned short per, const char *label)
 
                        printk(KERN_ERR
                               "%s: Peripheral %d function %d is already"
-                              "reserved by %s !\n",
+                              " reserved by %s !\n",
                               __FUNCTION__, ident, P_FUNCT2MUX(per),
                                get_label(ident));
                        dump_stack();
@@ -691,8 +903,6 @@ int peripheral_request(unsigned short per, const char *label)
        }
 
 anyway:
-
-
        portmux_setup(per, P_FUNCT2MUX(per));
 
        port_setup(ident, PERIPHERAL_USAGE);
@@ -704,6 +914,7 @@ anyway:
        return 0;
 }
 EXPORT_SYMBOL(peripheral_request);
+#endif
 
 int peripheral_request_list(unsigned short per[], const char *label)
 {
@@ -711,9 +922,15 @@ int peripheral_request_list(unsigned short per[], const char *label)
        int ret;
 
        for (cnt = 0; per[cnt] != 0; cnt++) {
+
                ret = peripheral_request(per[cnt], label);
-               if (ret < 0)
-                       return ret;
+
+               if (ret < 0) {
+                       for ( ; cnt > 0; cnt--) {
+                               peripheral_free(per[cnt - 1]);
+                       }
+               return ret;
+               }
        }
 
        return 0;
@@ -748,6 +965,8 @@ void peripheral_free(unsigned short per)
 
        reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident);
 
+       set_label(ident, "free");
+
        local_irq_restore(flags);
 }
 EXPORT_SYMBOL(peripheral_free);
@@ -768,8 +987,8 @@ EXPORT_SYMBOL(peripheral_free_list);
 * FUNCTIONS: Blackfin GPIO Driver
 *
 * INPUTS/OUTPUTS:
-* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
-*
+* gpio PIO Number between 0 and MAX_BLACKFIN_GPIOS
+* label        String
 *
 * DESCRIPTION: Blackfin GPIO Driver API
 *
@@ -787,17 +1006,39 @@ int gpio_request(unsigned short gpio, const char *label)
 
        local_irq_save(flags);
 
+       /*
+        * Allow that the identical GPIO can
+        * be requested from the same driver twice
+        * Do nothing and return -
+        */
+
+       if (cmp_label(gpio, label) == 0) {
+               local_irq_restore(flags);
+               return 0;
+       }
+
        if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-               printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio);
+               printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
+                        gpio, get_label(gpio));
                dump_stack();
                local_irq_restore(flags);
                return -EBUSY;
        }
+       if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
+               printk(KERN_ERR
+                      "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
+                      gpio, get_label(gpio));
+               dump_stack();
+               local_irq_restore(flags);
+               return -EBUSY;
+       }
+
        reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
 
        local_irq_restore(flags);
 
        port_setup(gpio, GPIO_USAGE);
+       set_label(gpio, label);
 
        return 0;
 }
@@ -823,10 +1064,57 @@ void gpio_free(unsigned short gpio)
 
        reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
 
+       set_label(gpio, "free");
+
        local_irq_restore(flags);
 }
 EXPORT_SYMBOL(gpio_free);
 
+#ifdef BF548_FAMILY
+void gpio_direction_input(unsigned short gpio)
+{
+       unsigned long flags;
+
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+
+       local_irq_save(flags);
+       gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
+       gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+void gpio_direction_output(unsigned short gpio)
+{
+       unsigned long flags;
+
+       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
+
+       local_irq_save(flags);
+       gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
+       gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+void gpio_set_value(unsigned short gpio, unsigned short arg)
+{
+       if (arg)
+               gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
+       else
+               gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio);
+
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+unsigned short gpio_get_value(unsigned short gpio)
+{
+       return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio)));
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+#else
+
 void gpio_direction_input(unsigned short gpio)
 {
        unsigned long flags;
@@ -836,6 +1124,7 @@ void gpio_direction_input(unsigned short gpio)
        local_irq_save(flags);
        gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
        gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
+       AWA_DUMMY_READ(inen);
        local_irq_restore(flags);
 }
 EXPORT_SYMBOL(gpio_direction_input);
@@ -849,6 +1138,28 @@ void gpio_direction_output(unsigned short gpio)
        local_irq_save(flags);
        gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
        gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
+       AWA_DUMMY_READ(dir);
        local_irq_restore(flags);
 }
 EXPORT_SYMBOL(gpio_direction_output);
+
+/* If we are booting from SPI and our board lacks a strong enough pull up,
+ * the core can reset and execute the bootrom faster than the resistor can
+ * pull the signal logically high.  To work around this (common) error in
+ * board design, we explicitly set the pin back to GPIO mode, force /CS
+ * high, and wait for the electrons to do their thing.
+ *
+ * This function only makes sense to be called from reset code, but it
+ * lives here as we need to force all the GPIO states w/out going through
+ * BUG() checks and such.
+ */
+void bfin_gpio_reset_spi0_ssel1(void)
+{
+       u16 gpio = P_IDENT(P_SPI0_SSEL1);
+
+       port_setup(gpio, GPIO_USAGE);
+       gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
+       udelay(1);
+}
+
+#endif /*BF548_FAMILY */
index 70455949cfd207f91475d100d6f8787574b37ab2..2198afe40f338efae030e7516055cf2596936c6d 100644 (file)
@@ -60,6 +60,7 @@ EXPORT_SYMBOL(csum_partial_copy);
  * their interface isn't gonna change any time soon now, so
  * it's OK to leave it out of version control.
  */
+EXPORT_SYMBOL(strcpy);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memcmp);
index 4d41a40e8133ef1fb6d7e39e07175f04c2793c7d..62cbba7364b0d066b5559e4f1a7add76567722ef 100644 (file)
 
 #include <asm/cacheflush.h>
 #include <asm/blackfin.h>
+#include <asm/cplb.h>
 #include <asm/cplbinit.h>
 
-#if defined(CONFIG_BLKFIN_CACHE)
+#if defined(CONFIG_BFIN_ICACHE)
 void bfin_icache_init(void)
 {
        unsigned long *table = icplb_table;
@@ -44,7 +45,7 @@ void bfin_icache_init(void)
 }
 #endif
 
-#if defined(CONFIG_BLKFIN_DCACHE)
+#if defined(CONFIG_BFIN_DCACHE)
 void bfin_dcache_init(void)
 {
        unsigned long *table = dcplb_table;
index bbdb403fcb55670b71ecbc65a12f0322a7a80852..f2db6a5e2b5b987852828d4a95cadf88923d005c 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/module.h>
 
 #include <asm/blackfin.h>
+#include <asm/cplb.h>
 #include <asm/cplbinit.h>
 
 u_long icplb_table[MAX_CPLBS+1];
@@ -56,7 +57,7 @@ struct s_cplb {
        struct cplb_tab switch_d;
 };
 
-#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
+#if defined(CONFIG_BFIN_DCACHE) || defined(CONFIG_BFIN_ICACHE)
 static struct cplb_desc cplb_data[] = {
        {
                .start = 0,
@@ -230,8 +231,8 @@ static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_en
                                cplb_data[i].psize,
                                cplb_data[i].i_conf);
        } else {
-#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
-               if (i == SDRAM_KERN) {
+#if defined(CONFIG_BFIN_ICACHE)
+               if (ANOMALY_05000263 && i == SDRAM_KERN) {
                        fill_cplbtab(t,
                                        cplb_data[i].start,
                                        cplb_data[i].end,
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c
new file mode 100644 (file)
index 0000000..6ec518a
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * File:         arch/blackfin/kernel/early_printk.c
+ * Based on:     arch/x86_64/kernel/early_printk.c
+ * Author:       Robin Getz <rgetz@blackfin.uclinux.org
+ *
+ * Created:      14Aug2007
+ * Description:  allow a console to be used for early printk
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <asm/blackfin.h>
+#include <asm/irq_handler.h>
+#include <asm/early_printk.h>
+
+#ifdef CONFIG_SERIAL_BFIN
+extern struct console *bfin_earlyserial_init(unsigned int port,
+                                               unsigned int cflag);
+#endif
+
+static struct console *early_console;
+
+/* Default console */
+#define DEFAULT_PORT 0
+#define DEFAULT_CFLAG CS8|B57600
+
+/* Default console for early crashes */
+#define DEFAULT_EARLY_PORT "serial,uart0,57600"
+
+#ifdef CONFIG_SERIAL_CORE
+/* What should get here is "0,57600" */
+static struct console * __init earlyserial_init(char *buf)
+{
+       int baud, bit;
+       char parity;
+       unsigned int serial_port = DEFAULT_PORT;
+       unsigned int cflag = DEFAULT_CFLAG;
+
+       serial_port = simple_strtoul(buf, &buf, 10);
+       buf++;
+
+       cflag = 0;
+       baud = simple_strtoul(buf, &buf, 10);
+       switch (baud) {
+       case 1200:
+               cflag |= B1200;
+               break;
+       case 2400:
+               cflag |= B2400;
+               break;
+       case 4800:
+               cflag |= B4800;
+               break;
+       case 9600:
+               cflag |= B9600;
+               break;
+       case 19200:
+               cflag |= B19200;
+               break;
+       case 38400:
+               cflag |= B38400;
+               break;
+       case 115200:
+               cflag |= B115200;
+               break;
+       default:
+               cflag |= B57600;
+       }
+
+       parity = buf[0];
+       buf++;
+       switch (parity) {
+       case 'e':
+               cflag |= PARENB;
+               break;
+       case 'o':
+               cflag |= PARODD;
+               break;
+       }
+
+       bit = simple_strtoul(buf, &buf, 10);
+       switch (bit) {
+       case 5:
+               cflag |= CS5;
+               break;
+       case 6:
+               cflag |= CS5;
+               break;
+       case 7:
+               cflag |= CS5;
+               break;
+       default:
+               cflag |= CS8;
+       }
+
+#ifdef CONFIG_SERIAL_BFIN
+       return bfin_earlyserial_init(serial_port, cflag);
+#else
+       return NULL;
+#endif
+
+}
+#endif
+
+int __init setup_early_printk(char *buf)
+{
+
+       /* Crashing in here would be really bad, so check both the var
+          and the pointer before we start using it
+        */
+       if (!buf)
+               return 0;
+
+       if (!*buf)
+               return 0;
+
+       if (early_console != NULL)
+               return 0;
+
+#ifdef CONFIG_SERIAL_BFIN
+       /* Check for Blackfin Serial */
+       if (!strncmp(buf, "serial,uart", 11)) {
+               buf += 11;
+               early_console = earlyserial_init(buf);
+       }
+#endif
+#ifdef CONFIG_FB
+               /* TODO: add framebuffer console support */
+#endif
+
+       if (likely(early_console)) {
+               early_console->flags |= CON_BOOT;
+
+               register_console(early_console);
+               printk(KERN_INFO "early printk enabled on %s%d\n",
+                       early_console->name,
+                       early_console->index);
+       }
+
+       return 0;
+}
+
+/*
+ * Set up a temporary Event Vector Table, so if something bad happens before
+ * the kernel is fully started, it doesn't vector off into somewhere we don't
+ * know
+ */
+
+asmlinkage void __init init_early_exception_vectors(void)
+{
+       SSYNC();
+
+       /* cannot program in software:
+        * evt0 - emulation (jtag)
+        * evt1 - reset
+        */
+       bfin_write_EVT2(early_trap);
+       bfin_write_EVT3(early_trap);
+       bfin_write_EVT5(early_trap);
+       bfin_write_EVT6(early_trap);
+       bfin_write_EVT7(early_trap);
+       bfin_write_EVT8(early_trap);
+       bfin_write_EVT9(early_trap);
+       bfin_write_EVT10(early_trap);
+       bfin_write_EVT11(early_trap);
+       bfin_write_EVT12(early_trap);
+       bfin_write_EVT13(early_trap);
+       bfin_write_EVT14(early_trap);
+       bfin_write_EVT15(early_trap);
+       CSYNC();
+
+       /* Set all the return from interupt, exception, NMI to a known place
+        * so if we do a RETI, RETX or RETN by mistake - we go somewhere known
+        * Note - don't change RETS - we are in a subroutine, or
+        * RETE - since it might screw up if emulator is attached
+        */
+       asm("\tRETI = %0; RETX = %0; RETN = %0;\n"
+               : : "p"(early_trap));
+
+}
+
+asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
+{
+       /* This can happen before the uart is initialized, so initialize
+        * the UART now
+        */
+       if (likely(early_console == NULL))
+               setup_early_printk(DEFAULT_EARLY_PORT);
+
+       dump_bfin_regs(fp, retaddr);
+       dump_bfin_trace_buffer();
+
+       panic("Died early");
+}
+
+early_param("earlyprintk", setup_early_printk);
index 1fc001c7abdac10b22be68d12b89c6be3638a69f..73647c158774e0acd31efcf3e7385dd2b104365a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/kallsyms.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <asm/trace.h>
 
 static unsigned long irq_err_count;
 static spinlock_t irq_controller_lock;
@@ -97,9 +98,8 @@ int show_interrupts(struct seq_file *p, void *v)
  */
 
 #ifdef CONFIG_DO_IRQ_L1
-asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)__attribute__((l1_text));
+__attribute__((l1_text))
 #endif
-
 asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs;
@@ -144,4 +144,12 @@ void __init init_IRQ(void)
        }
 
        init_arch_irq();
+
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
+       /* Now that evt_ivhw is set up, turn this on */
+       trace_buff_offset = 0;
+       bfin_write_TBUFCTL(BFIN_TRACE_ON);
+       printk(KERN_INFO "Hardware Trace expanded to %ik\n",
+         1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN);
+#endif
 }
index 6a7aefe4834639cd39b42b8d055187f4ad7e0d77..9124467651c4a794659b147f37e874b603524521 100644 (file)
@@ -134,31 +134,6 @@ void cpu_idle(void)
        }
 }
 
-void machine_restart(char *__unused)
-{
-#if defined(CONFIG_BLKFIN_CACHE)
-       bfin_write_IMEM_CONTROL(0x01);
-       SSYNC();
-#endif
-       bfin_reset();
-       /* Dont do anything till the reset occurs */
-       while (1) {
-               SSYNC();
-       }
-}
-
-void machine_halt(void)
-{
-       for (;;)
-               asm volatile ("idle");
-}
-
-void machine_power_off(void)
-{
-       for (;;)
-               asm volatile ("idle");
-}
-
 void show_regs(struct pt_regs *regs)
 {
        printk(KERN_NOTICE "\n");
@@ -420,7 +395,8 @@ void finish_atomic_sections (struct pt_regs *regs)
 #if defined(CONFIG_ACCESS_CHECK)
 int _access_ok(unsigned long addr, unsigned long size)
 {
-
+       if (size == 0)
+               return 1;
        if (addr > (addr + size))
                return 0;
        if (segment_eq(get_fs(), KERNEL_DS))
index ed800c7456dd004a9863e2643a8a4aac720d2c9b..64ce5fea8609afd848dbf301f2fccb10e53668a5 100644 (file)
@@ -44,6 +44,7 @@
 #include <asm/processor.h>
 #include <asm/asm-offsets.h>
 #include <asm/dma.h>
+#include <asm/fixed_code.h>
 
 #define MAX_SHARED_LIBS 3
 #define TEXT_OFFSET 0
@@ -169,6 +170,9 @@ static inline int is_user_addr_valid(struct task_struct *child,
                    && start + len <= (unsigned long)sraml->addr + sraml->length)
                        return 0;
 
+       if (start >= FIXED_CODE_START && start + len <= FIXED_CODE_END)
+               return 0;
+
        return -EIO;
 }
 
@@ -215,9 +219,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                                copied = sizeof(tmp);
                        } else
 #endif
-                       copied =
-                           access_process_vm(child, addr + add, &tmp,
-                                             sizeof(tmp), 0);
+                       if (addr + add >= FIXED_CODE_START
+                           && addr + add + sizeof(tmp) <= FIXED_CODE_END) {
+                               memcpy(&tmp, (const void *)(addr + add), sizeof(tmp));
+                               copied = sizeof(tmp);
+                       } else
+                               copied = access_process_vm(child, addr + add, &tmp,
+                                                          sizeof(tmp), 0);
                        pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp);
                        if (copied != sizeof(tmp))
                                break;
@@ -281,9 +289,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                                copied = sizeof(data);
                        } else
 #endif
-                       copied =
-                           access_process_vm(child, addr + add, &data,
-                                             sizeof(data), 1);
+                       if (addr + add >= FIXED_CODE_START
+                           && addr + add + sizeof(data) <= FIXED_CODE_END) {
+                               memcpy((void *)(addr + add), &data, sizeof(data));
+                               copied = sizeof(data);
+                       } else
+                               copied = access_process_vm(child, addr + add, &data,
+                                                          sizeof(data), 1);
                        pr_debug("ptrace: copied size %d\n", copied);
                        if (copied != sizeof(data))
                                break;
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c
new file mode 100644 (file)
index 0000000..356078e
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * arch/blackfin/kernel/reboot.c - handle shutdown/reboot
+ *
+ * Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/interrupt.h>
+#include <asm/bfin-global.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+#if defined(BF537_FAMILY) || defined(BF533_FAMILY)
+#define SYSCR_VAL      0x0
+#elif defined(BF561_FAMILY)
+#define SYSCR_VAL      0x20
+#elif defined(BF548_FAMILY)
+#define SYSCR_VAL      0x10
+#endif
+
+/* A system soft reset makes external memory unusable
+ * so force this function into L1.
+ */
+__attribute__((l1_text))
+void bfin_reset(void)
+{
+       /* force BMODE and disable Core B (as needed) */
+       bfin_write_SYSCR(SYSCR_VAL);
+
+       /* we use asm ssync here because it's save and we save some L1 */
+       asm("ssync;");
+
+       while (1) {
+               /* initiate system soft reset with magic 0x7 */
+               bfin_write_SWRST(0x7);
+               asm("ssync;");
+               /* clear system soft reset */
+               bfin_write_SWRST(0);
+               asm("ssync;");
+               /* issue core reset */
+               asm("raise 1");
+       }
+}
+
+__attribute__((weak))
+void native_machine_restart(char *cmd)
+{
+}
+
+void machine_restart(char *cmd)
+{
+       native_machine_restart(cmd);
+       local_irq_disable();
+       bfin_reset();
+}
+
+__attribute__((weak))
+void native_machine_halt(void)
+{
+       idle_with_irq_disabled();
+}
+
+void machine_halt(void)
+{
+       native_machine_halt();
+}
+
+__attribute__((weak))
+void native_machine_power_off(void)
+{
+       idle_with_irq_disabled();
+}
+
+void machine_power_off(void)
+{
+       native_machine_power_off();
+}
index 88f221b89b33341192aa7d2099495e10351a99aa..8dcd76e87ed5171056796c08911642ba4026e988 100644 (file)
 #include <linux/cramfs_fs.h>
 #include <linux/romfs_fs.h>
 
+#include <asm/cplb.h>
 #include <asm/cacheflush.h>
 #include <asm/blackfin.h>
 #include <asm/cplbinit.h>
 #include <asm/fixed_code.h>
+#include <asm/early_printk.h>
 
 u16 _bfin_swrst;
 
@@ -66,21 +68,21 @@ char __initdata command_line[COMMAND_LINE_SIZE];
 
 void __init bf53x_cache_init(void)
 {
-#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
+#if defined(CONFIG_BFIN_DCACHE) || defined(CONFIG_BFIN_ICACHE)
        generate_cpl_tables();
 #endif
 
-#ifdef CONFIG_BLKFIN_CACHE
+#ifdef CONFIG_BFIN_ICACHE
        bfin_icache_init();
        printk(KERN_INFO "Instruction Cache Enabled\n");
 #endif
 
-#ifdef CONFIG_BLKFIN_DCACHE
+#ifdef CONFIG_BFIN_DCACHE
        bfin_dcache_init();
        printk(KERN_INFO "Data Cache Enabled"
-# if defined CONFIG_BLKFIN_WB
+# if defined CONFIG_BFIN_WB
                " (write-back)"
-# elif defined CONFIG_BLKFIN_WT
+# elif defined CONFIG_BFIN_WT
                " (write-through)"
 # endif
                "\n");
@@ -156,8 +158,10 @@ static __init void parse_cmdline_early(char *cmdline_p)
                                                            1;
                                        }
                                }
+                       } else if (!memcmp(to, "earlyprintk=", 12)) {
+                               to += 12;
+                               setup_early_printk(to);
                        }
-
                }
                c = *(to++);
                if (!c)
@@ -176,22 +180,36 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_DUMMY_CONSOLE
        conswitchp = &dummy_con;
 #endif
+
+#if defined(CONFIG_CMDLINE_BOOL)
+       strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line));
+       command_line[sizeof(command_line) - 1] = 0;
+#endif
+
+       /* Keep a copy of command line */
+       *cmdline_p = &command_line[0];
+       memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
+       boot_command_line[COMMAND_LINE_SIZE - 1] = '\0';
+
+       /* setup memory defaults from the user config */
+       physical_mem_end = 0;
+       _ramend = CONFIG_MEM_SIZE * 1024 * 1024;
+
+       parse_cmdline_early(&command_line[0]);
+
        cclk = get_cclk();
        sclk = get_sclk();
 
-#if !defined(CONFIG_BFIN_KERNEL_CLOCK) && defined(ANOMALY_05000273)
-       if (cclk == sclk)
+#if !defined(CONFIG_BFIN_KERNEL_CLOCK)
+       if (ANOMALY_05000273 && cclk == sclk)
                panic("ANOMALY 05000273, SCLK can not be same as CCLK");
 #endif
 
-#if defined(ANOMALY_05000266)
-       bfin_read_IMDMA_D0_IRQ_STATUS();
-       bfin_read_IMDMA_D1_IRQ_STATUS();
-#endif
-
-#ifdef DEBUG_SERIAL_EARLY_INIT
-       bfin_console_init();    /* early console registration */
-       /* this give a chance to get printk() working before crash. */
+#ifdef BF561_FAMILY
+       if (ANOMALY_05000266) {
+               bfin_read_IMDMA_D0_IRQ_STATUS();
+               bfin_read_IMDMA_D1_IRQ_STATUS();
+       }
 #endif
 
        printk(KERN_INFO "Hardware Trace ");
@@ -212,22 +230,6 @@ void __init setup_arch(char **cmdline_p)
        flash_probe();
 #endif
 
-#if defined(CONFIG_CMDLINE_BOOL)
-       strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line));
-       command_line[sizeof(command_line) - 1] = 0;
-#endif
-
-       /* Keep a copy of command line */
-       *cmdline_p = &command_line[0];
-       memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
-       boot_command_line[COMMAND_LINE_SIZE - 1] = '\0';
-
-       /* setup memory defaults from the user config */
-       physical_mem_end = 0;
-       _ramend = CONFIG_MEM_SIZE * 1024 * 1024;
-
-       parse_cmdline_early(&command_line[0]);
-
        if (physical_mem_end == 0)
                physical_mem_end = _ramend;
 
@@ -260,7 +262,7 @@ void __init setup_arch(char **cmdline_p)
            && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1)
                mtd_size =
                    PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2]));
-#  if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
+#  if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263)
        /* Due to a Hardware Anomaly we need to limit the size of usable
         * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
         * 05000263 - Hardware loop corrupted when taking an ICPLB exception
@@ -289,7 +291,7 @@ void __init setup_arch(char **cmdline_p)
        _ebss = memory_mtd_start;       /* define _ebss for compatible */
 #endif                         /* CONFIG_MTD_UCLINUX */
 
-#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
+#if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263)
        /* Due to a Hardware Anomaly we need to limit the size of usable
         * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
         * 05000263 - Hardware loop corrupted when taking an ICPLB exception
@@ -334,13 +336,11 @@ void __init setup_arch(char **cmdline_p)
                       CPU, bfin_revid());
        printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n");
 
-       printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu Mhz System Clock\n",
+       printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n",
               cclk / 1000000,  sclk / 1000000);
 
-#if defined(ANOMALY_05000273)
-       if ((cclk >> 1) <= sclk)
+       if (ANOMALY_05000273 && (cclk >> 1) <= sclk)
                printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n");
-#endif
 
        printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20);
        printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20);
@@ -535,9 +535,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                seq_printf(m, "I-CACHE:\tOFF\n");
        if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))
                seq_printf(m, "D-CACHE:\tON"
-#if defined CONFIG_BLKFIN_WB
+#if defined CONFIG_BFIN_WB
                           " (write-back)"
-#elif defined CONFIG_BLKFIN_WT
+#elif defined CONFIG_BFIN_WT
                           " (write-through)"
 #endif
                           "\n");
@@ -566,15 +566,15 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        }
 
 
-       seq_printf(m, "I-CACHE Size:\t%dKB\n", BLKFIN_ICACHESIZE / 1024);
+       seq_printf(m, "I-CACHE Size:\t%dKB\n", BFIN_ICACHESIZE / 1024);
        seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size);
        seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n",
-                  BLKFIN_ISUBBANKS, BLKFIN_IWAYS, BLKFIN_ILINES);
+                  BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES);
        seq_printf(m,
                   "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n",
-                  dsup_banks, BLKFIN_DSUBBANKS, BLKFIN_DWAYS,
-                  BLKFIN_DLINES);
-#ifdef CONFIG_BLKFIN_CACHE_LOCK
+                  dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS,
+                  BFIN_DLINES);
+#ifdef CONFIG_BFIN_ICACHE_LOCK
        switch (read_iloc()) {
        case WAY0_L:
                seq_printf(m, "Way0 Locked-Down\n");
index 792a8416fe10160cc81e2660c553bba5c3db92a0..8823e9ade5849b02968442e158990e3c02ade6c6 100644 (file)
@@ -51,10 +51,9 @@ void __init trap_init(void)
        CSYNC();
 }
 
-asmlinkage void trap_c(struct pt_regs *fp);
-
 int kstack_depth_to_print = 48;
 
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
 static int printk_address(unsigned long address)
 {
        struct vm_list_struct *vml;
@@ -131,10 +130,22 @@ static int printk_address(unsigned long address)
        /* we were unable to find this address anywhere */
        return printk("[<0x%p>]", (void *)address);
 }
+#endif
+
+asmlinkage void double_fault_c(struct pt_regs *fp)
+{
+       printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n");
+       dump_bfin_regs(fp, (void *)fp->retx);
+       panic("Double Fault - unrecoverable event\n");
+
+}
 
 asmlinkage void trap_c(struct pt_regs *fp)
 {
-       int j, sig = 0;
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
+       int j;
+#endif
+       int sig = 0;
        siginfo_t info;
        unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE;
 
@@ -391,10 +402,6 @@ asmlinkage void trap_c(struct pt_regs *fp)
                break;
        }
 
-       info.si_signo = sig;
-       info.si_errno = 0;
-       info.si_addr = (void *)fp->pc;
-       force_sig_info(sig, &info, current);
        if (sig != 0 && sig != SIGTRAP) {
                unsigned long stack;
                dump_bfin_regs(fp, (void *)fp->retx);
@@ -403,6 +410,10 @@ asmlinkage void trap_c(struct pt_regs *fp)
                if (current->mm == NULL)
                        panic("Kernel exception");
        }
+       info.si_signo = sig;
+       info.si_errno = 0;
+       info.si_addr = (void *)fp->pc;
+       force_sig_info(sig, &info, current);
 
        /* if the address that we are about to return to is not valid, set it
         * to a valid address, if we have a current application or panic
@@ -429,24 +440,56 @@ asmlinkage void trap_c(struct pt_regs *fp)
 
 /* Typical exception handling routines */
 
+#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1)
+
 void dump_bfin_trace_buffer(void)
 {
-       int tflags;
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
+       int tflags, i = 0;
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
+       int j, index;
+#endif
+
        trace_buffer_save(tflags);
 
+       printk(KERN_EMERG "Hardware Trace:\n");
+
        if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) {
-               int i;
-               printk(KERN_EMERG "Hardware Trace:\n");
-               for (i = 0; bfin_read_TBUFSTAT() & TBUFCNT; i++) {
-                       printk(KERN_EMERG "%2i Target : ", i);
+               for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) {
+                       printk(KERN_EMERG "%4i Target : ", i);
                        printk_address((unsigned long)bfin_read_TBUF());
-                       printk("\n" KERN_EMERG "   Source : ");
+                       printk("\n" KERN_EMERG "     Source : ");
                        printk_address((unsigned long)bfin_read_TBUF());
                        printk("\n");
                }
        }
 
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
+       if (trace_buff_offset)
+               index = trace_buff_offset/4 - 1;
+       else
+               index = EXPAND_LEN;
+
+       j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128;
+       while (j) {
+               printk(KERN_EMERG "%4i Target : ", i);
+               printk_address(software_trace_buff[index]);
+               index -= 1;
+               if (index < 0 )
+                       index = EXPAND_LEN;
+               printk("\n" KERN_EMERG "     Source : ");
+               printk_address(software_trace_buff[index]);
+               index -= 1;
+               if (index < 0)
+                       index = EXPAND_LEN;
+               printk("\n");
+               j--;
+               i++;
+       }
+#endif
+
        trace_buffer_restore(tflags);
+#endif
 }
 EXPORT_SYMBOL(dump_bfin_trace_buffer);
 
@@ -510,7 +553,9 @@ void show_stack(struct task_struct *task, unsigned long *stack)
 void dump_stack(void)
 {
        unsigned long stack;
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
        int tflags;
+#endif
        trace_buffer_save(tflags);
        dump_bfin_trace_buffer();
        show_stack(current, &stack);
@@ -559,8 +604,7 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr)
                unsigned short x = 0;
                for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) {
                        if (!(i & 0xF))
-                               printk(KERN_EMERG "\n" KERN_EMERG
-                                       "0x%08x: ", i);
+                               printk("\n" KERN_EMERG "0x%08x: ", i);
 
                        if (get_user(x, (unsigned short *)i))
                                break;
@@ -655,6 +699,42 @@ asmlinkage int sys_bfin_spinlock(int *spinlock)
        return ret;
 }
 
+int bfin_request_exception(unsigned int exception, void (*handler)(void))
+{
+       void (*curr_handler)(void);
+
+       if (exception > 0x3F)
+               return -EINVAL;
+
+       curr_handler = ex_table[exception];
+
+       if (curr_handler != ex_replaceable)
+               return -EBUSY;
+
+       ex_table[exception] = handler;
+
+       return 0;
+}
+EXPORT_SYMBOL(bfin_request_exception);
+
+int bfin_free_exception(unsigned int exception, void (*handler)(void))
+{
+       void (*curr_handler)(void);
+
+       if (exception > 0x3F)
+               return -EINVAL;
+
+       curr_handler = ex_table[exception];
+
+       if (curr_handler != handler)
+               return -EBUSY;
+
+       ex_table[exception] = ex_replaceable;
+
+       return 0;
+}
+EXPORT_SYMBOL(bfin_free_exception);
+
 void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
 {
        switch (cplb_panic) {
index fb53780247bc94bf5c1ce393f54cab5620e43db4..eec43674a46589a05411566d009ccc585e699904 100644 (file)
@@ -49,7 +49,8 @@ SECTIONS
                TEXT_TEXT
                SCHED_TEXT
                LOCK_TEXT
-               *(.text.lock)
+               KPROBES_TEXT
+               *(.text.*)
                *(.fixup)
 
                . = ALIGN(16);
@@ -61,7 +62,7 @@ SECTIONS
                __etext = .;
        }
 
-       RODATA
+       RO_DATA(PAGE_SIZE)
 
        .data :
        {
@@ -72,50 +73,63 @@ SECTIONS
                __sdata = .;
                . = ALIGN(THREAD_SIZE);
                *(.data.init_task)
-               DATA_DATA
-               CONSTRUCTORS
 
                . = ALIGN(32);
                *(.data.cacheline_aligned)
 
+               DATA_DATA
+               *(.data.*)
+               CONSTRUCTORS
+
                . = ALIGN(THREAD_SIZE);
                __edata = .;
        }
 
        ___init_begin = .;
-       .init :
+
+       .init.text :
        {
                . = ALIGN(PAGE_SIZE);
                __sinittext = .;
                *(.init.text)
                __einittext = .;
+       }
+       .init.data :
+       {
+               . = ALIGN(16);
                *(.init.data)
+       }
+       .init.setup :
+       {
                . = ALIGN(16);
                ___setup_start = .;
                *(.init.setup)
                ___setup_end = .;
-               ___start___param = .;
-               *(__param)
-               ___stop___param = .;
+       }
+       .initcall.init :
+       {
                ___initcall_start = .;
                INITCALLS
                ___initcall_end = .;
+       }
+       .con_initcall.init :
+       {
                ___con_initcall_start = .;
                *(.con_initcall.init)
                ___con_initcall_end = .;
-               ___security_initcall_start = .;
-               *(.security_initcall.init)
-               ___security_initcall_end = .;
+       }
+       SECURITY_INIT
+       .init.ramfs :
+       {
                . = ALIGN(4);
                ___initramfs_start = .;
                *(.init.ramfs)
                ___initramfs_end = .;
-               . = ALIGN(4);
        }
 
        __l1_lma_start = .;
 
-       .text_l1 L1_CODE_START : AT(LOADADDR(.init) + SIZEOF(.init))
+       .text_l1 L1_CODE_START : AT(LOADADDR(.init.ramfs) + SIZEOF(.init.ramfs))
        {
                . = ALIGN(4);
                __stext_l1 = .;
@@ -164,13 +178,19 @@ SECTIONS
        {
                . = ALIGN(4);
                ___bss_start = .;
-               *(.bss)
+               *(.bss .bss.*)
                *(COMMON)
                . = ALIGN(4);
                ___bss_stop = .;
                __end = .;
        }
 
+       STABS_DEBUG
+
+       DWARF_DEBUG
+
+       NOTES
+
        /DISCARD/ :
        {
                *(.exit.text)
index b88c5d2d1ebeb65fff4f7783cabc10dd3e8bfe30..219fa2877c62a9f0ca096d51091838157bd57a66 100644 (file)
@@ -61,7 +61,7 @@ ENTRY(_memcmp)
 
        LSETUP (.Lquad_loop_s, .Lquad_loop_e) LC0=P1;
 .Lquad_loop_s:
-#ifdef ANOMALY_05000202
+#if ANOMALY_05000202
        R0 = [P0++];
        R1 = [I0++];
 #else
index 14a5585bbd023e8a27fbd9d7f5727c1cfa25e6d3..2e6336492b4b3500e4511cd7e9a8e691aba02d3b 100644 (file)
@@ -98,7 +98,7 @@ ENTRY(_memcpy)
        R0 = R1;
        I1 = P1;
        R3 = [I1++];
-#ifdef ANOMALY_05000202
+#if ANOMALY_05000202
 .Lword_loops:
        [P0++] = R3;
 .Lword_loope:
index 6ee6e206e77cc59187872ff9ef4db312e4c6238f..33f8653145b7e8bc5c68c36dcd231a9c49dfe064 100644 (file)
@@ -70,7 +70,7 @@ ENTRY(_memmove)
        R1 = [I0++];
 
        LSETUP (.Lquad_loops, .Lquad_loope) LC0=P1;
-#ifdef ANOMALY_05000202
+#if ANOMALY_05000202
 .Lquad_loops:
        [P0++] = R1;
 .Lquad_loope:
@@ -102,7 +102,7 @@ ENTRY(_memmove)
        R1 = B[P3--] (Z);
        CC = P2 == 0;
        IF CC JUMP .Lno_loop;
-#ifdef ANOMALY_05000245
+#if ANOMALY_05000245
        NOP;
        NOP;
 #endif
index 4545f363e641d9f1aafd3d9dbcaa19a3a00ba53f..a57b52d207cda6ac4a200dace6093e1f12e2515c 100644 (file)
@@ -34,7 +34,9 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
+#include <linux/pata_platform.h>
 #include <linux/irq.h>
+#include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -93,7 +95,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                /* the modalias must be the same as spi device driver name */
                .modalias = "m25p80",       /* Name of spi_driver for this device */
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,               /* Framework bus number */
+               .bus_num = 0,               /* Framework bus number */
                .chip_select = 1,           /* Framework chip select. On STAMP537 it is SPISSEL1*/
                .platform_data = &bfin_spi_flash_data,
                .controller_data = &spi_flash_chip_info,
@@ -101,7 +103,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        }, {
                .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
                .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,               /* Framework bus number */
+               .bus_num = 0,               /* Framework bus number */
                .chip_select = 2,           /* Framework chip select. */
                .platform_data = NULL,      /* No spi_driver specific config */
                .controller_data = &spi_adc_chip_info,
@@ -110,24 +112,40 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad1836-spi",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
 #endif
 };
 
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
 /* SPI controller data */
-static struct bfin5xx_spi_master spi_bfin_master_info = {
+static struct bfin5xx_spi_master bfin_spi0_info = {
        .num_chipselect = 8,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
 };
 
-static struct platform_device spi_bfin_master_device = {
-       .name = "bfin-spi-master",
-       .id = 1, /* Bus number */
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
        .dev = {
-               .platform_data = &spi_bfin_master_info, /* Passed to driver */
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
        },
 };
 #endif  /* spi master and devices */
@@ -227,6 +245,43 @@ static struct platform_device isp1362_hcd_device = {
 };
 #endif
 
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT       38
+
+static struct pata_platform_info bfin_pata_platform_data = {
+       .ioport_shift = 2,
+       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+       {
+               .start = 0x2030C000,
+               .end = 0x2030C01F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = 0x2030D018,
+               .end = 0x2030D01B,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = PATA_INT,
+               .end = PATA_INT,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pata_device = {
+       .name = "pata_platform",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pata_resources),
+       .resource = bfin_pata_resources,
+       .dev = {
+               .platform_data = &bfin_pata_platform_data,
+       }
+};
+#endif
+
 static struct platform_device *cm_bf533_devices[] __initdata = {
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
        &bfin_uart_device,
@@ -250,7 +305,11 @@ static struct platform_device *cm_bf533_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       &spi_bfin_master_device,
+       &bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       &bfin_pata_device,
 #endif
 };
 
@@ -261,6 +320,10 @@ static int __init cm_bf533_init(void)
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
        spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 #endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
        return 0;
 }
 
index 0000b8f1239c5030a6b3e56cfd1b7ab907a18632..5c1e35d3c012b62e26c567fcc3b77a7978cd7d4d 100644 (file)
@@ -35,7 +35,9 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
+#include <linux/pata_platform.h>
 #include <linux/irq.h>
+#include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -50,6 +52,12 @@ static struct platform_device rtc_device = {
 };
 #endif
 
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+static struct platform_device bfin_fb_adv7393_device = {
+       .name = "bfin-adv7393",
+};
+#endif
+
 /*
  *  USB-LAN EzExtender board
  *  Driver needs to know address, irq and flag pin.
@@ -131,7 +139,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                /* the modalias must be the same as spi device driver name */
                .modalias = "m25p80", /* Name of spi_driver for this device */
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL2*/
                .platform_data = &bfin_spi_flash_data,
                .controller_data = &spi_flash_chip_info,
@@ -143,7 +151,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
                .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 1, /* Framework chip select. */
                .platform_data = NULL, /* No spi_driver specific config */
                .controller_data = &spi_adc_chip_info,
@@ -154,24 +162,40 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad1836-spi",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
 #endif
 };
 
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
 /* SPI controller data */
-static struct bfin5xx_spi_master spi_bfin_master_info = {
+static struct bfin5xx_spi_master bfin_spi0_info = {
        .num_chipselect = 8,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
 };
 
-static struct platform_device spi_bfin_master_device = {
-       .name = "bfin-spi-master",
-       .id = 1, /* Bus number */
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
        .dev = {
-               .platform_data = &spi_bfin_master_info, /* Passed to driver */
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
        },
 };
 #endif  /* spi master and devices */
@@ -193,13 +217,54 @@ static struct platform_device bfin_uart_device = {
 };
 #endif
 
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT       55
+
+static struct pata_platform_info bfin_pata_platform_data = {
+       .ioport_shift = 1,
+       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+       {
+               .start = 0x20314020,
+               .end = 0x2031403F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = 0x2031401C,
+               .end = 0x2031401F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = PATA_INT,
+               .end = PATA_INT,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pata_device = {
+       .name = "pata_platform",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pata_resources),
+       .resource = bfin_pata_resources,
+       .dev = {
+               .platform_data = &bfin_pata_platform_data,
+       }
+};
+#endif
+
 static struct platform_device *ezkit_devices[] __initdata = {
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
        &smc91x_device,
 #endif
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       &spi_bfin_master_device,
+       &bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+       &bfin_fb_adv7393_device,
 #endif
 
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
@@ -209,6 +274,10 @@ static struct platform_device *ezkit_devices[] __initdata = {
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
        &bfin_uart_device,
 #endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       &bfin_pata_device,
+#endif
 };
 
 static int __init ezkit_init(void)
@@ -218,6 +287,10 @@ static int __init ezkit_init(void)
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
        spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 #endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
        return 0;
 }
 
index a9143c4cbdcd110d3f88ddb697e04cab015e6e19..8975e06ea1582397849bada89e4b5b862405359b 100644 (file)
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb_isp1362.h>
 #endif
+#include <linux/pata_platform.h>
 #include <linux/irq.h>
+#include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
+#include <asm/reboot.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -77,6 +80,12 @@ static struct platform_device smc91x_device = {
 };
 #endif
 
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+static struct platform_device bfin_fb_adv7393_device = {
+       .name = "bfin-adv7393",
+};
+#endif
+
 #if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
 static struct resource net2272_bfin_resources[] = {
        {
@@ -177,7 +186,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                /* the modalias must be the same as spi device driver name */
                .modalias = "m25p80", /* Name of spi_driver for this device */
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL2*/
                .platform_data = &bfin_spi_flash_data,
                .controller_data = &spi_flash_chip_info,
@@ -189,7 +198,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
                .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 1, /* Framework chip select. */
                .platform_data = NULL, /* No spi_driver specific config */
                .controller_data = &spi_adc_chip_info,
@@ -200,7 +209,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad1836-spi",
                .max_speed_hz = 31250000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
@@ -210,7 +219,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "spi_mmc_dummy",
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = 0,
                .platform_data = NULL,
                .controller_data = &spi_mmc_chip_info,
@@ -219,7 +228,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "spi_mmc",
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SPI_MMC_CS_CHAN,
                .platform_data = NULL,
                .controller_data = &spi_mmc_chip_info,
@@ -231,16 +240,16 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "fxs-spi",
                .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
-               .chip_select = 3,
+               .bus_num = 0,
+               .chip_select = 8 - CONFIG_J11_JUMPER,
                .controller_data = &spi_si3xxx_chip_info,
                .mode = SPI_MODE_3,
        },
        {
                .modalias = "fxo-spi",
                .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
-               .chip_select = 2,
+               .bus_num = 0,
+               .chip_select = 8 - CONFIG_J19_JUMPER,
                .controller_data = &spi_si3xxx_chip_info,
                .mode = SPI_MODE_3,
        },
@@ -250,7 +259,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad5304_spi",
                .max_speed_hz = 1000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = 2,
                .platform_data = NULL,
                .controller_data = &ad5304_chip_info,
@@ -259,17 +268,33 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #endif
 };
 
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
 /* SPI controller data */
-static struct bfin5xx_spi_master spi_bfin_master_info = {
+static struct bfin5xx_spi_master bfin_spi0_info = {
        .num_chipselect = 8,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
 };
 
-static struct platform_device spi_bfin_master_device = {
-       .name = "bfin-spi-master",
-       .id = 1, /* Bus number */
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
        .dev = {
-               .platform_data = &spi_bfin_master_info, /* Passed to driver */
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
        },
 };
 #endif  /* spi master and devices */
@@ -309,6 +334,43 @@ static struct platform_device bfin_sport1_uart_device = {
 };
 #endif
 
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT       55
+
+static struct pata_platform_info bfin_pata_platform_data = {
+       .ioport_shift = 1,
+       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+       {
+               .start = 0x20314020,
+               .end = 0x2031403F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = 0x2031401C,
+               .end = 0x2031401F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = PATA_INT,
+               .end = PATA_INT,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pata_device = {
+       .name = "pata_platform",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pata_resources),
+       .resource = bfin_pata_resources,
+       .dev = {
+               .platform_data = &bfin_pata_platform_data,
+       }
+};
+#endif
+
 static struct platform_device *stamp_devices[] __initdata = {
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
        &rtc_device,
@@ -318,12 +380,16 @@ static struct platform_device *stamp_devices[] __initdata = {
        &smc91x_device,
 #endif
 
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+       &bfin_fb_adv7393_device,
+#endif
+
 #if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
        &net2272_bfin_device,
 #endif
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       &spi_bfin_master_device,
+       &bfin_spi0_device,
 #endif
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
@@ -334,6 +400,10 @@ static struct platform_device *stamp_devices[] __initdata = {
        &bfin_sport0_uart_device,
        &bfin_sport1_uart_device,
 #endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       &bfin_pata_device,
+#endif
 };
 
 static int __init stamp_init(void)
@@ -355,8 +425,23 @@ static int __init stamp_init(void)
 #endif
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       return spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+       spi_register_board_info(bfin_spi_board_info,
+                               ARRAY_SIZE(bfin_spi_board_info));
+#endif
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
 #endif
+       return 0;
 }
 
 arch_initcall(stamp_init);
+
+void native_machine_restart(char *cmd)
+{
+#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
+# define BIT_TO_SET (1 << CONFIG_ENET_FLASH_PIN)
+       bfin_write_FIO_INEN(~BIT_TO_SET);
+       bfin_write_FIO_DIR(BIT_TO_SET);
+       bfin_write_FIO_FLAG_C(BIT_TO_SET);
+#endif
+}
index 7dd0e9c3a936402e4e9470677114b8155eababbe..1ded945a6fa0212973a122b24d022bd79751cd2c 100644 (file)
 #include <asm/blackfin.h>
 #include <asm/trace.h>
 #if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach-common/clocks.h>
 #include <asm/mach/mem_init.h>
 #endif
-#if CONFIG_DEBUG_KERNEL_START
-#include <asm/mach-common/def_LPBlackfin.h>
-#endif
 
 .global __rambase
 .global __ramstart
@@ -52,10 +50,12 @@ __INIT
 ENTRY(__start)
        /* R0: argument of command line string, passed from uboot, save it */
        R7 = R0;
-       /* Set the SYSCFG register:
-        * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit)
-        */
-       R0 = 0x36;
+       /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+       R0 = SYSCFG_SNEN;
+#else
+       R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
        SYSCFG = R0;
        R0 = 0;
 
@@ -97,40 +97,10 @@ ENTRY(__start)
        M2 = r0;
        M3 = r0;
 
-       trace_buffer_start(p0,r0);
+       trace_buffer_init(p0,r0);
        P0 = R1;
        R0 = R1;
 
-#if CONFIG_DEBUG_KERNEL_START
-
-/*
- * Set up a temporary Event Vector Table, so if something bad happens before
- * the kernel is fully started, it doesn't vector off into the bootloaders
- * table
- */
-       P0.l = lo(EVT2);
-       P0.h = hi(EVT2);
-       P1.l = lo(EVT15);
-       P1.h = hi(EVT15);
-       P2.l = debug_kernel_start_trap;
-       P2.h = debug_kernel_start_trap;
-
-       RTS = P2;
-       RTI = P2;
-       RTX = P2;
-       RTN = P2;
-       RTE = P2;
-
-.Lfill_temp_vector_table:
-       [P0++] = P2;    /* Core Event Vector Table */
-       CC = P0 == P1;
-       if !CC JUMP .Lfill_temp_vector_table
-       P0 = r0;
-       P1 = r0;
-       P2 = r0;
-
-#endif
-
        p0.h = hi(FIO_MASKA_C);
        p0.l = lo(FIO_MASKA_C);
        r0 = 0xFFFF(Z);
@@ -144,38 +114,38 @@ ENTRY(__start)
        ssync;
 
        /* Turn off the icache */
-       p0.l = (IMEM_CONTROL & 0xFFFF);
-       p0.h = (IMEM_CONTROL >> 16);
+       p0.l = LO(IMEM_CONTROL);
+       p0.h = HI(IMEM_CONTROL);
        R1 = [p0];
        R0 = ~ENICPLB;
        R0 = R0 & R1;
 
        /* Anomaly 05000125 */
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        CLI R2;
        SSYNC;
 #endif
        [p0] = R0;
        SSYNC;
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        STI R2;
 #endif
 
        /* Turn off the dcache */
-       p0.l = (DMEM_CONTROL & 0xFFFF);
-       p0.h = (DMEM_CONTROL >> 16);
+       p0.l = LO(DMEM_CONTROL);
+       p0.h = HI(DMEM_CONTROL);
        R1 = [p0];
        R0 = ~ENDCPLB;
        R0 = R0 & R1;
 
        /* Anomaly 05000125 */
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        CLI R2;
        SSYNC;
 #endif
        [p0] = R0;
        SSYNC;
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        STI R2;
 #endif
 
@@ -211,6 +181,12 @@ ENTRY(__start)
        fp = sp;
        usp = sp;
 
+#ifdef CONFIG_EARLY_PRINTK
+       SP += -12;
+       call _init_early_exception_vectors;
+       SP += 12;
+#endif
+
        /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
        call _bf53x_relocate_l1_mem;
 #if CONFIG_BFIN_KERNEL_CLOCK
@@ -264,7 +240,7 @@ ENTRY(__start)
        p0.l = .LWAIT_HERE;
        p0.h = .LWAIT_HERE;
        reti = p0;
-#if defined(ANOMALY_05000281)
+#if ANOMALY_05000281
        nop; nop; nop;
 #endif
        rti;
@@ -417,8 +393,8 @@ ENTRY(_start_dma_code)
        w[p0] = r0.l;
        ssync;
 
-       p0.l = (EBIU_SDBCTL & 0xFFFF);
-       p0.h = (EBIU_SDBCTL >> 16);     /* SDRAM Memory Bank Control Register */
+       p0.l = LO(EBIU_SDBCTL);
+       p0.h = HI(EBIU_SDBCTL);     /* SDRAM Memory Bank Control Register */
        r0 = mem_SDBCTL;
        w[p0] = r0.l;
        ssync;
@@ -456,276 +432,6 @@ ENTRY(_start_dma_code)
 ENDPROC(_start_dma_code)
 #endif /* CONFIG_BFIN_KERNEL_CLOCK */
 
-ENTRY(_bfin_reset)
-       /* No more interrupts to be handled*/
-       CLI R6;
-       SSYNC;
-
-#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
-       p0.h = hi(FIO_INEN);
-       p0.l = lo(FIO_INEN);
-       r0.l = ~(1 << CONFIG_ENET_FLASH_PIN);
-       w[p0] = r0.l;
-
-       p0.h = hi(FIO_DIR);
-       p0.l = lo(FIO_DIR);
-       r0.l = (1 << CONFIG_ENET_FLASH_PIN);
-       w[p0] = r0.l;
-
-       p0.h = hi(FIO_FLAG_C);
-       p0.l = lo(FIO_FLAG_C);
-       r0.l = (1 << CONFIG_ENET_FLASH_PIN);
-       w[p0] = r0.l;
-#endif
-
-       /* Clear the IMASK register */
-       p0.h = hi(IMASK);
-       p0.l = lo(IMASK);
-       r0 = 0x0;
-       [p0] = r0;
-
-       /* Clear the ILAT register */
-       p0.h = hi(ILAT);
-       p0.l = lo(ILAT);
-       r0 = [p0];
-       [p0] = r0;
-       SSYNC;
-
-       /* make sure SYSCR is set to use BMODE */
-       P0.h = hi(SYSCR);
-       P0.l = lo(SYSCR);
-       R0.l = 0x0;
-       W[P0] = R0.l;
-       SSYNC;
-
-       /* issue a system soft reset */
-       P1.h = hi(SWRST);
-       P1.l = lo(SWRST);
-       R1.l = 0x0007;
-       W[P1] = R1;
-       SSYNC;
-
-       /* clear system soft reset */
-       R0.l = 0x0000;
-       W[P0] = R0;
-       SSYNC;
-
-       /* issue core reset */
-       raise 1;
-
-       RTS;
-ENDPROC(_bfin_reset)
-
-#if CONFIG_DEBUG_KERNEL_START
-debug_kernel_start_trap:
-       /* Set up a temp stack in L1 - SDRAM might not be working  */
-       P0.L = lo(L1_DATA_A_START + 0x100);
-       P0.H = hi(L1_DATA_A_START + 0x100);
-       SP = P0;
-
-       /* Make sure the Clocks are the way I think they should be */
-       r0 = CONFIG_VCO_MULT & 63;       /* Load the VCO multiplier         */
-       r0 = r0 << 9;                    /* Shift it over,                  */
-       r1 = CLKIN_HALF;                 /* Do we need to divide CLKIN by 2?*/
-       r0 = r1 | r0;
-       r1 = PLL_BYPASS;                 /* Bypass the PLL?                 */
-       r1 = r1 << 8;                    /* Shift it over                   */
-       r0 = r1 | r0;                    /* add them all together           */
-
-       p0.h = hi(PLL_CTL);
-       p0.l = lo(PLL_CTL);              /* Load the address                */
-       cli r2;                          /* Disable interrupts              */
-       ssync;
-       w[p0] = r0.l;                    /* Set the value                   */
-       idle;                            /* Wait for the PLL to stablize    */
-       sti r2;                          /* Enable interrupts               */
-
-.Lcheck_again1:
-       p0.h = hi(PLL_STAT);
-       p0.l = lo(PLL_STAT);
-       R0 = W[P0](Z);
-       CC = BITTST(R0,5);
-       if ! CC jump .Lcheck_again1;
-
-       /* Configure SCLK & CCLK Dividers */
-       r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
-       p0.h = hi(PLL_DIV);
-       p0.l = lo(PLL_DIV);
-       w[p0] = r0.l;
-       ssync;
-
-       /* Make sure UART is enabled - you can never be sure */
-
-/*
- * Setup for console. Argument comes from the menuconfig
- */
-
-#ifdef CONFIG_BAUD_9600
-#define CONSOLE_BAUD_RATE       9600
-#elif CONFIG_BAUD_19200
-#define CONSOLE_BAUD_RATE       19200
-#elif CONFIG_BAUD_38400
-#define CONSOLE_BAUD_RATE       38400
-#elif CONFIG_BAUD_57600
-#define CONSOLE_BAUD_RATE       57600
-#elif CONFIG_BAUD_115200
-#define CONSOLE_BAUD_RATE       115200
-#endif
-
-       p0.h = hi(UART_GCTL);
-       p0.l = lo(UART_GCTL);
-       r0 = 0x00(Z);
-       w[p0] = r0.L;   /* To Turn off UART clocks */
-       ssync;
-
-       p0.h = hi(UART_LCR);
-       p0.l = lo(UART_LCR);
-       r0 = 0x83(Z);
-       w[p0] = r0.L;   /* To enable DLL writes */
-       ssync;
-
-       R1 = (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_SCLK_DIV) / (CONSOLE_BAUD_RATE * 16));
-
-       p0.h = hi(UART_DLL);
-       p0.l = lo(UART_DLL);
-       r0 = 0xFF(Z);
-       r0 = R1 & R0;
-       w[p0] = r0.L;
-       ssync;
-
-       p0.h = hi(UART_DLH);
-       p0.l = lo(UART_DLH);
-       r1 >>= 8 ;
-       w[p0] = r1.L;
-       ssync;
-
-       p0.h = hi(UART_GCTL);
-       p0.l = lo(UART_GCTL);
-       r0 = 0x0(Z);
-       w[p0] = r0.L;   /* To enable UART clock */
-       ssync;
-
-       p0.h = hi(UART_LCR);
-       p0.l = lo(UART_LCR);
-       r0 = 0x03(Z);
-       w[p0] = r0.L;   /* To Turn on UART */
-       ssync;
-
-       p0.h = hi(UART_GCTL);
-       p0.l = lo(UART_GCTL);
-       r0 = 0x01(Z);
-       w[p0] = r0.L;   /* To Turn on UART Clocks */
-       ssync;
-
-       P0.h = hi(UART_THR);
-       P0.l = lo(UART_THR);
-       P1.h = hi(UART_LSR);
-       P1.l = lo(UART_LSR);
-
-       R0.L = 'K';
-       call .Lwait_char;
-       R0.L='e';
-       call .Lwait_char;
-       R0.L='r';
-       call .Lwait_char;
-       R0.L='n'
-       call .Lwait_char;
-       R0.L='e'
-       call .Lwait_char;
-       R0.L='l';
-       call .Lwait_char;
-       R0.L=' ';
-       call .Lwait_char;
-       R0.L='c';
-       call .Lwait_char;
-       R0.L='r';
-       call .Lwait_char;
-       R0.L='a';
-       call .Lwait_char;
-       R0.L='s';
-       call .Lwait_char;
-       R0.L='h';
-       call .Lwait_char;
-       R0.L='\r';
-       call .Lwait_char;
-       R0.L='\n';
-       call .Lwait_char;
-
-       R0.L='S';
-       call .Lwait_char;
-       R0.L='E';
-       call .Lwait_char;
-       R0.L='Q'
-       call .Lwait_char;
-       R0.L='S'
-       call .Lwait_char;
-       R0.L='T';
-       call .Lwait_char;
-       R0.L='A';
-       call .Lwait_char;
-       R0.L='T';
-       call .Lwait_char;
-       R0.L='=';
-       call .Lwait_char;
-       R2 = SEQSTAT;
-       call .Ldump_reg;
-
-       R0.L=' ';
-       call .Lwait_char;
-       R0.L='R';
-       call .Lwait_char;
-       R0.L='E'
-       call .Lwait_char;
-       R0.L='T'
-       call .Lwait_char;
-       R0.L='X';
-       call .Lwait_char;
-       R0.L='=';
-       call .Lwait_char;
-       R2 = RETX;
-       call .Ldump_reg;
-
-       R0.L='\r';
-       call .Lwait_char;
-       R0.L='\n';
-       call .Lwait_char;
-
-.Ldebug_kernel_start_trap_done:
-       JUMP    .Ldebug_kernel_start_trap_done;
-.Ldump_reg:
-       R3 = 32;
-       R4 = 0x0F;
-       R5 = ':';  /* one past 9 */
-
-.Ldump_reg2:
-       R0 = R2;
-       R3 += -4;
-       R0 >>>= R3;
-       R0 = R0 & R4;
-       R0 += 0x30;
-       CC = R0 <= R5;
-       if CC JUMP .Ldump_reg1;
-       R0 += 7;
-
-.Ldump_reg1:
-       R1.l = W[P1];
-       CC = BITTST(R1, 5);
-       if !CC JUMP .Ldump_reg1;
-       W[P0] = r0;
-
-       CC = R3 == 0;
-       if !CC JUMP .Ldump_reg2
-       RTS;
-
-.Lwait_char:
-       R1.l = W[P1];
-       CC = BITTST(R1, 5);
-       if !CC JUMP .Lwait_char;
-       W[P0] = r0;
-       RTS;
-
-#endif  /* CONFIG_DEBUG_KERNEL_START  */
-
 .data
 
 /*
index cc9ae38a4dda151f741c9b4e124b5f4b207fcd72..e6648db0951931a694bd4c28c3b2b6e19889ec31 100644 (file)
@@ -2,33 +2,6 @@ if (BF537 || BF534 || BF536)
 
 menu "BF537 Specific Configuration"
 
-comment "PORT F/G Selection"
-choice
-       prompt "Select BF537/6/4 default GPIO PFx PORTx"
-       help
-         Quick Hack for BF537/6/4 default GPIO PFx PORTF.
-
-config BF537_PORT_F
-       bool "Select BF537/6/4 default GPIO PFx PORTF"
-       depends on (BF537 || BF536 || BF534)
-       help
-         Quick Hack for BF537/6/4 default GPIO PFx PORTF.
-
-config BF537_PORT_G
-       bool "Select BF537/6/4 default GPIO PFx PORTG"
-       depends on (BF537 || BF536 || BF534)
-       help
-         Quick Hack for BF537/6/4 default GPIO PFx PORTG.
-
-config BF537_PORT_H
-       bool "Select BF537/6/4 default GPIO PFx PORTH"
-       depends on (BF537 || BF536 || BF534)
-       help
-         Quick Hack for BF537/6/4 default GPIO PFx PORTH
-         Use only when Blackfin EMAC support is not required.
-
-endchoice
-
 comment "Interrupt Priority Assignment"
 menu "Priority"
 
index a8f947b727542fc2705107c515fe76556179fdaa..44dea05e1d034a6f29871b761196cfbc8549c478 100644 (file)
@@ -35,7 +35,9 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
+#include <linux/pata_platform.h>
 #include <linux/irq.h>
+#include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -113,7 +115,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                /* the modalias must be the same as spi device driver name */
                .modalias = "m25p80", /* Name of spi_driver for this device */
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
                .platform_data = &bfin_spi_flash_data,
                .controller_data = &spi_flash_chip_info,
@@ -125,7 +127,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
                .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 1, /* Framework chip select. */
                .platform_data = NULL, /* No spi_driver specific config */
                .controller_data = &spi_adc_chip_info,
@@ -136,7 +138,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad1836-spi",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
@@ -146,7 +148,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad9960-spi",
                .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = 1,
                .controller_data = &ad9960_spi_chip_info,
        },
@@ -156,7 +158,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "spi_mmc_dummy",
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = 7,
                .platform_data = NULL,
                .controller_data = &spi_mmc_chip_info,
@@ -165,7 +167,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "spi_mmc",
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SPI_MMC_CS_CHAN,
                .platform_data = NULL,
                .controller_data = &spi_mmc_chip_info,
@@ -174,17 +176,33 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #endif
 };
 
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+               },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
 /* SPI controller data */
-static struct bfin5xx_spi_master spi_bfin_master_info = {
+static struct bfin5xx_spi_master bfin_spi0_info = {
        .num_chipselect = 8,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
 };
 
-static struct platform_device spi_bfin_master_device = {
-       .name = "bfin-spi-master",
-       .id = 1, /* Bus number */
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
        .dev = {
-               .platform_data = &spi_bfin_master_info, /* Passed to driver */
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
        },
 };
 #endif  /* spi master and devices */
@@ -316,6 +334,43 @@ static struct platform_device bfin_mac_device = {
 };
 #endif
 
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT       64
+
+static struct pata_platform_info bfin_pata_platform_data = {
+       .ioport_shift = 2,
+       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+       {
+               .start = 0x2030C000,
+               .end = 0x2030C01F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = 0x2030D018,
+               .end = 0x2030D01B,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = PATA_INT,
+               .end = PATA_INT,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pata_device = {
+       .name = "pata_platform",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pata_resources),
+       .resource = bfin_pata_resources,
+       .dev = {
+               .platform_data = &bfin_pata_platform_data,
+       }
+};
+#endif
+
 static struct platform_device *cm_bf537_devices[] __initdata = {
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
        &rtc_device,
@@ -347,7 +402,11 @@ static struct platform_device *cm_bf537_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       &spi_bfin_master_device,
+       &bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       &bfin_pata_device,
 #endif
 };
 
@@ -358,6 +417,10 @@ static int __init cm_bf537_init(void)
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
        spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 #endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
        return 0;
 }
 
index 648d984e98d6ce45b536a9a92b06a8c8e4333e5e..5e9d09eb857944fb553e6de1c23c9f9d9780c59f 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Modified:
  *               Copyright 2005 National ICT Australia (NICTA)
- *               Copyright 2004-2006 Analog Devices Inc.
+ *               Copyright 2004-2007 Analog Devices Inc.
  *
  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
  *
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb_isp1362.h>
+#endif
+#include <linux/pata_platform.h>
 #include <linux/irq.h>
+#include <linux/interrupt.h>
 #include <linux/usb_sl811.h>
+#include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
+#include <asm/reboot.h>
+#include <linux/spi/ad7877.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
  */
-char *bfin_board_name = "UNKNOWN BOARD";
+char *bfin_board_name = "GENERIC Board";
 
 /*
  *  Driver needs to know address, irq and flag pin.
  */
 
+#define ISP1761_BASE       0x203C0000
+#define ISP1761_IRQ        IRQ_PF7
+
+#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
+static struct resource bfin_isp1761_resources[] = {
+       [0] = {
+               .name   = "isp1761-regs",
+               .start  = ISP1761_BASE + 0x00000000,
+               .end    = ISP1761_BASE + 0x000fffff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = ISP1761_IRQ,
+               .end    = ISP1761_IRQ,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_isp1761_device = {
+       .name           = "isp1761",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(bfin_isp1761_resources),
+       .resource       = bfin_isp1761_resources,
+};
+
+static struct platform_device *bfin_isp1761_devices[] = {
+       &bfin_isp1761_device,
+};
+
+int __init bfin_isp1761_init(void)
+{
+       unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices);
+
+       printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+       set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING);
+
+       return platform_add_devices(bfin_isp1761_devices, num_devices);
+}
+
+void __exit bfin_isp1761_exit(void)
+{
+       platform_device_unregister(&bfin_isp1761_device);
+}
+
+arch_initcall(bfin_isp1761_init);
+#endif
+
 #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
 static struct resource bfin_pcmcia_cf_resources[] = {
        {
@@ -58,10 +112,6 @@ static struct resource bfin_pcmcia_cf_resources[] = {
                .start = 0x20311000, /* Attribute Memory */
                .end = 0x20311FFF,
                .flags = IORESOURCE_MEM,
-       }, {
-               .start = IRQ_PROG_INTA,
-               .end = IRQ_PROG_INTA,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
        }, {
                .start = IRQ_PF4,
                .end = IRQ_PF4,
@@ -96,14 +146,7 @@ static struct resource smc91x_resources[] = {
                .end = 0x20300300 + 16,
                .flags = IORESOURCE_MEM,
        }, {
-               .start = IRQ_PROG_INTB,
-               .end = IRQ_PROG_INTB,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       }, {
-               /*
-                *  denotes the flag pin and is used directly if
-                *  CONFIG_IRQCHIP_DEMUX_GPIO is defined.
-                */
+
                .start = IRQ_PF7,
                .end = IRQ_PF7,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
@@ -117,6 +160,28 @@ static struct platform_device smc91x_device = {
 };
 #endif
 
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource dm9000_resources[] = {
+       [0] = {
+               .start  = 0x203FB800,
+               .end    = 0x203FB800 + 8,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_PF9,
+               .end    = IRQ_PF9,
+               .flags  = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
+       },
+};
+
+static struct platform_device dm9000_device = {
+       .name           = "dm9000",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(dm9000_resources),
+       .resource       = dm9000_resources,
+};
+#endif
+
 #if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
 static struct resource sl811_hcd_resources[] = {
        {
@@ -128,12 +193,8 @@ static struct resource sl811_hcd_resources[] = {
                .end = 0x20340004,
                .flags = IORESOURCE_MEM,
        }, {
-               .start = IRQ_PROG_INTA,
-               .end = IRQ_PROG_INTA,
-               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       }, {
-               .start = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
-               .end = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO,
+               .start = CONFIG_USB_SL811_BFIN_IRQ,
+               .end = CONFIG_USB_SL811_BFIN_IRQ,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
        },
 };
@@ -141,21 +202,19 @@ static struct resource sl811_hcd_resources[] = {
 #if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
 void sl811_port_power(struct device *dev, int is_on)
 {
-       unsigned short mask = (1<<CONFIG_USB_SL811_BFIN_GPIO_VBUS);
-
-       bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask);
-       bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask);
+       gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
+       gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS);
 
        if (is_on)
-               bfin_write_FIO_FLAG_S(mask);
+               gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
        else
-               bfin_write_FIO_FLAG_C(mask);
+               gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
 }
 #endif
 
 static struct sl811_platform_data sl811_priv = {
        .potpg = 10,
-       .power = 250,           /* == 500mA */
+       .power = 250,       /* == 500mA */
 #if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
        .port_power = &sl811_port_power,
 #endif
@@ -170,7 +229,6 @@ static struct platform_device sl811_hcd_device = {
        .num_resources = ARRAY_SIZE(sl811_hcd_resources),
        .resource = sl811_hcd_resources,
 };
-
 #endif
 
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
@@ -184,13 +242,9 @@ static struct resource isp1362_hcd_resources[] = {
                .end = 0x20360004,
                .flags = IORESOURCE_MEM,
        }, {
-               .start = IRQ_PROG_INTA,
-               .end = IRQ_PROG_INTA,
+               .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+               .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-       }, {
-               .start = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
-               .end = IRQ_PF0 + CONFIG_USB_ISP1362_BFIN_GPIO,
-               .flags = IORESOURCE_IRQ,
        },
 };
 
@@ -246,7 +300,8 @@ static struct platform_device net2272_bfin_device = {
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 /* all SPI peripherals info goes here */
 
-#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+#if defined(CONFIG_MTD_M25P80) \
+       || defined(CONFIG_MTD_M25P80_MODULE)
 static struct mtd_partition bfin_spi_flash_partitions[] = {
        {
                .name = "bootloader",
@@ -302,70 +357,198 @@ static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
 };
 #endif
 
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+       .enable_dma = 1,
+       .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_PBX)
+static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
+       .ctl_reg        = 0x4, /* send zero */
+       .enable_dma     = 0,
+       .bits_per_word  = 8,
+       .cs_change_per_word = 1,
+};
+#endif
+
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+static struct bfin5xx_spi_chip ad5304_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+       .model                  = 7877,
+       .vref_delay_usecs       = 50,   /* internal, no capacitor */
+       .x_plate_ohms           = 419,
+       .y_plate_ohms           = 486,
+       .pressure_max           = 1000,
+       .pressure_min           = 0,
+       .stopacq_polarity       = 1,
+       .first_conversion_delay = 3,
+       .acquisition_time       = 1,
+       .averaging              = 1,
+       .pen_down_acc_interval  = 1,
+};
+#endif
+
 static struct spi_board_info bfin_spi_board_info[] __initdata = {
-#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+#if defined(CONFIG_MTD_M25P80) \
+       || defined(CONFIG_MTD_M25P80_MODULE)
        {
                /* the modalias must be the same as spi device driver name */
                .modalias = "m25p80", /* Name of spi_driver for this device */
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
-               .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+               .bus_num = 0, /* Framework bus number */
+               .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
                .platform_data = &bfin_spi_flash_data,
                .controller_data = &spi_flash_chip_info,
                .mode = SPI_MODE_3,
        },
 #endif
 
-#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE)
+#if defined(CONFIG_SPI_ADC_BF533) \
+       || defined(CONFIG_SPI_ADC_BF533_MODULE)
        {
                .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
                .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 1, /* Framework chip select. */
                .platform_data = NULL, /* No spi_driver specific config */
                .controller_data = &spi_adc_chip_info,
        },
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+       || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
        {
                .modalias = "ad1836-spi",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
 #endif
-
 #if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
        {
                .modalias = "ad9960-spi",
                .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = 1,
                .controller_data = &ad9960_spi_chip_info,
        },
 #endif
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+       {
+               .modalias = "spi_mmc_dummy",
+               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 0,
+               .platform_data = NULL,
+               .controller_data = &spi_mmc_chip_info,
+               .mode = SPI_MODE_3,
+       },
+       {
+               .modalias = "spi_mmc",
+               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = CONFIG_SPI_MMC_CS_CHAN,
+               .platform_data = NULL,
+               .controller_data = &spi_mmc_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+#if defined(CONFIG_PBX)
+       {
+               .modalias = "fxs-spi",
+               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 8 - CONFIG_J11_JUMPER,
+               .controller_data = &spi_si3xxx_chip_info,
+               .mode = SPI_MODE_3,
+       },
+       {
+               .modalias = "fxo-spi",
+               .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 8 - CONFIG_J19_JUMPER,
+               .controller_data = &spi_si3xxx_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+       {
+               .modalias = "ad5304_spi",
+               .max_speed_hz = 1250000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0,
+               .chip_select = 2,
+               .platform_data = NULL,
+               .controller_data = &ad5304_chip_info,
+               .mode = SPI_MODE_2,
+       },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+       {
+               .modalias               = "ad7877",
+               .platform_data          = &bfin_ad7877_ts_info,
+               .irq                    = IRQ_PF6,
+               .max_speed_hz   = 12500000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num        = 1,
+               .chip_select  = 1,
+               .controller_data = &spi_ad7877_chip_info,
+       },
+#endif
 };
 
 /* SPI controller data */
-static struct bfin5xx_spi_master spi_bfin_master_info = {
+static struct bfin5xx_spi_master bfin_spi0_info = {
        .num_chipselect = 8,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
 };
 
-static struct platform_device spi_bfin_master_device = {
-       .name = "bfin-spi-master",
-       .id = 1, /* Bus number */
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+               },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
        .dev = {
-               .platform_data = &spi_bfin_master_info, /* Passed to driver */
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
        },
 };
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
 static struct platform_device bfin_fb_device = {
-       .name = "bf537-fb",
+       .name = "bf537-lq035",
+};
+#endif
+
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+static struct platform_device bfin_fb_adv7393_device = {
+       .name = "bfin-adv7393",
 };
 #endif
 
@@ -390,15 +573,86 @@ static struct platform_device bfin_uart_device = {
 };
 #endif
 
-static struct platform_device *stamp_devices[] __initdata = {
-#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
-       &rtc_device,
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+       [0] = {
+               .start = TWI0_REGBASE,
+               .end   = TWI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TWI,
+               .end   = IRQ_TWI,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+       .name = "i2c-bfin-twi",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_twi0_resource),
+       .resource = bfin_twi0_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+       .name = "bfin-sport-uart",
+       .id = 1,
+};
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT       55
+
+static struct pata_platform_info bfin_pata_platform_data = {
+       .ioport_shift = 1,
+       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+       {
+               .start = 0x20314020,
+               .end = 0x2031403F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = 0x2031401C,
+               .end = 0x2031401F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = PATA_INT,
+               .end = PATA_INT,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pata_device = {
+       .name = "pata_platform",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pata_resources),
+       .resource = bfin_pata_resources,
+       .dev = {
+               .platform_data = &bfin_pata_platform_data,
+       }
+};
 #endif
 
+static struct platform_device *stamp_devices[] __initdata = {
 #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
        &bfin_pcmcia_cf_device,
 #endif
 
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+       &rtc_device,
+#endif
+
 #if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
        &sl811_hcd_device,
 #endif
@@ -411,6 +665,10 @@ static struct platform_device *stamp_devices[] __initdata = {
        &smc91x_device,
 #endif
 
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+       &dm9000_device,
+#endif
+
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
        &bfin_mac_device,
 #endif
@@ -420,16 +678,33 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       &spi_bfin_master_device,
+       &bfin_spi0_device,
 #endif
 
 #if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
        &bfin_fb_device,
 #endif
 
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+       &bfin_fb_adv7393_device,
+#endif
+
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
        &bfin_uart_device,
 #endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+       &i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+       &bfin_sport0_uart_device,
+       &bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       &bfin_pata_device,
+#endif
 };
 
 static int __init stamp_init(void)
@@ -437,9 +712,21 @@ static int __init stamp_init(void)
        printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
        platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+       spi_register_board_info(bfin_spi_board_info,
+                               ARRAY_SIZE(bfin_spi_board_info));
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
 #endif
        return 0;
 }
 
 arch_initcall(stamp_init);
+
+void native_machine_restart(char *cmd)
+{
+       /* workaround reboot hang when booting from SPI */
+       if ((bfin_read_SYSCR() & 0x7) == 0x3)
+               bfin_gpio_reset_spi0_ssel1();
+}
index 8806f1230f2da480c4a3b8e055466985fa0e4698..20507e92a3a4bfbd334d06eb324492c0bbd665cd 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/usb_isp1362.h>
 #endif
 #include <linux/irq.h>
+#include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 #include <linux/usb_sl811.h>
 
@@ -130,15 +131,13 @@ static struct resource sl811_hcd_resources[] = {
 #if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
 void sl811_port_power(struct device *dev, int is_on)
 {
-       unsigned short mask = (1 << CONFIG_USB_SL811_BFIN_GPIO_VBUS);
-
-       bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask);
-       bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask);
+       gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
+       gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS);
 
        if (is_on)
-               bfin_write_FIO_FLAG_S(mask);
+               gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
        else
-               bfin_write_FIO_FLAG_C(mask);
+               gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
 }
 #endif
 
@@ -323,7 +322,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                /* the modalias must be the same as spi device driver name */
                .modalias = "m25p80", /* Name of spi_driver for this device */
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
                .platform_data = &bfin_spi_flash_data,
                .controller_data = &spi_flash_chip_info,
@@ -336,7 +335,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
                .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 1, /* Framework chip select. */
                .platform_data = NULL, /* No spi_driver specific config */
                .controller_data = &spi_adc_chip_info,
@@ -348,7 +347,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad1836-spi",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
@@ -357,7 +356,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad9960-spi",
                .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = 1,
                .controller_data = &ad9960_spi_chip_info,
        },
@@ -366,7 +365,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "spi_mmc_dummy",
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = 7,
                .platform_data = NULL,
                .controller_data = &spi_mmc_chip_info,
@@ -375,7 +374,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "spi_mmc",
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SPI_MMC_CS_CHAN,
                .platform_data = NULL,
                .controller_data = &spi_mmc_chip_info,
@@ -396,24 +395,40 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 };
 
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+               },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
 /* SPI controller data */
-static struct bfin5xx_spi_master spi_bfin_master_info = {
+static struct bfin5xx_spi_master bfin_spi0_info = {
        .num_chipselect = 8,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
 };
 
-static struct platform_device spi_bfin_master_device = {
-       .name = "bfin-spi-master",
-       .id = 1, /* Bus number */
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
        .dev = {
-               .platform_data = &spi_bfin_master_info, /* Passed to driver */
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
        },
 };
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
 static struct platform_device bfin_fb_device = {
-       .name = "bf537-fb",
+       .name = "bf537-lq035",
 };
 #endif
 
@@ -469,7 +484,7 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       &spi_bfin_master_device,
+       &bfin_spi0_device,
 #endif
 
 #if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
index 9c43d775651088f219f948c80f0f9f9432014232..47d7d4a0e73dd1e2e3e2cf25264ed5ff9840ee49 100644 (file)
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb_isp1362.h>
 #endif
+#include <linux/pata_platform.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/usb_sl811.h>
+#include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
+#include <asm/reboot.h>
 #include <linux/spi/ad7877.h>
 
 /*
@@ -199,15 +202,13 @@ static struct resource sl811_hcd_resources[] = {
 #if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
 void sl811_port_power(struct device *dev, int is_on)
 {
-       unsigned short mask = (1 << CONFIG_USB_SL811_BFIN_GPIO_VBUS);
-
-       bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask);
-       bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask);
+       gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
+       gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS);
 
        if (is_on)
-               bfin_write_FIO_FLAG_S(mask);
+               gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
        else
-               bfin_write_FIO_FLAG_C(mask);
+               gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
 }
 #endif
 
@@ -407,7 +408,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                /* the modalias must be the same as spi device driver name */
                .modalias = "m25p80", /* Name of spi_driver for this device */
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
                .platform_data = &bfin_spi_flash_data,
                .controller_data = &spi_flash_chip_info,
@@ -420,7 +421,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
                .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 1, /* Framework chip select. */
                .platform_data = NULL, /* No spi_driver specific config */
                .controller_data = &spi_adc_chip_info,
@@ -432,7 +433,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad1836-spi",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
@@ -441,7 +442,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad9960-spi",
                .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = 1,
                .controller_data = &ad9960_spi_chip_info,
        },
@@ -450,7 +451,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "spi_mmc_dummy",
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = 0,
                .platform_data = NULL,
                .controller_data = &spi_mmc_chip_info,
@@ -459,7 +460,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "spi_mmc",
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SPI_MMC_CS_CHAN,
                .platform_data = NULL,
                .controller_data = &spi_mmc_chip_info,
@@ -470,16 +471,16 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "fxs-spi",
                .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
-               .chip_select = 3,
+               .bus_num = 0,
+               .chip_select = 8 - CONFIG_J11_JUMPER,
                .controller_data = &spi_si3xxx_chip_info,
                .mode = SPI_MODE_3,
        },
        {
                .modalias = "fxo-spi",
                .max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
-               .chip_select = 2,
+               .bus_num = 0,
+               .chip_select = 8 - CONFIG_J19_JUMPER,
                .controller_data = &spi_si3xxx_chip_info,
                .mode = SPI_MODE_3,
        },
@@ -488,7 +489,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad5304_spi",
                .max_speed_hz = 1250000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = 2,
                .platform_data = NULL,
                .controller_data = &ad5304_chip_info,
@@ -509,23 +510,45 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 };
 
 /* SPI controller data */
-static struct bfin5xx_spi_master spi_bfin_master_info = {
+static struct bfin5xx_spi_master bfin_spi0_info = {
        .num_chipselect = 8,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
 };
 
-static struct platform_device spi_bfin_master_device = {
-       .name = "bfin-spi-master",
-       .id = 1, /* Bus number */
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+               },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
        .dev = {
-               .platform_data = &spi_bfin_master_info, /* Passed to driver */
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
        },
 };
 #endif  /* spi master and devices */
 
 #if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
 static struct platform_device bfin_fb_device = {
-       .name = "bf537-fb",
+       .name = "bf537-lq035",
+};
+#endif
+
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+static struct platform_device bfin_fb_adv7393_device = {
+       .name = "bfin-adv7393",
 };
 #endif
 
@@ -551,9 +574,24 @@ static struct platform_device bfin_uart_device = {
 #endif
 
 #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+       [0] = {
+               .start = TWI0_REGBASE,
+               .end   = TWI0_REGBASE,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TWI,
+               .end   = IRQ_TWI,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
 static struct platform_device i2c_bfin_twi_device = {
        .name = "i2c-bfin-twi",
        .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_twi0_resource),
+       .resource = bfin_twi0_resource,
 };
 #endif
 
@@ -569,6 +607,43 @@ static struct platform_device bfin_sport1_uart_device = {
 };
 #endif
 
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT       55
+
+static struct pata_platform_info bfin_pata_platform_data = {
+       .ioport_shift = 1,
+       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+       {
+               .start = 0x20314020,
+               .end = 0x2031403F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = 0x2031401C,
+               .end = 0x2031401F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = PATA_INT,
+               .end = PATA_INT,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pata_device = {
+       .name = "pata_platform",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pata_resources),
+       .resource = bfin_pata_resources,
+       .dev = {
+               .platform_data = &bfin_pata_platform_data,
+       }
+};
+#endif
+
 static struct platform_device *stamp_devices[] __initdata = {
 #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
        &bfin_pcmcia_cf_device,
@@ -603,13 +678,17 @@ static struct platform_device *stamp_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       &spi_bfin_master_device,
+       &bfin_spi0_device,
 #endif
 
 #if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
        &bfin_fb_device,
 #endif
 
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+       &bfin_fb_adv7393_device,
+#endif
+
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
        &bfin_uart_device,
 #endif
@@ -622,6 +701,10 @@ static struct platform_device *stamp_devices[] __initdata = {
        &bfin_sport0_uart_device,
        &bfin_sport1_uart_device,
 #endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       &bfin_pata_device,
+#endif
 };
 
 static int __init stamp_init(void)
@@ -632,7 +715,18 @@ static int __init stamp_init(void)
        spi_register_board_info(bfin_spi_board_info,
                                ARRAY_SIZE(bfin_spi_board_info));
 #endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
        return 0;
 }
 
 arch_initcall(stamp_init);
+
+void native_machine_restart(char *cmd)
+{
+       /* workaround reboot hang when booting from SPI */
+       if ((bfin_read_SYSCR() & 0x7) == 0x3)
+               bfin_gpio_reset_spi0_ssel1();
+}
index 429c8a1019dab0de10bc9e7dfdc2f1392994cc42..3014fe8dd1556bf717421422873e1f7ead28ab04 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/trace.h>
 
 #if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach-common/clocks.h>
 #include <asm/mach/mem_init.h>
 #endif
 
@@ -50,10 +51,12 @@ __INIT
 ENTRY(__start)
        /* R0: argument of command line string, passed from uboot, save it */
        R7 = R0;
-       /* Set the SYSCFG register:
-        * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit)
-        */
-       R0 = 0x36;
+       /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+       R0 = SYSCFG_SNEN;
+#else
+       R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
        SYSCFG = R0;
        R0 = 0;
 
@@ -95,43 +98,43 @@ ENTRY(__start)
        M2 = r0;
        M3 = r0;
 
-       trace_buffer_start(p0,r0);
+       trace_buffer_init(p0,r0);
        P0 = R1;
        R0 = R1;
 
        /* Turn off the icache */
-       p0.l = (IMEM_CONTROL & 0xFFFF);
-       p0.h = (IMEM_CONTROL >> 16);
+       p0.l = LO(IMEM_CONTROL);
+       p0.h = HI(IMEM_CONTROL);
        R1 = [p0];
        R0 = ~ENICPLB;
        R0 = R0 & R1;
 
        /* Anomaly 05000125 */
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        CLI R2;
        SSYNC;
 #endif
        [p0] = R0;
        SSYNC;
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        STI R2;
 #endif
 
        /* Turn off the dcache */
-       p0.l = (DMEM_CONTROL & 0xFFFF);
-       p0.h = (DMEM_CONTROL >> 16);
+       p0.l = LO(DMEM_CONTROL);
+       p0.h = HI(DMEM_CONTROL);
        R1 = [p0];
        R0 = ~ENDCPLB;
        R0 = R0 & R1;
 
        /* Anomaly 05000125 */
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        CLI R2;
        SSYNC;
 #endif
        [p0] = R0;
        SSYNC;
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        STI R2;
 #endif
 
@@ -141,12 +144,12 @@ ENTRY(__start)
         */
        p0.h = hi(BFIN_PORT_MUX);
        p0.l = lo(BFIN_PORT_MUX);
-#ifdef ANOMALY_05000212
+#if ANOMALY_05000212
        R0.L = W[P0]; /* Read */
        SSYNC;
 #endif
        R0 = (PGDE_UART | PFTE_UART)(Z);
-#ifdef ANOMALY_05000212
+#if ANOMALY_05000212
        W[P0] = R0.L; /* Write */
        SSYNC;
 #endif
@@ -155,12 +158,12 @@ ENTRY(__start)
 
        p0.h = hi(PORTF_FER);
        p0.l = lo(PORTF_FER);
-#ifdef ANOMALY_05000212
+#if ANOMALY_05000212
        R0.L = W[P0]; /* Read */
        SSYNC;
 #endif
        R0 = 0x000F(Z);
-#ifdef ANOMALY_05000212
+#if ANOMALY_05000212
        W[P0] = R0.L; /* Write */
        SSYNC;
 #endif
@@ -221,6 +224,12 @@ ENTRY(__start)
        fp = sp;
        usp = sp;
 
+#ifdef CONFIG_EARLY_PRINTK
+       SP += -12;
+       call _init_early_exception_vectors;
+       SP += 12;
+#endif
+
        /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
        call _bf53x_relocate_l1_mem;
 #if CONFIG_BFIN_KERNEL_CLOCK
@@ -274,7 +283,7 @@ ENTRY(__start)
        p0.l = .LWAIT_HERE;
        p0.h = .LWAIT_HERE;
        reti = p0;
-#if defined(ANOMALY_05000281)
+#if ANOMALY_05000281
        nop; nop; nop;
 #endif
        rti;
@@ -436,8 +445,8 @@ ENTRY(_start_dma_code)
        w[p0] = r0.l;
        ssync;
 
-       p0.l = (EBIU_SDBCTL & 0xFFFF);
-       p0.h = (EBIU_SDBCTL >> 16);     /* SDRAM Memory Bank Control Register */
+       p0.l = LO(EBIU_SDBCTL);
+       p0.h = HI(EBIU_SDBCTL);     /* SDRAM Memory Bank Control Register */
        r0 = mem_SDBCTL;
        w[p0] = r0.l;
        ssync;
@@ -475,85 +484,6 @@ ENTRY(_start_dma_code)
 ENDPROC(_start_dma_code)
 #endif /* CONFIG_BFIN_KERNEL_CLOCK */
 
-ENTRY(_bfin_reset)
-       /* No more interrupts to be handled*/
-       CLI R6;
-       SSYNC;
-
-#if defined(CONFIG_MTD_M25P80)
-       /*
-        * The following code fix the SPI flash reboot issue,
-        * /CS signal of the chip which is using PF10 return to GPIO mode
-        */
-       p0.h = hi(PORTF_FER);
-       p0.l = lo(PORTF_FER);
-       r0.l = 0x0000;
-       w[p0] = r0.l;
-       SSYNC;
-
-       /* /CS return to high */
-       p0.h = hi(PORTFIO);
-       p0.l = lo(PORTFIO);
-       r0.l = 0xFFFF;
-       w[p0] = r0.l;
-       SSYNC;
-
-       /* Delay some time, This is necessary */
-       r1.h = 0;
-       r1.l = 0x400;
-       p1   = r1;
-       lsetup (.L_delay_lab1, .L_delay_lab1_end) lc1 = p1;
-.L_delay_lab1:
-       r0.h = 0;
-       r0.l = 0x8000;
-       p0   = r0;
-       lsetup (.L_delay_lab0, .L_delay_lab0_end) lc0 = p0;
-.L_delay_lab0:
-       nop;
-.L_delay_lab0_end:
-       nop;
-.L_delay_lab1_end:
-       nop;
-#endif
-
-       /* Clear the IMASK register */
-       p0.h = hi(IMASK);
-       p0.l = lo(IMASK);
-       r0 = 0x0;
-       [p0] = r0;
-
-       /* Clear the ILAT register */
-       p0.h = hi(ILAT);
-       p0.l = lo(ILAT);
-       r0 = [p0];
-       [p0] = r0;
-       SSYNC;
-
-       /* make sure SYSCR is set to use BMODE */
-       P0.h = hi(SYSCR);
-       P0.l = lo(SYSCR);
-       R0.l = 0x0;
-       W[P0] = R0.l;
-       SSYNC;
-
-       /* issue a system soft reset */
-       P1.h = hi(SWRST);
-       P1.l = lo(SWRST);
-       R1.l = 0x0007;
-       W[P1] = R1;
-       SSYNC;
-
-       /* clear system soft reset */
-       R0.l = 0x0000;
-       W[P0] = R0;
-       SSYNC;
-
-       /* issue core reset */
-       raise 1;
-
-       RTS;
-ENDPROC(_bfin_reset)
-
 .data
 
 /*
index e78b03d56c7c9ad3c7c9db4335acd10d423f3d89..08d8dc83701c3e7cb3d279f757358155fba662f7 100644 (file)
@@ -2,6 +2,13 @@ if (BF54x)
 
 menu "BF548 Specific Configuration"
 
+config DEB_DMA_URGENT
+       bool "DMA has priority over core for ext. accesses"
+       depends on BF54x
+       default n
+       help
+         Treat any DEB1, DEB2 and DEB3 request as Urgent
+
 comment "Interrupt Priority Assignment"
 menu "Priority"
 
@@ -282,7 +289,7 @@ menu "Assignment"
 
 config PINTx_REASSIGN
        bool "Reprogram PINT Assignment"
-       default n
+       default y
        help
          The interrupt assignment registers controls the pin-to-interrupt
          assignment in a byte-wide manner. Each option allows you to select
@@ -303,7 +310,7 @@ config PINT1_ASSIGN
 config PINT2_ASSIGN
        hex "PINT2_ASSIGN"
        depends on PINTx_REASSIGN
-       default 0x00000101
+       default 0x07000101
 config PINT3_ASSIGN
        hex "PINT3_ASSIGN"
        depends on PINTx_REASSIGN
index 060ad78ebf1db5fc7898e25ba18b2265241124d3..7e7c9c8ac5b263ac02f3aaa58ff349ed3060ee55 100644 (file)
@@ -4,6 +4,6 @@
 
 extra-y := head.o
 
-obj-y := ints-priority.o dma.o gpio.o
+obj-y := ints-priority.o dma.o
 
 obj-$(CONFIG_CPU_FREQ)   += cpu.o
index 96ad95fab1a8b78169aef06ee20c9e9e32f943d9..2c47db494f7de50cef4858d1ee4394ec2852031a 100644 (file)
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/irq.h>
-#include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/usb/musb.h>
 #include <asm/bfin5xx_spi.h>
+#include <asm/cplb.h>
+#include <asm/dma.h>
+#include <asm/gpio.h>
+#include <asm/nand.h>
+#include <asm/mach/bf54x_keys.h>
+#include <linux/input.h>
+#include <linux/spi/ad7877.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -48,6 +55,88 @@ char *bfin_board_name = "ADSP-BF548-EZKIT";
  *  Driver needs to know address, irq and flag pin.
  */
 
+#if defined(CONFIG_FB_BF54X_LQ043) || defined(CONFIG_FB_BF54X_LQ043_MODULE)
+
+#include <asm/mach/bf54x-lq043.h>
+
+static struct bfin_bf54xfb_mach_info bf54x_lq043_data = {
+       .width =        480,
+       .height =       272,
+       .xres =         {480, 480, 480},
+       .yres =         {272, 272, 272},
+       .bpp =          {24, 24, 24},
+       .disp =         GPIO_PE3,
+};
+
+static struct resource bf54x_lq043_resources[] = {
+       {
+               .start = IRQ_EPPI0_ERR,
+               .end = IRQ_EPPI0_ERR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bf54x_lq043_device = {
+       .name           = "bf54x-lq043",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(bf54x_lq043_resources),
+       .resource       = bf54x_lq043_resources,
+       .dev            = {
+               .platform_data = &bf54x_lq043_data,
+       },
+};
+#endif
+
+#if defined(CONFIG_KEYBOARD_BFIN) || defined(CONFIG_KEYBOARD_BFIN_MODULE)
+static int bf548_keymap[] = {
+       KEYVAL(0, 0, KEY_ENTER),
+       KEYVAL(0, 1, KEY_HELP),
+       KEYVAL(0, 2, KEY_0),
+       KEYVAL(0, 3, KEY_BACKSPACE),
+       KEYVAL(1, 0, KEY_TAB),
+       KEYVAL(1, 1, KEY_9),
+       KEYVAL(1, 2, KEY_8),
+       KEYVAL(1, 3, KEY_7),
+       KEYVAL(2, 0, KEY_DOWN),
+       KEYVAL(2, 1, KEY_6),
+       KEYVAL(2, 2, KEY_5),
+       KEYVAL(2, 3, KEY_4),
+       KEYVAL(3, 0, KEY_UP),
+       KEYVAL(3, 1, KEY_3),
+       KEYVAL(3, 2, KEY_2),
+       KEYVAL(3, 3, KEY_1),
+};
+
+static struct bfin_kpad_platform_data bf54x_kpad_data = {
+       .rows                   = 4,
+       .cols                   = 4,
+       .keymap                 = bf548_keymap,
+       .keymapsize             = ARRAY_SIZE(bf548_keymap),
+       .repeat                 = 0,
+       .debounce_time          = 5000, /* ns (5ms) */
+       .coldrive_time          = 1000, /* ns (1ms) */
+       .keyup_test_interval    = 50, /* ms (50ms) */
+};
+
+static struct resource bf54x_kpad_resources[] = {
+       {
+               .start = IRQ_KEY,
+               .end = IRQ_KEY,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bf54x_kpad_device = {
+       .name           = "bf54x-keys",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(bf54x_kpad_resources),
+       .resource       = bf54x_kpad_resources,
+       .dev            = {
+               .platform_data = &bf54x_kpad_data,
+       },
+};
+#endif
+
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 static struct platform_device rtc_device = {
        .name = "rtc-bfin",
@@ -94,6 +183,344 @@ static struct platform_device bfin_uart_device = {
 };
 #endif
 
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct resource smsc911x_resources[] = {
+       {
+               .name = "smsc911x-memory",
+               .start = 0x24000000,
+               .end = 0x24000000 + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_PE8,
+               .end = IRQ_PE8,
+               .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+       },
+};
+static struct platform_device smsc911x_device = {
+       .name = "smsc911x",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(smsc911x_resources),
+       .resource = smsc911x_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_BF54x_HCD) || defined(CONFIG_USB_BF54x_HCD_MODULE)
+static struct resource bf54x_hcd_resources[] = {
+       {
+               .start = 0xFFC03C00,
+               .end = 0xFFC040FF,
+               .flags = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device bf54x_hcd = {
+       .name = "bf54x-hcd",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bf54x_hcd_resources),
+       .resource = bf54x_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
+static struct resource musb_resources[] = {
+       [0] = {
+               .start  = 0xFFC03C00,
+               .end    = 0xFFC040FF,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = { /* general IRQ */
+               .start  = IRQ_USB_INT0,
+               .end    = IRQ_USB_INT0,
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+       [2] = { /* DMA IRQ */
+               .start  = IRQ_USB_DMA,
+               .end    = IRQ_USB_DMA,
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+       },
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#ifdef CONFIG_USB_MUSB_OTG
+       .mode           = MUSB_OTG,
+#elif CONFIG_USB_MUSB_HDRC_HCD
+       .mode           = MUSB_HOST,
+#elif CONFIG_USB_GADGET_MUSB_HDRC
+       .mode           = MUSB_PERIPHERAL,
+#endif
+       .multipoint     = 1,
+};
+
+static u64 musb_dmamask = ~(u32)0;
+
+static struct platform_device musb_device = {
+       .name           = "musb_hdrc",
+       .id             = 0,
+       .dev = {
+               .dma_mask               = &musb_dmamask,
+               .coherent_dma_mask      = 0xffffffff,
+               .platform_data          = &musb_plat,
+       },
+       .num_resources  = ARRAY_SIZE(musb_resources),
+       .resource       = musb_resources,
+};
+#endif
+
+#if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
+static struct resource bfin_atapi_resources[] = {
+       {
+               .start = 0xFFC03800,
+               .end = 0xFFC0386F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = IRQ_ATAPI_ERR,
+               .end = IRQ_ATAPI_ERR,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_atapi_device = {
+       .name = "pata-bf54x",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_atapi_resources),
+       .resource = bfin_atapi_resources,
+};
+#endif
+
+#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
+static struct mtd_partition partition_info[] = {
+       {
+               .name = "Linux Kernel",
+               .offset = 0,
+               .size = 4 * SIZE_1M,
+       },
+       {
+               .name = "File System",
+               .offset = 4 * SIZE_1M,
+               .size = (256 - 4) * SIZE_1M,
+       },
+};
+
+static struct bf5xx_nand_platform bf5xx_nand_platform = {
+       .page_size = NFC_PG_SIZE_256,
+       .data_width = NFC_NWIDTH_8,
+       .partitions = partition_info,
+       .nr_partitions = ARRAY_SIZE(partition_info),
+       .rd_dly = 3,
+       .wr_dly = 3,
+};
+
+static struct resource bf5xx_nand_resources[] = {
+       {
+               .start = 0xFFC03B00,
+               .end = 0xFFC03B4F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = CH_NFC,
+               .end = CH_NFC,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bf5xx_nand_device = {
+       .name = "bf5xx-nand",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bf5xx_nand_resources),
+       .resource = bf5xx_nand_resources,
+       .dev = {
+               .platform_data = &bf5xx_nand_platform,
+       },
+};
+#endif
+
+#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN)
+static struct platform_device bf54x_sdh_device = {
+       .name = "bfin-sdh",
+       .id = 0,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+#if defined(CONFIG_MTD_M25P80) \
+       || defined(CONFIG_MTD_M25P80_MODULE)
+/* SPI flash chip (m25p16) */
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+       {
+               .name = "bootloader",
+               .size = 0x00040000,
+               .offset = 0,
+               .mask_flags = MTD_CAP_ROM
+       }, {
+               .name = "linux kernel",
+               .size = 0x1c0000,
+               .offset = 0x40000
+       }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+       .name = "m25p80",
+       .parts = bfin_spi_flash_partitions,
+       .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+       .type = "m25p16",
+};
+
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+       .enable_dma = 0,         /* use dma transfer with this chip*/
+       .bits_per_word = 8,
+       .cs_change_per_word = 0,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+       .cs_change_per_word = 1,
+       .enable_dma = 0,
+       .bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+       .model                  = 7877,
+       .vref_delay_usecs       = 50,   /* internal, no capacitor */
+       .x_plate_ohms           = 419,
+       .y_plate_ohms           = 486,
+       .pressure_max           = 1000,
+       .pressure_min           = 0,
+       .stopacq_polarity       = 1,
+       .first_conversion_delay = 3,
+       .acquisition_time       = 1,
+       .averaging              = 1,
+       .pen_down_acc_interval  = 1,
+};
+#endif
+
+static struct spi_board_info bf54x_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+       || defined(CONFIG_MTD_M25P80_MODULE)
+       {
+               /* the modalias must be the same as spi device driver name */
+               .modalias = "m25p80", /* Name of spi_driver for this device */
+               .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+               .bus_num = 0, /* Framework bus number */
+               .chip_select = 1, /* SPI_SSEL1*/
+               .platform_data = &bfin_spi_flash_data,
+               .controller_data = &spi_flash_chip_info,
+               .mode = SPI_MODE_3,
+       },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+{
+       .modalias               = "ad7877",
+       .platform_data          = &bfin_ad7877_ts_info,
+       .irq                    = IRQ_PJ11,
+       .max_speed_hz           = 12500000,     /* max spi clock (SCK) speed in HZ */
+       .bus_num                = 0,
+       .chip_select            = 2,
+       .controller_data = &spi_ad7877_chip_info,
+},
+#endif
+};
+
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = CH_SPI0,
+               .end   = CH_SPI0,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+/* SPI (1) */
+static struct resource bfin_spi1_resource[] = {
+       [0] = {
+               .start = SPI1_REGBASE,
+               .end   = SPI1_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = CH_SPI1,
+               .end   = CH_SPI1,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master bf54x_spi_master_info = {
+       .num_chipselect = 8,
+       .enable_dma = 1,  /* master has the ability to do dma transfer */
+};
+
+static struct platform_device bf54x_spi_master0 = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
+       .dev = {
+               .platform_data = &bf54x_spi_master_info, /* Passed to driver */
+               },
+};
+
+static struct platform_device bf54x_spi_master1 = {
+       .name = "bfin-spi",
+       .id = 1, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi1_resource),
+       .resource = bfin_spi1_resource,
+       .dev = {
+               .platform_data = &bf54x_spi_master_info, /* Passed to driver */
+               },
+};
+#endif  /* spi master and devices */
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+       [0] = {
+               .start = TWI0_REGBASE,
+               .end   = TWI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TWI0,
+               .end   = IRQ_TWI0,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device i2c_bfin_twi0_device = {
+       .name = "i2c-bfin-twi",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(bfin_twi0_resource),
+       .resource = bfin_twi0_resource,
+};
+
+static struct resource bfin_twi1_resource[] = {
+       [0] = {
+               .start = TWI1_REGBASE,
+               .end   = TWI1_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TWI1,
+               .end   = IRQ_TWI1,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device i2c_bfin_twi1_device = {
+       .name = "i2c-bfin-twi",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(bfin_twi1_resource),
+       .resource = bfin_twi1_resource,
+};
+#endif
+
 static struct platform_device *ezkit_devices[] __initdata = {
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
        &rtc_device,
@@ -102,12 +529,60 @@ static struct platform_device *ezkit_devices[] __initdata = {
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
        &bfin_uart_device,
 #endif
+
+#if defined(CONFIG_FB_BF54X_LQ043) || defined(CONFIG_FB_BF54X_LQ043_MODULE)
+       &bf54x_lq043_device,
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+       &smsc911x_device,
+#endif
+
+#if defined(CONFIG_USB_BF54x_HCD) || defined(CONFIG_USB_BF54x_HCD_MODULE)
+       &bf54x_hcd,
+#endif
+
+#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
+       &musb_device,
+#endif
+
+#if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
+       &bfin_atapi_device,
+#endif
+
+#if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
+       &bf5xx_nand_device,
+#endif
+
+#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN)
+       &bf54x_sdh_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+       &bf54x_spi_master0,
+/*     &bf54x_spi_master1,*/
+#endif
+
+#if defined(CONFIG_KEYBOARD_BFIN) || defined(CONFIG_KEYBOARD_BFIN_MODULE)
+       &bf54x_kpad_device,
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+       &i2c_bfin_twi0_device,
+       &i2c_bfin_twi1_device,
+#endif
 };
 
 static int __init stamp_init(void)
 {
        printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
        platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices));
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+       spi_register_board_info(bf54x_spi_board_info,
+                       ARRAY_SIZE(bf54x_spi_board_info));
+#endif
+
        return 0;
 }
 
diff --git a/arch/blackfin/mach-bf548/gpio.c b/arch/blackfin/mach-bf548/gpio.c
deleted file mode 100644 (file)
index 0da5f00..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * File:         arch/blackfin/mach-bf548/gpio.c
- * Based on:
- * Author:       Michael Hennerich (hennerich@blackfin.uclinux.org)
- *
- * Created:
- * Description:  GPIO Abstraction Layer
- *
- * Modified:
- *               Copyright 2007 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/module.h>
-#include <linux/err.h>
-#include <asm/blackfin.h>
-#include <asm/gpio.h>
-#include <asm/portmux.h>
-#include <linux/irq.h>
-
-static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
-       (struct gpio_port_t *)PORTA_FER,
-       (struct gpio_port_t *)PORTB_FER,
-       (struct gpio_port_t *)PORTC_FER,
-       (struct gpio_port_t *)PORTD_FER,
-       (struct gpio_port_t *)PORTE_FER,
-       (struct gpio_port_t *)PORTF_FER,
-       (struct gpio_port_t *)PORTG_FER,
-       (struct gpio_port_t *)PORTH_FER,
-       (struct gpio_port_t *)PORTI_FER,
-       (struct gpio_port_t *)PORTJ_FER,
-};
-
-static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
-static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
-
-inline int check_gpio(unsigned short gpio)
-{
-       if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
-           || gpio == GPIO_PH14 || gpio == GPIO_PH15
-           || gpio == GPIO_PJ14 || gpio == GPIO_PJ15
-           || gpio > MAX_BLACKFIN_GPIOS)
-               return -EINVAL;
-       return 0;
-}
-
-inline void portmux_setup(unsigned short portno, unsigned short function)
-{
-       u32 pmux;
-
-       pmux = gpio_array[gpio_bank(portno)]->port_mux;
-
-       pmux &= ~(0x3 << (2 * gpio_sub_n(portno)));
-       pmux |= (function & 0x3) << (2 * gpio_sub_n(portno));
-
-       gpio_array[gpio_bank(portno)]->port_mux = pmux;
-
-}
-
-inline u16 get_portmux(unsigned short portno)
-{
-       u32 pmux;
-
-       pmux = gpio_array[gpio_bank(portno)]->port_mux;
-
-       return (pmux >> (2 * gpio_sub_n(portno)) & 0x3);
-
-}
-
-static void port_setup(unsigned short gpio, unsigned short usage)
-{
-       if (usage == GPIO_USAGE) {
-               if (gpio_array[gpio_bank(gpio)]->port_fer & gpio_bit(gpio))
-                       printk(KERN_WARNING
-                              "bfin-gpio: Possible Conflict with Peripheral "
-                              "usage and GPIO %d detected!\n", gpio);
-               gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
-       } else
-               gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
-       SSYNC();
-}
-
-static int __init bfin_gpio_init(void)
-{
-       printk(KERN_INFO "Blackfin GPIO Controller\n");
-
-       return 0;
-}
-
-arch_initcall(bfin_gpio_init);
-
-int peripheral_request(unsigned short per, const char *label)
-{
-       unsigned long flags;
-       unsigned short ident = P_IDENT(per);
-
-       if (!(per & P_DEFINED))
-               return -ENODEV;
-
-       if (check_gpio(ident) < 0)
-               return -EINVAL;
-
-       local_irq_save(flags);
-
-       if (unlikely(reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
-               printk(KERN_ERR
-                      "%s: Peripheral %d is already reserved as GPIO!\n",
-                      __FUNCTION__, per);
-               dump_stack();
-               local_irq_restore(flags);
-               return -EBUSY;
-       }
-
-       if (unlikely(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident))) {
-
-               u16 funct = get_portmux(ident);
-
-               if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) {
-                       printk(KERN_ERR
-                              "%s: Peripheral %d is already reserved!\n",
-                              __FUNCTION__, per);
-                       dump_stack();
-                       local_irq_restore(flags);
-                       return -EBUSY;
-               }
-       }
-
-       reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident);
-
-       portmux_setup(ident, P_FUNCT2MUX(per));
-       port_setup(ident, PERIPHERAL_USAGE);
-
-       local_irq_restore(flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(peripheral_request);
-
-int peripheral_request_list(unsigned short per[], const char *label)
-{
-
-       u16 cnt;
-       int ret;
-
-       for (cnt = 0; per[cnt] != 0; cnt++) {
-               ret = peripheral_request(per[cnt], label);
-               if (ret < 0)
-                       return ret;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(peripheral_request_list);
-
-void peripheral_free(unsigned short per)
-{
-       unsigned long flags;
-       unsigned short ident = P_IDENT(per);
-
-       if (!(per & P_DEFINED))
-               return;
-
-       if (check_gpio(ident) < 0)
-               return;
-
-       local_irq_save(flags);
-
-       if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) {
-               printk(KERN_ERR "bfin-gpio: Peripheral %d wasn't reserved!\n", per);
-               dump_stack();
-               local_irq_restore(flags);
-               return;
-       }
-
-       if (!(per & P_MAYSHARE)) {
-               port_setup(ident, GPIO_USAGE);
-       }
-
-       reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident);
-
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL(peripheral_free);
-
-void peripheral_free_list(unsigned short per[])
-{
-       u16 cnt;
-
-       for (cnt = 0; per[cnt] != 0; cnt++) {
-               peripheral_free(per[cnt]);
-       }
-
-}
-EXPORT_SYMBOL(peripheral_free_list);
-
-/***********************************************************
-*
-* FUNCTIONS: Blackfin GPIO Driver
-*
-* INPUTS/OUTPUTS:
-* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
-*
-*
-* DESCRIPTION: Blackfin GPIO Driver API
-*
-* CAUTION:
-*************************************************************
-* MODIFICATION HISTORY :
-**************************************************************/
-
-int gpio_request(unsigned short gpio, const char *label)
-{
-       unsigned long flags;
-
-       if (check_gpio(gpio) < 0)
-               return -EINVAL;
-
-       local_irq_save(flags);
-
-       if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-               printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio);
-               dump_stack();
-               local_irq_restore(flags);
-               return -EBUSY;
-       }
-
-       if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
-               printk(KERN_ERR
-                      "bfin-gpio: GPIO %d is already reserved as Peripheral!\n", gpio);
-               dump_stack();
-               local_irq_restore(flags);
-               return -EBUSY;
-       }
-
-       reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
-
-       local_irq_restore(flags);
-
-       port_setup(gpio, GPIO_USAGE);
-
-       return 0;
-}
-EXPORT_SYMBOL(gpio_request);
-
-void gpio_free(unsigned short gpio)
-{
-       unsigned long flags;
-
-       if (check_gpio(gpio) < 0)
-               return;
-
-       local_irq_save(flags);
-
-       if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
-               printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio);
-               dump_stack();
-               local_irq_restore(flags);
-               return;
-       }
-
-       reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
-
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL(gpio_free);
-
-void gpio_direction_input(unsigned short gpio)
-{
-       unsigned long flags;
-
-       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
-
-       local_irq_save(flags);
-       gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
-       gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL(gpio_direction_input);
-
-void gpio_direction_output(unsigned short gpio)
-{
-       unsigned long flags;
-
-       BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
-
-       local_irq_save(flags);
-       gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
-       gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
-       local_irq_restore(flags);
-}
-EXPORT_SYMBOL(gpio_direction_output);
-
-void gpio_set_value(unsigned short gpio, unsigned short arg)
-{
-       if (arg)
-               gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
-       else
-               gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio);
-
-}
-EXPORT_SYMBOL(gpio_set_value);
-
-unsigned short gpio_get_value(unsigned short gpio)
-{
-       return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio)));
-}
-EXPORT_SYMBOL(gpio_get_value);
index 06751ae8b85704335d279127bd184bf42f5945b4..3071c243d42672147e83bfe415ca602c5e2acbb9 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/blackfin.h>
 #include <asm/trace.h>
 #if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach-common/clocks.h>
 #include <asm/mach/mem_init.h>
 #endif
 
@@ -49,9 +50,13 @@ ENTRY(__start)
 ENTRY(__stext)
        /* R0: argument of command line string, passed from uboot, save it */
        R7 = R0;
-       /* Set the SYSCFG register */
-       R0 = 0x36;
-       SYSCFG = R0;   /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
+       /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+       R0 = SYSCFG_SNEN;
+#else
+       R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
+       SYSCFG = R0;
        R0 = 0;
 
        /* Clear Out All the data and pointer  Registers*/
@@ -92,13 +97,13 @@ ENTRY(__stext)
        M2 = r0;
        M3 = r0;
 
-       trace_buffer_start(p0,r0);
+       trace_buffer_init(p0,r0);
        P0 = R1;
        R0 = R1;
 
        /* Turn off the icache */
-       p0.l = (IMEM_CONTROL & 0xFFFF);
-       p0.h = (IMEM_CONTROL >> 16);
+       p0.l = LO(IMEM_CONTROL);
+       p0.h = HI(IMEM_CONTROL);
        R1 = [p0];
        R0 = ~ENICPLB;
        R0 = R0 & R1;
@@ -106,8 +111,8 @@ ENTRY(__stext)
        SSYNC;
 
        /* Turn off the dcache */
-       p0.l = (DMEM_CONTROL & 0xFFFF);
-       p0.h = (DMEM_CONTROL >> 16);
+       p0.l = LO(DMEM_CONTROL);
+       p0.h = HI(DMEM_CONTROL);
        R1 = [p0];
        R0 = ~ENDCPLB;
        R0 = R0 & R1;
@@ -120,6 +125,12 @@ ENTRY(__stext)
        FP = SP;
        USP = SP;
 
+#ifdef CONFIG_EARLY_PRINTK
+       SP += -12;
+       call _init_early_exception_vectors;
+       SP += 12;
+#endif
+
        /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
        call _bf53x_relocate_l1_mem;
 #if CONFIG_BFIN_KERNEL_CLOCK
@@ -172,7 +183,7 @@ ENTRY(__stext)
        p0.l = .LWAIT_HERE;
        p0.h = .LWAIT_HERE;
        reti = p0;
-#if defined (ANOMALY_05000281)
+#if ANOMALY_05000281
        nop;
        nop;
        nop;
@@ -335,8 +346,8 @@ ENTRY(_start_dma_code)
        w[p0] = r0.l;
        ssync;
 
-       p0.l = (EBIU_SDBCTL & 0xFFFF);
-       p0.h = (EBIU_SDBCTL >> 16);     /* SDRAM Memory Bank Control Register */
+       p0.l = LO(EBIU_SDBCTL);
+       p0.h = HI(EBIU_SDBCTL);     /* SDRAM Memory Bank Control Register */
        r0 = mem_SDBCTL;
        w[p0] = r0.l;
        ssync;
@@ -373,129 +384,6 @@ ENTRY(_start_dma_code)
        RTS;
 #endif /* CONFIG_BFIN_KERNEL_CLOCK */
 
-ENTRY(_bfin_reset)
-       /* No more interrupts to be handled*/
-       CLI R6;
-       SSYNC;
-
-#if defined(CONFIG_MTD_M25P80)
-/*
- * The following code fix the SPI flash reboot issue,
- * /CS signal of the chip which is using PF10 return to GPIO mode
- */
-       p0.h = hi(PORTF_FER);
-       p0.l = lo(PORTF_FER);
-       r0.l = 0x0000;
-       w[p0] = r0.l;
-       SSYNC;
-
-/* /CS return to high */
-       p0.h = hi(PORTFIO);
-       p0.l = lo(PORTFIO);
-       r0.l = 0xFFFF;
-       w[p0] = r0.l;
-       SSYNC;
-
-/* Delay some time, This is necessary */
-       r1.h = 0;
-       r1.l = 0x400;
-       p1   = r1;
-       lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1;
-_delay_lab1:
-       r0.h = 0;
-       r0.l = 0x8000;
-       p0   = r0;
-       lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0;
-_delay_lab0:
-       nop;
-_delay_lab0_end:
-       nop;
-_delay_lab1_end:
-       nop;
-#endif
-
-       /* Clear the bits 13-15 in SWRST if they werent cleared */
-       p0.h = hi(SWRST);
-       p0.l = lo(SWRST);
-       csync;
-       r0.l = w[p0];
-
-       /* Clear the IMASK register */
-       p0.h = hi(IMASK);
-       p0.l = lo(IMASK);
-       r0 = 0x0;
-       [p0] = r0;
-
-       /* Clear the ILAT register */
-       p0.h = hi(ILAT);
-       p0.l = lo(ILAT);
-       r0 = [p0];
-       [p0] = r0;
-       SSYNC;
-
-       /* Disable the WDOG TIMER */
-       p0.h = hi(WDOG_CTL);
-       p0.l = lo(WDOG_CTL);
-       r0.l = 0xAD6;
-       w[p0] = r0.l;
-       SSYNC;
-
-       /* Clear the sticky bit incase it is already set */
-       p0.h = hi(WDOG_CTL);
-       p0.l = lo(WDOG_CTL);
-       r0.l = 0x8AD6;
-       w[p0] = r0.l;
-       SSYNC;
-
-       /* Program the count value */
-       R0.l = 0x100;
-       R0.h = 0x0;
-       P0.h = hi(WDOG_CNT);
-       P0.l = lo(WDOG_CNT);
-       [P0] = R0;
-       SSYNC;
-
-       /* Program WDOG_STAT if necessary */
-       P0.h = hi(WDOG_CTL);
-       P0.l = lo(WDOG_CTL);
-       R0 = W[P0](Z);
-       CC = BITTST(R0,1);
-       if !CC JUMP .LWRITESTAT;
-       CC = BITTST(R0,2);
-       if !CC JUMP .LWRITESTAT;
-       JUMP .LSKIP_WRITE;
-
-.LWRITESTAT:
-       /* When watch dog timer is enabled,
-        * a write to STAT will load the contents of CNT to STAT
-        */
-       R0 = 0x0000(z);
-       P0.h = hi(WDOG_STAT);
-       P0.l = lo(WDOG_STAT)
-       [P0] = R0;
-       SSYNC;
-
-.LSKIP_WRITE:
-       /* Enable the reset event */
-       P0.h = hi(WDOG_CTL);
-       P0.l = lo(WDOG_CTL);
-       R0 = W[P0](Z);
-       BITCLR(R0,1);
-       BITCLR(R0,2);
-       W[P0] = R0.L;
-       SSYNC;
-       NOP;
-
-       /* Enable the wdog counter */
-       R0 = W[P0](Z);
-       BITCLR(R0,4);
-       W[P0] = R0.L;
-       SSYNC;
-
-       IDLE;
-
-       RTS;
-
 .data
 
 /*
index 5b2b544529a19c49a919f0fb2e57f6b55f9c3eb3..cd827a1b6ba139e37604fa8e148836911dc8d7a2 100644 (file)
@@ -34,7 +34,9 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/usb_isp1362.h>
+#include <linux/pata_platform.h>
 #include <linux/irq.h>
+#include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -112,7 +114,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
                /* the modalias must be the same as spi device driver name */
                .modalias = "m25p80", /* Name of spi_driver for this device */
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
                .platform_data = &bfin_spi_flash_data,
                .controller_data = &spi_flash_chip_info,
@@ -124,7 +126,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
                .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1, /* Framework bus number */
+               .bus_num = 0, /* Framework bus number */
                .chip_select = 1, /* Framework chip select. */
                .platform_data = NULL, /* No spi_driver specific config */
                .controller_data = &spi_adc_chip_info,
@@ -135,7 +137,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad1836-spi",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
@@ -144,7 +146,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad9960-spi",
                .max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = 1,
                .controller_data = &ad9960_spi_chip_info,
        },
@@ -153,7 +155,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "spi_mmc",
                .max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SPI_MMC_CS_CHAN,
                .platform_data = NULL,
                .controller_data = &spi_mmc_chip_info,
@@ -162,17 +164,33 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #endif
 };
 
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
 /* SPI controller data */
-static struct bfin5xx_spi_master spi_bfin_master_info = {
+static struct bfin5xx_spi_master bfin_spi0_info = {
        .num_chipselect = 8,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
 };
 
-static struct platform_device spi_bfin_master_device = {
-       .name = "bfin-spi-master",
-       .id = 1, /* Bus number */
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
        .dev = {
-               .platform_data = &spi_bfin_master_info, /* Passed to driver */
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
        },
 };
 #endif  /* spi master and devices */
@@ -256,6 +274,43 @@ static struct platform_device bfin_uart_device = {
 };
 #endif
 
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT       119
+
+static struct pata_platform_info bfin_pata_platform_data = {
+       .ioport_shift = 2,
+       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+       {
+               .start = 0x2400C000,
+               .end = 0x2400C001F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = 0x2400D018,
+               .end = 0x2400D01B,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = PATA_INT,
+               .end = PATA_INT,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pata_device = {
+       .name = "pata_platform",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pata_resources),
+       .resource = bfin_pata_resources,
+       .dev = {
+               .platform_data = &bfin_pata_platform_data,
+       }
+};
+#endif
+
 static struct platform_device *cm_bf561_devices[] __initdata = {
 
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
@@ -271,9 +326,12 @@ static struct platform_device *cm_bf561_devices[] __initdata = {
 #endif
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       &spi_bfin_master_device,
+       &bfin_spi0_device,
 #endif
 
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       &bfin_pata_device,
+#endif
 };
 
 static int __init cm_bf561_init(void)
@@ -283,6 +341,10 @@ static int __init cm_bf561_init(void)
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
        spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 #endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
        return 0;
 }
 
index 724191da20a249a8f1f66c60cfba7b190f5f6074..57e14edca8b1bb75f38c486e19ebeebb9b104344 100644 (file)
@@ -32,6 +32,8 @@
 #include <linux/spi/spi.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/pata_platform.h>
+#include <asm/dma.h>
 #include <asm/bfin5xx_spi.h>
 
 /*
@@ -140,17 +142,33 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 #endif
 #endif
 
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+       [0] = {
+               .start = SPI0_REGBASE,
+               .end   = SPI0_REGBASE + 0xFF,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = CH_SPI,
+               .end   = CH_SPI,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
 /* SPI controller data */
-static struct bfin5xx_spi_master spi_bfin_master_info = {
+static struct bfin5xx_spi_master bfin_spi0_info = {
        .num_chipselect = 8,
        .enable_dma = 1,  /* master has the ability to do dma transfer */
 };
 
-static struct platform_device spi_bfin_master_device = {
-       .name = "bfin-spi-master",
-       .id = 1, /* Bus number */
+static struct platform_device bfin_spi0_device = {
+       .name = "bfin-spi",
+       .id = 0, /* Bus number */
+       .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+       .resource = bfin_spi0_resource,
        .dev = {
-               .platform_data = &spi_bfin_master_info, /* Passed to driver */
+               .platform_data = &bfin_spi0_info, /* Passed to driver */
        },
 };
 
@@ -160,23 +178,63 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
        {
                .modalias = "ad1836-spi",
                .max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
-               .bus_num = 1,
+               .bus_num = 0,
                .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
                .controller_data = &ad1836_spi_chip_info,
        },
 #endif
 };
 
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT       55
+
+static struct pata_platform_info bfin_pata_platform_data = {
+       .ioport_shift = 1,
+       .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+       {
+               .start = 0x20314020,
+               .end = 0x2031403F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = 0x2031401C,
+               .end = 0x2031401F,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = PATA_INT,
+               .end = PATA_INT,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bfin_pata_device = {
+       .name = "pata_platform",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(bfin_pata_resources),
+       .resource = bfin_pata_resources,
+       .dev = {
+               .platform_data = &bfin_pata_platform_data,
+       }
+};
+#endif
+
 static struct platform_device *ezkit_devices[] __initdata = {
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
        &smc91x_device,
 #endif
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-       &spi_bfin_master_device,
+       &bfin_spi0_device,
 #endif
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
        &bfin_uart_device,
 #endif
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       &bfin_pata_device,
+#endif
 };
 
 static int __init ezkit_init(void)
@@ -194,7 +252,15 @@ static int __init ezkit_init(void)
        SSYNC();
 #endif
 
-       return spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+       spi_register_board_info(bfin_spi_board_info,
+                               ARRAY_SIZE(bfin_spi_board_info));
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+       irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
+       return 0;
 }
 
 arch_initcall(ezkit_init);
index 38650a628980fec47626a20c4aad07ccb1319d1f..96a3d456fb6d8a678e614cc37741cbf824263490 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/trace.h>
 
 #if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach-common/clocks.h>
 #include <asm/mach/mem_init.h>
 #endif
 
@@ -50,10 +51,12 @@ __INIT
 ENTRY(__start)
        /* R0: argument of command line string, passed from uboot, save it */
        R7 = R0;
-       /* Set the SYSCFG register:
-        * Enable Cycle Counter and Nesting Of Interrupts (3rd Bit)
-        */
-       R0 = 0x36;
+       /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+       R0 = SYSCFG_SNEN;
+#else
+       R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
        SYSCFG = R0;
        R0 = 0;
 
@@ -95,43 +98,42 @@ ENTRY(__start)
        M2 = r0;
        M3 = r0;
 
-       trace_buffer_start(p0,r0);
+       trace_buffer_init(p0,r0);
        P0 = R1;
        R0 = R1;
 
        /* Turn off the icache */
-       p0.l = (IMEM_CONTROL & 0xFFFF);
-       p0.h = (IMEM_CONTROL >> 16);
+       p0.l = LO(IMEM_CONTROL);
+       p0.h = HI(IMEM_CONTROL);
        R1 = [p0];
        R0 = ~ENICPLB;
        R0 = R0 & R1;
 
-       /* Anomaly 05000125 */
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        CLI R2;
        SSYNC;
 #endif
        [p0] = R0;
        SSYNC;
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        STI R2;
 #endif
 
        /* Turn off the dcache */
-       p0.l = (DMEM_CONTROL & 0xFFFF);
-       p0.h = (DMEM_CONTROL >> 16);
+       p0.l = LO(DMEM_CONTROL);
+       p0.h = HI(DMEM_CONTROL);
        R1 = [p0];
        R0 = ~ENDCPLB;
        R0 = R0 & R1;
 
        /* Anomaly 05000125 */
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        CLI R2;
        SSYNC;
 #endif
        [p0] = R0;
        SSYNC;
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
        STI R2;
 #endif
 
@@ -167,6 +169,12 @@ ENTRY(__start)
        fp = sp;
        usp = sp;
 
+#ifdef CONFIG_EARLY_PRINTK
+       SP += -12;
+       call _init_early_exception_vectors;
+       SP += 12;
+#endif
+
        /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
        call _bf53x_relocate_l1_mem;
 #if CONFIG_BFIN_KERNEL_CLOCK
@@ -220,7 +228,7 @@ ENTRY(__start)
        p0.l = .LWAIT_HERE;
        p0.h = .LWAIT_HERE;
        reti = p0;
-#if defined(ANOMALY_05000281)
+#if ANOMALY_05000281
        nop; nop; nop;
 #endif
        rti;
@@ -372,8 +380,8 @@ ENTRY(_start_dma_code)
        w[p0] = r0.l;
        ssync;
 
-       p0.l = (EBIU_SDBCTL & 0xFFFF);
-       p0.h = (EBIU_SDBCTL >> 16);     /* SDRAM Memory Bank Control Register */
+       p0.l = LO(EBIU_SDBCTL);
+       p0.h = HI(EBIU_SDBCTL);     /* SDRAM Memory Bank Control Register */
        r0 = mem_SDBCTL;
        w[p0] = r0.l;
        ssync;
@@ -404,66 +412,6 @@ ENTRY(_start_dma_code)
 ENDPROC(_start_dma_code)
 #endif /* CONFIG_BFIN_KERNEL_CLOCK */
 
-ENTRY(_bfin_reset)
-       /* No more interrupts to be handled*/
-       CLI R6;
-       SSYNC;
-
-#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
-       p0.h = hi(FIO_INEN);
-       p0.l = lo(FIO_INEN);
-       r0.l = ~(PF1 | PF0);
-       w[p0] = r0.l;
-
-       p0.h = hi(FIO_DIR);
-       p0.l = lo(FIO_DIR);
-       r0.l = (PF1 | PF0);
-       w[p0] = r0.l;
-
-       p0.h = hi(FIO_FLAG_C);
-       p0.l = lo(FIO_FLAG_C);
-       r0.l = (PF1 | PF0);
-       w[p0] = r0.l;
-#endif
-
-       /* Clear the IMASK register */
-       p0.h = hi(IMASK);
-       p0.l = lo(IMASK);
-       r0 = 0x0;
-       [p0] = r0;
-
-       /* Clear the ILAT register */
-       p0.h = hi(ILAT);
-       p0.l = lo(ILAT);
-       r0 = [p0];
-       [p0] = r0;
-       SSYNC;
-
-       /* make sure SYSCR is set to use BMODE */
-       P0.h = hi(SYSCR);
-       P0.l = lo(SYSCR);
-       R0.l = 0x20;            /* on BF561, disable core b */
-       W[P0] = R0.l;
-       SSYNC;
-
-       /* issue a system soft reset */
-       P1.h = hi(SWRST);
-       P1.l = lo(SWRST);
-       R1.l = 0x0007;
-       W[P1] = R1;
-       SSYNC;
-
-       /* clear system soft reset */
-       R0.l = 0x0000;
-       W[P0] = R0;
-       SSYNC;
-
-       /* issue core reset */
-       raise 1;
-
-       RTS;
-ENDPROC(_bfin_reset)
-
 .data
 
 /*
index 0279ede70392fb40d0403044eff8bdd8fd487791..4d7733dfd5de009522fc203a4c7e884d8c2bcd5f 100644 (file)
@@ -4,7 +4,7 @@
 
 obj-y := \
        cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \
-       interrupt.o lock.o irqpanic.o
+       interrupt.o lock.o irqpanic.o arch_checks.o
 
 obj-$(CONFIG_CPLB_INFO)          += cplbinfo.o
 obj-$(CONFIG_BFIN_SINGLE_CORE)   += ints-priority-sc.o
diff --git a/arch/blackfin/mach-common/arch_checks.c b/arch/blackfin/mach-common/arch_checks.c
new file mode 100644 (file)
index 0000000..2f6ce39
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * File:         arch/blackfin/mach-common/arch_checks.c
+ * Based on:
+ * Author:      Robin Getz <rgetz@blackfin.uclinux.org>
+ *
+ * Created:      25Jul07
+ * Description:  Do some checking to make sure things are OK
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <asm/mach/anomaly.h>
+#include <asm/mach-common/clocks.h>
+
+#ifdef CONFIG_BFIN_KERNEL_CLOCK
+
+# if (CONFIG_VCO_HZ > CONFIG_MAX_VCO_HZ)
+#  error "VCO selected is more than maximum value. Please change the VCO multipler"
+# endif
+
+# if (CONFIG_SCLK_HZ > CONFIG_MAX_SCLK_HZ)
+# error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier"
+# endif
+
+# if (CONFIG_SCLK_HZ < CONFIG_MIN_SCLK_HZ)
+# error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier"
+# endif
+
+# if (ANOMALY_05000273) && (CONFIG_SCLK_HZ * 2 > CONFIG_CCLK_HZ)
+# error "ANOMALY 05000273, please make sure CCLK is at least 2x SCLK"
+# endif
+
+# if (CONFIG_SCLK_HZ > CONFIG_CCLK_HZ) && (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ) && (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ)
+# error "Please select sclk less than cclk"
+# endif
+
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+#if (CONFIG_MEM_SIZE % 4)
+#error "SDRAM mem size must be multible of 4MB"
+#endif
+
index 7063795eb7c08205c137abe6e5e045b94da47af3..0521b15882044e7665dcb400703a13792285db77 100644 (file)
@@ -79,8 +79,8 @@ ENTRY(_icache_invalidate)
 ENTRY(_invalidate_entire_icache)
        [--SP] = ( R7:5);
 
-       P0.L = (IMEM_CONTROL & 0xFFFF);
-       P0.H = (IMEM_CONTROL >> 16);
+       P0.L = LO(IMEM_CONTROL);
+       P0.H = HI(IMEM_CONTROL);
        R7 = [P0];
 
        /* Clear the IMC bit , All valid bits in the instruction
@@ -197,8 +197,8 @@ ENTRY(_invalidate_entire_dcache)
 ENTRY(_dcache_invalidate)
        [--SP] = ( R7:6);
 
-       P0.L = (DMEM_CONTROL & 0xFFFF);
-       P0.H = (DMEM_CONTROL >> 16);
+       P0.L = LO(DMEM_CONTROL);
+       P0.H = HI(DMEM_CONTROL);
        R7 = [P0];
 
        /* Clear the DMC[1:0] bits, All valid bits in the data
index 5be6b975ae4a0fc88c65d0186652691d42658497..22fada0c1cb3e0e16a27039dda9648080fd3c63b 100644 (file)
 
 .text
 
-#ifdef ANOMALY_05000125
-#if defined(CONFIG_BLKFIN_CACHE)
+#if ANOMALY_05000125
+#if defined(CONFIG_BFIN_ICACHE)
 ENTRY(_bfin_write_IMEM_CONTROL)
 
        /* Enable Instruction Cache */
-       P0.l = (IMEM_CONTROL & 0xFFFF);
-       P0.h = (IMEM_CONTROL >> 16);
+       P0.l = LO(IMEM_CONTROL);
+       P0.h = HI(IMEM_CONTROL);
 
        /* Anomaly 05000125 */
        CLI R1;
@@ -58,10 +58,10 @@ ENTRY(_bfin_write_IMEM_CONTROL)
 ENDPROC(_bfin_write_IMEM_CONTROL)
 #endif
 
-#if defined(CONFIG_BLKFIN_DCACHE)
+#if defined(CONFIG_BFIN_DCACHE)
 ENTRY(_bfin_write_DMEM_CONTROL)
-       P0.l = (DMEM_CONTROL & 0xFFFF);
-       P0.h = (DMEM_CONTROL >> 16);
+       P0.l = LO(DMEM_CONTROL);
+       P0.h = HI(DMEM_CONTROL);
 
        CLI R1;
        SSYNC;          /* SSYNC required before writing to DMEM_CONTROL. */
index 2f3c72c239977e77f6b8cc5e60a2c453dfa3cec5..2788532de72be3176bd9503fd5894ec45dbb13a4 100644 (file)
@@ -69,14 +69,14 @@ ENTRY(__cplb_hdr)
 
 .Lis_icplb_miss:
 
-#if defined(CONFIG_BLKFIN_CACHE) || defined(CONFIG_BLKFIN_DCACHE)
-# if defined(CONFIG_BLKFIN_CACHE) && !defined(CONFIG_BLKFIN_DCACHE)
+#if defined(CONFIG_BFIN_ICACHE) || defined(CONFIG_BFIN_DCACHE)
+# if defined(CONFIG_BFIN_ICACHE) && !defined(CONFIG_BFIN_DCACHE)
        R1 = CPLB_ENABLE_ICACHE;
 # endif
-# if !defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE)
+# if !defined(CONFIG_BFIN_ICACHE) && defined(CONFIG_BFIN_DCACHE)
        R1 = CPLB_ENABLE_DCACHE;
 # endif
-# if defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE)
+# if defined(CONFIG_BFIN_ICACHE) && defined(CONFIG_BFIN_DCACHE)
        R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE;
 # endif
 #else
index e4b47e09cf1311b0123450027ba7a08570cabc8b..946703ef48ffc912a45b93c7c10a05d0ccb848bc 100644 (file)
@@ -75,15 +75,15 @@ ENTRY(_cplb_mgr)
        * from the configuration table.
        */
 
-       P4.L = (ICPLB_FAULT_ADDR & 0xFFFF);
-       P4.H = (ICPLB_FAULT_ADDR >> 16);
+       P4.L = LO(ICPLB_FAULT_ADDR);
+       P4.H = HI(ICPLB_FAULT_ADDR);
 
        P1 = 16;
        P5.L = _page_size_table;
        P5.H = _page_size_table;
 
-       P0.L = (ICPLB_DATA0 & 0xFFFF);
-       P0.H = (ICPLB_DATA0 >> 16);
+       P0.L = LO(ICPLB_DATA0);
+       P0.H = HI(ICPLB_DATA0);
        R4 = [P4];              /* Get faulting address*/
        R6 = 64;                /* Advance past the fault address, which*/
        R6 = R6 + R4;           /* we'll use if we find a match*/
@@ -117,13 +117,13 @@ ENTRY(_cplb_mgr)
        I0 = R4;                /* Fault address we'll search for*/
 
        /* set up pointers */
-       P0.L = (ICPLB_DATA0 & 0xFFFF);
-       P0.H = (ICPLB_DATA0 >> 16);
+       P0.L = LO(ICPLB_DATA0);
+       P0.H = HI(ICPLB_DATA0);
 
        /* The replacement procedure for ICPLBs */
 
-       P4.L = (IMEM_CONTROL & 0xFFFF);
-       P4.H = (IMEM_CONTROL >> 16);
+       P4.L = LO(IMEM_CONTROL);
+       P4.H = HI(IMEM_CONTROL);
 
        /* disable cplbs */
        R5 = [P4];              /* Control Register*/
@@ -243,8 +243,8 @@ ENTRY(_cplb_mgr)
         * last entry of the table.
         */
 
-       P1.L = (ICPLB_DATA15 & 0xFFFF);         /* ICPLB_DATA15 */
-       P1.H = (ICPLB_DATA15 >> 16);
+       P1.L = LO(ICPLB_DATA15);                /* ICPLB_DATA15 */
+       P1.H = HI(ICPLB_DATA15);
        [P1] = R2;
        [P1-0x100] = R4;
 #ifdef CONFIG_CPLB_INFO
@@ -292,10 +292,10 @@ ENTRY(_cplb_mgr)
         * pending writes associated with the CPLB.
         */
 
-       P4.L = (DCPLB_STATUS & 0xFFFF);
-       P4.H = (DCPLB_STATUS >> 16);
-       P3.L = (DCPLB_DATA0 & 0xFFFF);
-       P3.H = (DCPLB_DATA0 >> 16);
+       P4.L = LO(DCPLB_STATUS);
+       P4.H = HI(DCPLB_STATUS);
+       P3.L = LO(DCPLB_DATA0);
+       P3.H = HI(DCPLB_DATA0);
        R5 = [P4];
 
        /* A protection violation can be caused by more than just writes
@@ -355,11 +355,11 @@ ENTRY(_cplb_mgr)
         * config table, that covers the faulting address.
         */
 
-       P1.L = (DCPLB_DATA15 & 0xFFFF);
-       P1.H = (DCPLB_DATA15 >> 16);
+       P1.L = LO(DCPLB_DATA15);
+       P1.H = HI(DCPLB_DATA15);
 
-       P4.L = (DCPLB_FAULT_ADDR & 0xFFFF);
-       P4.H = (DCPLB_FAULT_ADDR >> 16);
+       P4.L = LO(DCPLB_FAULT_ADDR);
+       P4.H = HI(DCPLB_FAULT_ADDR);
        R4 = [P4];
        I0 = R4;
 
@@ -368,8 +368,8 @@ ENTRY(_cplb_mgr)
        R6 = R1;        /* Save for later*/
 
        /* Turn off CPLBs while we work.*/
-       P4.L = (DMEM_CONTROL & 0xFFFF);
-       P4.H = (DMEM_CONTROL >> 16);
+       P4.L = LO(DMEM_CONTROL);
+       P4.H = HI(DMEM_CONTROL);
        R5 = [P4];
        BITCLR(R5,ENDCPLB_P);
        CLI R0;
@@ -384,8 +384,8 @@ ENTRY(_cplb_mgr)
         * are no good.
         */
 
-       I1.L = (DCPLB_DATA0 & 0xFFFF);
-       I1.H = (DCPLB_DATA0 >> 16);
+       I1.L = LO(DCPLB_DATA0);
+       I1.H = HI(DCPLB_DATA0);
        P1 = 2;
        P2 = 16;
        I2.L = _dcplb_preference;
@@ -405,7 +405,7 @@ ENTRY(_cplb_mgr)
        P3.L = _page_size_table; /* retrieve end address */
        P3.H = _page_size_table; /* retrieve end address */
        R3 = 0x1002;            /* 16th - position, 2 bits -length */
-#ifdef ANOMALY_05000209
+#if ANOMALY_05000209
        nop;                    /* Anomaly 05000209 */
 #endif
        R7 = EXTRACT(R1,R3.l);
@@ -475,8 +475,8 @@ ENTRY(_cplb_mgr)
         * one space closer to the start.
         */
 
-       R1.L = (DCPLB_DATA16 & 0xFFFF);         /* DCPLB_DATA15 + 4 */
-       R1.H = (DCPLB_DATA16 >> 16);
+       R1.L = LO(DCPLB_DATA16);                /* DCPLB_DATA15 + 4 */
+       R1.H = HI(DCPLB_DATA16);
        R0 = P0;
 
        /* If the victim happens to be in DCPLB15,
@@ -549,8 +549,8 @@ ENTRY(_cplb_mgr)
         * if necessary.
         */
 
-       P1.L = (DCPLB_DATA15 & 0xFFFF);
-       P1.H = (DCPLB_DATA15 >> 16);
+       P1.L = LO(DCPLB_DATA15);
+       P1.H = HI(DCPLB_DATA15);
 
        /* If the DCPLB has cache bits set, but caching hasn't
         * been enabled, then we want to mask off the cache-in-L1
@@ -565,7 +565,7 @@ ENTRY(_cplb_mgr)
         * cost of first-write exceptions to mark the page as dirty.
         */
 
-#ifdef CONFIG_BLKFIN_WT
+#ifdef CONFIG_BFIN_WT
        BITSET(R6, 14);         /* Set WT*/
 #endif
 
index 97cdcd6a00d47b8c52eaaee3f71c2bb9e155bd16..39fbc2861107b53b90d9641e68973434d7a63a47 100644 (file)
@@ -39,8 +39,8 @@ ENTRY(_unmask_wdog_wakeup_evt)
        P0.H = hi(SICA_IWR1);
        P0.L = lo(SICA_IWR1);
 #else
-       P0.h = (SIC_IWR >> 16);
-       P0.l = (SIC_IWR & 0xFFFF);
+       P0.h = HI(SIC_IWR);
+       P0.l = LO(SIC_IWR);
 #endif
        R7 = [P0];
 #if defined(CONFIG_BF561)
@@ -60,11 +60,11 @@ ENTRY(_unmask_wdog_wakeup_evt)
         */
        R7 = 0x0000(z);
 #if defined(CONFIG_BF561)
-       P0.h = (WDOGA_STAT >> 16);
-       P0.l = (WDOGA_STAT & 0xFFFF);
+       P0.h = HI(WDOGA_STAT);
+       P0.l = LO(WDOGA_STAT);
 #else
-       P0.h = (WDOG_STAT >> 16);
-       P0.l = (WDOG_STAT & 0xFFFF);
+       P0.h = HI(WDOG_STAT);
+       P0.l = LO(WDOG_STAT);
 #endif
        [P0] = R7;
        SSYNC;
@@ -73,21 +73,21 @@ ENTRY(_unmask_wdog_wakeup_evt)
 ENTRY(_program_wdog_timer)
        [--SP] = ( R7:0, P5:0 );
 #if defined(CONFIG_BF561)
-       P0.h = (WDOGA_CNT >> 16);
-       P0.l = (WDOGA_CNT & 0xFFFF);
+       P0.h = HI(WDOGA_CNT);
+       P0.l = LO(WDOGA_CNT);
 #else
-       P0.h = (WDOG_CNT >> 16);
-       P0.l = (WDOG_CNT & 0xFFFF);
+       P0.h = HI(WDOG_CNT);
+       P0.l = LO(WDOG_CNT);
 #endif
        [P0] = R0;
        SSYNC;
 
 #if defined(CONFIG_BF561)
-       P0.h = (WDOGA_CTL >> 16);
-       P0.l = (WDOGA_CTL & 0xFFFF);
+       P0.h = HI(WDOGA_CTL);
+       P0.l = LO(WDOGA_CTL);
 #else
-       P0.h = (WDOG_CTL >> 16);
-       P0.l = (WDOG_CTL & 0xFFFF);
+       P0.h = HI(WDOG_CTL);
+       P0.l = LO(WDOG_CTL);
 #endif
        R7 = W[P0](Z);
        CC = BITTST(R7,1);
@@ -97,11 +97,11 @@ ENTRY(_program_wdog_timer)
 
 .LSKIP_WRITE_TO_STAT:
 #if defined(CONFIG_BF561)
-       P0.h = (WDOGA_CTL >> 16);
-           P0.l = (WDOGA_CTL & 0xFFFF);
+       P0.h = HI(WDOGA_CTL);
+       P0.l = LO(WDOGA_CTL);
 #else
-       P0.h = (WDOG_CTL >> 16);
-           P0.l = (WDOG_CTL & 0xFFFF);
+       P0.h = HI(WDOG_CTL);
+       P0.l = LO(WDOG_CTL);
 #endif
        R7 = W[P0](Z);
        BITCLR(R7,1);   /* Enable GP event */
@@ -122,11 +122,11 @@ ENTRY(_clear_wdog_wakeup_evt)
        [--SP] = ( R7:0, P5:0 );
 
 #if defined(CONFIG_BF561)
-       P0.h = (WDOGA_CTL >> 16);
-       P0.l = (WDOGA_CTL & 0xFFFF);
+       P0.h = HI(WDOGA_CTL);
+       P0.l = LO(WDOGA_CTL);
 #else
-       P0.h = (WDOG_CTL >> 16);
-       P0.l = (WDOG_CTL & 0xFFFF);
+       P0.h = HI(WDOG_CTL);
+       P0.l = LO(WDOG_CTL);
 #endif
        R7 = 0x0AD6(Z);
        W[P0] = R7.L;
@@ -149,11 +149,11 @@ ENTRY(_clear_wdog_wakeup_evt)
 ENTRY(_disable_wdog_timer)
        [--SP] = ( R7:0, P5:0 );
 #if defined(CONFIG_BF561)
-       P0.h = (WDOGA_CTL >> 16);
-       P0.l = (WDOGA_CTL & 0xFFFF);
+       P0.h = HI(WDOGA_CTL);
+       P0.l = LO(WDOGA_CTL);
 #else
-       P0.h = (WDOG_CTL >> 16);
-       P0.l = (WDOG_CTL & 0xFFFF);
+       P0.h = HI(WDOG_CTL);
+       P0.l = LO(WDOG_CTL);
 #endif
        R7 = 0xAD6(Z);
        W[P0] = R7.L;
@@ -300,7 +300,7 @@ ENTRY(_sleep_deeper)
        P0.H = hi(PLL_CTL);
        P0.L = lo(PLL_CTL);
        R5 = W[P0](z);
-       R0.L = (MIN_VC/CONFIG_CLKIN_HZ) << 9;
+       R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9;
        W[P0] = R0.l;
 
        SSYNC;
index 9604588083446d6c866595e4336d0e63fc6c7b97..e3ad5802868a2489865a761ae32b824b6a87ecc4 100644 (file)
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-/*
- * 25-Dec-2004 - LG Soft India
- *     1. Fix in return_from_int, to make sure any pending
- *     system call in ILAT for this process to get
- *     executed, otherwise in case context switch happens,
- *     system call of first process (i.e in ILAT) will be
- *     carried forward to the switched process.
- *     2. Removed Constant references for the following
- *             a.  IPEND
- *             b.  EXCAUSE mask
- *             c.  PAGE Mask
- */
-
-/*
- * NOTE: This code handles signal-recognition, which happens every time
+/* NOTE: This code handles signal-recognition, which happens every time
  * after a timer-interrupt and after each system call.
  */
 
 
 #include <asm/mach-common/context.S>
 
+#if defined(CONFIG_BFIN_SCRATCH_REG_RETN)
+# define EX_SCRATCH_REG RETN
+#elif defined(CONFIG_BFIN_SCRATCH_REG_RETE)
+# define EX_SCRATCH_REG RETE
+#else
+# define EX_SCRATCH_REG CYCLES
+#endif
+
+#if ANOMALY_05000281
+ENTRY(_safe_speculative_execution)
+       NOP;
+       NOP;
+       NOP;
+       jump _safe_speculative_execution;
+ENDPROC(_safe_speculative_execution)
+#endif
+
 #ifdef CONFIG_EXCPT_IRQ_SYSC_L1
 .section .l1.text
 #else
@@ -69,7 +72,7 @@
  * patch up CPLB misses on the kernel stack.
  */
 ENTRY(_ex_dcplb)
-#if defined(ANOMALY_05000261)
+#if ANOMALY_05000261
        /*
         * Work around an anomaly: if we see a new DCPLB fault, return
         * without doing anything.  Then, if we get the same fault again,
@@ -93,7 +96,7 @@ ENTRY(_ex_icplb)
        call __cplb_hdr;
        DEBUG_START_HWTRACE(p5, r7)
        RESTORE_ALL_SYS
-       SP = RETN;
+       SP = EX_SCRATCH_REG;
        rtx;
 ENDPROC(_ex_icplb)
 
@@ -102,7 +105,7 @@ ENTRY(_ex_syscall)
        (R7:6,P5:4) = [sp++];
        ASTAT = [sp++];
        raise 15;               /* invoked by TRAP #0, for sys call */
-       sp = retn;
+       sp = EX_SCRATCH_REG;
        rtx
 ENDPROC(_ex_syscall)
 
@@ -135,9 +138,9 @@ ENTRY(_ex_single_step)
        cc = r6 == r7;
        if !cc jump _ex_trap_c;
 
-_return_from_exception:
+ENTRY(_return_from_exception)
        DEBUG_START_HWTRACE(p5, r7)
-#ifdef ANOMALY_05000257
+#if ANOMALY_05000257
        R7=LC0;
        LC0=R7;
        R7=LC1;
@@ -145,7 +148,7 @@ _return_from_exception:
 #endif
        (R7:6,P5:4) = [sp++];
        ASTAT = [sp++];
-       sp = retn;
+       sp = EX_SCRATCH_REG;
        rtx;
 ENDPROC(_ex_soft_bp)
 
@@ -163,7 +166,17 @@ ENTRY(_handle_bad_cplb)
        [--sp] = ASTAT;
        [--sp] = (R7:6, P5:4);
 
+ENTRY(_ex_replaceable)
+       nop;
+
 ENTRY(_ex_trap_c)
+       /* Make sure we are not in a double fault */
+       p4.l = lo(IPEND);
+       p4.h = hi(IPEND);
+       r7 = [p4];
+       CC = BITTST (r7, 5);
+       if CC jump _double_fault;
+
        /* Call C code (trap_c) to handle the exception, which most
         * likely involves sending a signal to the current process.
         * To avoid double faults, lower our priority to IRQ5 first.
@@ -204,11 +217,57 @@ ENTRY(_ex_trap_c)
        DEBUG_START_HWTRACE(p5, r7)
        (R7:6,P5:4) = [sp++];
        ASTAT = [sp++];
-       SP = RETN;
+       SP = EX_SCRATCH_REG;
        raise 5;
        rtx;
 ENDPROC(_ex_trap_c)
 
+/* We just realized we got an exception, while we were processing a different
+ * exception. This is a unrecoverable event, so crash
+ */
+ENTRY(_double_fault)
+        /* Turn caches & protection off, to ensure we don't get any more
+         * double exceptions
+         */
+
+        P4.L = LO(IMEM_CONTROL);
+        P4.H = HI(IMEM_CONTROL);
+
+        R5 = [P4];              /* Control Register*/
+        BITCLR(R5,ENICPLB_P);
+        SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
+        .align 8;
+        [P4] = R5;
+        SSYNC;
+
+        P4.L = LO(DMEM_CONTROL);
+        P4.H = HI(DMEM_CONTROL);
+        R5 = [P4];
+        BITCLR(R5,ENDCPLB_P);
+        SSYNC;          /* SSYNC required before writing to DMEM_CONTROL. */
+        .align 8;
+        [P4] = R5;
+        SSYNC;
+
+        /* Fix up the stack */
+        (R7:6,P5:4) = [sp++];
+        ASTAT = [sp++];
+        SP = EX_SCRATCH_REG;
+
+        /* We should be out of the exception stack, and back down into
+         * kernel or user space stack
+         */
+        SAVE_ALL_SYS
+
+        r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
+        SP += -12;
+        call _double_fault_c;
+        SP += 12;
+.L_double_fault_panic:
+        JUMP .L_double_fault_panic
+
+ENDPROC(_double_fault)
+
 ENTRY(_exception_to_level5)
        SAVE_ALL_SYS
 
@@ -279,7 +338,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
         * covered by a CPLB.  Switch to an exception stack; use RETN as a
         * scratch register (for want of a better option).
         */
-       retn = sp;
+       EX_SCRATCH_REG = sp;
        sp.l = _exception_stack_top;
        sp.h = _exception_stack_top;
        /* Try to deal with syscalls quickly.  */
@@ -290,8 +349,8 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
        r6.l = lo(SEQSTAT_EXCAUSE);
        r6.h = hi(SEQSTAT_EXCAUSE);
        r7 = r7 & r6;
-       p5.h = _extable;
-       p5.l = _extable;
+       p5.h = _ex_table;
+       p5.l = _ex_table;
        p4 = r7;
        p5 = p5 + (p4 << 2);
        p4 = [p5];
@@ -634,9 +693,9 @@ ENTRY(_return_from_int)
        p1.h = _schedule_and_signal_from_int;
        [p0] = p1;
        csync;
-#if defined(ANOMALY_05000281)
-       r0.l = lo(CONFIG_BOOT_LOAD);
-       r0.h = hi(CONFIG_BOOT_LOAD);
+#if ANOMALY_05000281
+       r0.l = _safe_speculative_execution;
+       r0.h = _safe_speculative_execution;
        reti = r0;
 #endif
        r0 = 0x801f (z);
@@ -648,9 +707,9 @@ ENTRY(_return_from_int)
 ENDPROC(_return_from_int)
 
 ENTRY(_lower_to_irq14)
-#if defined(ANOMALY_05000281)
-       r0.l = lo(CONFIG_BOOT_LOAD);
-       r0.h = hi(CONFIG_BOOT_LOAD);
+#if ANOMALY_05000281
+       r0.l = _safe_speculative_execution;
+       r0.h = _safe_speculative_execution;
        reti = r0;
 #endif
        r0 = 0x401f;
@@ -731,6 +790,114 @@ ENTRY(_init_exception_buff)
        rts;
 ENDPROC(_init_exception_buff)
 
+/* We handle this 100% in exception space - to reduce overhead
+ * Only potiential problem is if the software buffer gets swapped out of the
+ * CPLB table - then double fault. - so we don't let this happen in other places
+ */
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
+ENTRY(_ex_trace_buff_full)
+       [--sp] = P3;
+       [--sp] = P2;
+       [--sp] = LC0;
+       [--sp] = LT0;
+       [--sp] = LB0;
+       P5.L = _trace_buff_offset;
+       P5.H = _trace_buff_offset;
+       P3 = [P5];              /* trace_buff_offset */
+       P5.L = lo(TBUFSTAT);
+       P5.H = hi(TBUFSTAT);
+       R7 = [P5];
+       R7 <<= 1;               /* double, since we need to read twice */
+       LC0 = R7;
+       R7 <<= 2;               /* need to shift over again,
+                                * to get the number of bytes */
+       P5.L = lo(TBUF);
+       P5.H = hi(TBUF);
+       R6 = ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN)*1024) - 1;
+
+       P2 = R7;
+       P3 = P3 + P2;
+       R7 = P3;
+       R7 = R7 & R6;
+       P3 = R7;
+       P2.L = _trace_buff_offset;
+       P2.H = _trace_buff_offset;
+       [P2] = P3;
+
+       P2.L = _software_trace_buff;
+       P2.H = _software_trace_buff;
+
+       LSETUP (.Lstart, .Lend) LC0;
+.Lstart:
+       R7 = [P5];      /* read TBUF */
+       P4 = P3 + P2;
+       [P4] = R7;
+       P3 += -4;
+       R7 = P3;
+       R7 = R7 & R6;
+.Lend:
+       P3 = R7;
+
+       LB0 = [sp++];
+       LT0 = [sp++];
+       LC0 = [sp++];
+       P2 = [sp++];
+       P3 = [sp++];
+       jump _return_from_exception;
+ENDPROC(_ex_trace_buff_full)
+
+#if CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN == 4
+.data
+#else
+.section .l1.data.B
+#endif /* CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN */
+ENTRY(_trace_buff_offset)
+        .long 0;
+ALIGN
+ENTRY(_software_trace_buff)
+       .rept ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN)*256);
+       .long 0
+       .endr
+#endif /* CONFIG_DEBUG_BFIN_HWTRACE_EXPAND */
+
+#if CONFIG_EARLY_PRINTK
+.section .init.text
+ENTRY(_early_trap)
+       SAVE_ALL_SYS
+       trace_buffer_stop(p0,r0);
+
+       /* Turn caches off, to ensure we don't get double exceptions */
+
+       P4.L = LO(IMEM_CONTROL);
+       P4.H = HI(IMEM_CONTROL);
+
+       R5 = [P4];              /* Control Register*/
+       BITCLR(R5,ENICPLB_P);
+       CLI R1;
+       SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
+       .align 8;
+       [P4] = R5;
+       SSYNC;
+
+       P4.L = LO(DMEM_CONTROL);
+       P4.H = HI(DMEM_CONTROL);
+       R5 = [P4];
+       BITCLR(R5,ENDCPLB_P);
+       SSYNC;          /* SSYNC required before writing to DMEM_CONTROL. */
+       .align 8;
+       [P4] = R5;
+       SSYNC;
+       STI R1;
+
+       r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
+       r1 = RETX;
+
+       SP += -12;
+       call _early_trap_c;
+       SP += 12;
+ENDPROC(_early_trap)
+#endif /* CONFIG_EARLY_PRINTK */
+
 /*
  * Put these in the kernel data section - that should always be covered by
  * a CPLB. This is needed to ensure we don't get double fault conditions
@@ -741,30 +908,33 @@ ENDPROC(_init_exception_buff)
 #else
 .data
 #endif
-ALIGN
-_extable:
+ENTRY(_ex_table)
        /* entry for each EXCAUSE[5:0]
         * This table must be in sync with the table in ./kernel/traps.c
         * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined
         */
-       .long _ex_syscall;      /* 0x00 - User Defined - Linux Syscall */
+       .long _ex_syscall       /* 0x00 - User Defined - Linux Syscall */
        .long _ex_soft_bp       /* 0x01 - User Defined - Software breakpoint */
-       .long _ex_trap_c        /* 0x02 - User Defined */
+       .long _ex_replaceable   /* 0x02 - User Defined */
        .long _ex_trap_c        /* 0x03 - User Defined - userspace stack overflow */
-       .long _ex_trap_c        /* 0x04 - User Defined */
-       .long _ex_trap_c        /* 0x05 - User Defined */
-       .long _ex_trap_c        /* 0x06 - User Defined */
-       .long _ex_trap_c        /* 0x07 - User Defined */
-       .long _ex_trap_c        /* 0x08 - User Defined */
-       .long _ex_trap_c        /* 0x09 - User Defined */
-       .long _ex_trap_c        /* 0x0A - User Defined */
-       .long _ex_trap_c        /* 0x0B - User Defined */
-       .long _ex_trap_c        /* 0x0C - User Defined */
-       .long _ex_trap_c        /* 0x0D - User Defined */
-       .long _ex_trap_c        /* 0x0E - User Defined */
-       .long _ex_trap_c        /* 0x0F - User Defined */
+       .long _ex_replaceable   /* 0x04 - User Defined */
+       .long _ex_replaceable   /* 0x05 - User Defined */
+       .long _ex_replaceable   /* 0x06 - User Defined */
+       .long _ex_replaceable   /* 0x07 - User Defined */
+       .long _ex_replaceable   /* 0x08 - User Defined */
+       .long _ex_replaceable   /* 0x09 - User Defined */
+       .long _ex_replaceable   /* 0x0A - User Defined */
+       .long _ex_replaceable   /* 0x0B - User Defined */
+       .long _ex_replaceable   /* 0x0C - User Defined */
+       .long _ex_replaceable   /* 0x0D - User Defined */
+       .long _ex_replaceable   /* 0x0E - User Defined */
+       .long _ex_replaceable   /* 0x0F - User Defined */
        .long _ex_single_step   /* 0x10 - HW Single step */
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
+       .long _ex_trace_buff_full /* 0x11 - Trace Buffer Full */
+#else
        .long _ex_trap_c        /* 0x11 - Trace Buffer Full */
+#endif
        .long _ex_trap_c        /* 0x12 - Reserved */
        .long _ex_trap_c        /* 0x13 - Reserved */
        .long _ex_trap_c        /* 0x14 - Reserved */
@@ -812,8 +982,8 @@ _extable:
        .long _ex_trap_c        /* 0x3D - Reserved */
        .long _ex_trap_c        /* 0x3E - Reserved */
        .long _ex_trap_c        /* 0x3F - Reserved */
+END(_ex_table)
 
-ALIGN
 ENTRY(_sys_call_table)
        .long _sys_restart_syscall      /* 0 */
        .long _sys_exit
@@ -1184,7 +1354,7 @@ _exception_stack:
        .endr
 _exception_stack_top:
 
-#if defined(ANOMALY_05000261)
+#if ANOMALY_05000261
 /* Used by the assembly entry point to work around an anomaly.  */
 _last_cplb_fault_retx:
        .long 0;
index 203e20709163811021e98131d2747b32e189c3a1..c6b32fe0f6e9f0b2cc12ebcaa3fd28e4e6ed89ef 100644 (file)
 
 .align 4       /* just in case */
 
-/*
- * initial interrupt handlers
- */
-
-#ifndef CONFIG_KGDB
-       /* interrupt routine for emulation - 0 */
-       /* Currently used only if GDB stub is not in - invalid */
-       /* gdb-stub set the evt itself */
-       /* save registers for post-mortem only */
-ENTRY(_evt_emulation)
-       SAVE_ALL_SYS
-#ifdef CONFIG_FRAME_POINTER
-       fp = 0;
-#endif
-       r0 = IRQ_EMU;
-       r1 = sp;
-       SP += -12;
-       call _irq_panic;
-       SP += 12;
-       /* - GDB stub fills this in by itself (if defined) */
-       rte;
-ENDPROC(_evt_emulation)
-#endif
-
 /* Common interrupt entry code.         First we do CLI, then push
  * RETI, to keep interrupts disabled, but to allow this state to be changed
  * by local_bh_enable.
@@ -140,7 +116,7 @@ __common_int_entry:
        fp = 0;
 #endif
 
-#if defined (ANOMALY_05000283) || defined (ANOMALY_05000315)
+#if ANOMALY_05000283 || ANOMALY_05000315
        cc = r7 == r7;
        p5.h = 0xffc0;
        p5.l = 0x0014;
@@ -163,7 +139,7 @@ ENTRY(_evt_ivhw)
 #ifdef CONFIG_FRAME_POINTER
        fp = 0;
 #endif
-#ifdef ANOMALY_05000283
+#if ANOMALY_05000283
        cc = r7 == r7;
        p5.h = 0xffc0;
        p5.l = 0x0014;
@@ -201,27 +177,15 @@ ENTRY(_evt_ivhw)
        jump .Lcommon_restore_context;
 #endif
 
-/* interrupt routine for evt2 - 2.  This is NMI.  */
-ENTRY(_evt_evt2)
-       SAVE_CONTEXT
-#ifdef CONFIG_FRAME_POINTER
-       fp = 0;
-#endif
-#ifdef ANOMALY_05000283
-       cc = r7 == r7;
-       p5.h = 0xffc0;
-       p5.l = 0x0014;
-       if cc jump 1f;
-       r7.l = W[p5];
-1:
-#endif
-       r0 = IRQ_NMI;
-       r1 =  sp;
-       SP += -12;
-       call _asm_do_IRQ;
-       SP += 12;
-       RESTORE_CONTEXT
+/* Interrupt routine for evt2 (NMI).
+ * We don't actually use this, so just return.
+ * For inner circle type details, please see:
+ * http://docs.blackfin.uclinux.org/doku.php?id=linux:nmi
+ */
+ENTRY(_evt_nmi)
+.weak _evt_nmi
        rtn;
+ENDPROC(_evt_nmi)
 
 /* interrupt routine for core timer - 6 */
 ENTRY(_evt_timer)
index 660f881b620a3591ee54474c041bff0545a7a705..2db3546fc874f73804cd360c6d46c16c99262b5a 100644 (file)
@@ -221,7 +221,7 @@ static unsigned int bf561_gpio_irq_startup(unsigned int irq)
 
        if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
 
-               ret = gpio_request(gpionr, NULL);
+               ret = gpio_request(gpionr, "IRQ");
                if (ret)
                        return ret;
 
@@ -261,7 +261,7 @@ static int bf561_gpio_irq_type(unsigned int irq, unsigned int type)
 
                if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
 
-                       ret = gpio_request(gpionr, NULL);
+                       ret = gpio_request(gpionr, "IRQ");
                        if (ret)
                                return ret;
 
@@ -362,10 +362,11 @@ void __init init_exception_vectors(void)
 {
        SSYNC();
 
-#ifndef CONFIG_KGDB
-       bfin_write_EVT0(evt_emulation);
-#endif
-       bfin_write_EVT2(evt_evt2);
+       /* cannot program in software:
+        * evt0 - emulation (jtag)
+        * evt1 - reset
+        */
+       bfin_write_EVT2(evt_nmi);
        bfin_write_EVT3(trap);
        bfin_write_EVT5(evt_ivhw);
        bfin_write_EVT6(evt_timer);
index 4708023fe716e2c11d1f63d369c33b8870393177..d3b7672b2b94ce91dd970c9ce30490cdf4362bae 100644 (file)
@@ -343,7 +343,7 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
        u16 gpionr = irq - IRQ_PF0;
 
        if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
-               ret = gpio_request(gpionr, NULL);
+               ret = gpio_request(gpionr, "IRQ");
                if (ret)
                        return ret;
        }
@@ -377,7 +377,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
        if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
                    IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
                if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
-                       ret = gpio_request(gpionr, NULL);
+                       ret = gpio_request(gpionr, "IRQ");
                        if (ret)
                                return ret;
                }
@@ -587,7 +587,7 @@ static unsigned int bfin_gpio_irq_startup(unsigned int irq)
        }
 
        if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
-               ret = gpio_request(gpionr, NULL);
+               ret = gpio_request(gpionr, "IRQ");
                if (ret)
                        return ret;
        }
@@ -627,7 +627,7 @@ static int bfin_gpio_irq_type(unsigned int irq, unsigned int type)
        if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING |
                    IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
                if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) {
-                       ret = gpio_request(gpionr, NULL);
+                       ret = gpio_request(gpionr, "IRQ");
                        if (ret)
                                return ret;
                }
@@ -721,10 +721,11 @@ void __init init_exception_vectors(void)
 {
        SSYNC();
 
-#ifndef CONFIG_KGDB
-       bfin_write_EVT0(evt_emulation);
-#endif
-       bfin_write_EVT2(evt_evt2);
+       /* cannot program in software:
+        * evt0 - emulation (jtag)
+        * evt1 - reset
+        */
+       bfin_write_EVT2(evt_nmi);
        bfin_write_EVT3(trap);
        bfin_write_EVT5(evt_ivhw);
        bfin_write_EVT6(evt_timer);
index 386ac8dda076c831d2a1d6a5489dece44db9ff49..28b87fe9ce3c6f610ef610f134a4c29858629234 100644 (file)
@@ -33,7 +33,7 @@
 
 .text
 
-#ifdef CONFIG_BLKFIN_CACHE_LOCK
+#ifdef CONFIG_BFIN_ICACHE_LOCK
 
 /* When you come here, it is assumed that
  * R0 - Which way to be locked
@@ -43,12 +43,12 @@ ENTRY(_cache_grab_lock)
 
        [--SP]=( R7:0,P5:0 );
 
-       P1.H = (IMEM_CONTROL >> 16);
-       P1.L = (IMEM_CONTROL & 0xFFFF);
-       P5.H = (ICPLB_ADDR0 >> 16);
-       P5.L = (ICPLB_ADDR0 & 0xFFFF);
-       P4.H = (ICPLB_DATA0 >> 16);
-       P4.L = (ICPLB_DATA0 & 0xFFFF);
+       P1.H = HI(IMEM_CONTROL);
+       P1.L = LO(IMEM_CONTROL);
+       P5.H = HI(ICPLB_ADDR0);
+       P5.L = LO(ICPLB_ADDR0);
+       P4.H = HI(ICPLB_DATA0);
+       P4.L = LO(ICPLB_DATA0);
        R7 = R0;
 
        /* If the code of interest already resides in the cache
@@ -167,8 +167,8 @@ ENTRY(_cache_lock)
 
        [--SP]=( R7:0,P5:0 );
 
-       P1.H = (IMEM_CONTROL >> 16);
-       P1.L = (IMEM_CONTROL & 0xFFFF);
+       P1.H = HI(IMEM_CONTROL);
+       P1.L = LO(IMEM_CONTROL);
 
        /* Disable the Interrupts*/
        CLI R3;
@@ -189,14 +189,14 @@ ENTRY(_cache_lock)
        RTS;
 ENDPROC(_cache_lock)
 
-#endif /* BLKFIN_CACHE_LOCK */
+#endif /* BFIN_ICACHE_LOCK */
 
 /* Return the ILOC bits of IMEM_CONTROL
  */
 
 ENTRY(_read_iloc)
-       P1.H = (IMEM_CONTROL >> 16);
-       P1.L = (IMEM_CONTROL & 0xFFFF);
+       P1.H = HI(IMEM_CONTROL);
+       P1.L = LO(IMEM_CONTROL);
        R1 = 0xF;
        R0 = [P1];
        R0 = R0 >> 3;
index 68459cc052a142ac14df1545c0c3fe86ec88428f..e97ea8fc8dc4915381a2f8610e5c4f19475442f8 100644 (file)
@@ -53,7 +53,7 @@ static unsigned long empty_bad_page;
 
 unsigned long empty_zero_page;
 
-void __init show_mem(void)
+void show_mem(void)
 {
        unsigned long i;
        int free = 0, total = 0, reserved = 0, shared = 0;
index f88f446c814fd8137b84fd93861766d480300977..05dd08c9d1549e3c498c561f5ede90c453d6d823 100644 (file)
@@ -68,7 +68,7 @@ static inline unsigned int ctr_read(void)
        unsigned int tmp;
 
        tmp = bfin_read_PFCTL();
-       __builtin_bfin_csync();
+       CSYNC();
 
        return tmp;
 }
@@ -76,21 +76,21 @@ static inline unsigned int ctr_read(void)
 static inline void ctr_write(unsigned int val)
 {
        bfin_write_PFCTL(val);
-       __builtin_bfin_csync();
+       CSYNC();
 }
 
 static inline void count_read(unsigned int *count)
 {
        count[0] = bfin_read_PFCNTR0();
        count[1] = bfin_read_PFCNTR1();
-       __builtin_bfin_csync();
+       CSYNC();
 }
 
 static inline void count_write(unsigned int *count)
 {
        bfin_write_PFCNTR0(count[0]);
        bfin_write_PFCNTR1(count[1]);
-       __builtin_bfin_csync();
+       CSYNC();
 }
 
 extern int pm_overflow_handler(int irq, struct pt_regs *regs);
index 97b64d7d6bf692baacc019df57845c964c771d39..2d85e4b87307a1e87b7999a068f8620304758c15 100644 (file)
@@ -226,7 +226,7 @@ config PARAVIRT
          However, when run without a hypervisor the kernel is
          theoretically slower.  If in doubt, say N.
 
-source "arch/i386/xen/Kconfig"
+source "arch/x86/xen/Kconfig"
 
 config VMI
        bool "VMI Paravirt-ops support"
@@ -707,7 +707,7 @@ config MATH_EMULATION
          intend to use this kernel on different machines.
 
          More information about the internals of the Linux math coprocessor
-         emulation can be found in <file:arch/i386/math-emu/README>.
+         emulation can be found in <file:arch/x86/math-emu/README>.
 
          If you are not sure, say Y; apart from resulting in a 66 KB bigger
          kernel, it won't hurt.
@@ -1067,7 +1067,7 @@ config APM_REAL_MODE_POWER_OFF
 
 endif # APM
 
-source "arch/i386/kernel/cpu/cpufreq/Kconfig"
+source "arch/x86/kernel/cpu/cpufreq/Kconfig"
 
 endmenu
 
@@ -1240,7 +1240,7 @@ menuconfig INSTRUMENTATION
 
 if INSTRUMENTATION
 
-source "arch/i386/oprofile/Kconfig"
+source "arch/x86/oprofile/Kconfig"
 
 config KPROBES
        bool "Kprobes"
index 52b932478c6dbcf947882e1a483c962bce167f07..5e50dbf00f3e948f69f9ea7885c84a9235cdbb7a 100644 (file)
@@ -17,6 +17,9 @@
 # 20050320  Kianusch Sayah Karadji <kianusch@sk-tech.net>
 #           Added support for GEODE CPU
 
+# Fill in SRCARCH
+SRCARCH        := x86
+
 HAS_BIARCH      := $(call cc-option-yn, -m32)
 ifeq ($(HAS_BIARCH),y)
 AS              := $(AS) --32
@@ -61,62 +64,62 @@ AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONF
 CFLAGS += $(cflags-y)
 
 # Default subarch .c files
-mcore-y  := mach-default
+mcore-y  := arch/x86/mach-default
 
 # Voyager subarch support
-mflags-$(CONFIG_X86_VOYAGER)   := -Iinclude/asm-i386/mach-voyager
-mcore-$(CONFIG_X86_VOYAGER)    := mach-voyager
+mflags-$(CONFIG_X86_VOYAGER)   := -Iinclude/asm-x86/mach-voyager
+mcore-$(CONFIG_X86_VOYAGER)    := arch/x86/mach-voyager
 
 # VISWS subarch support
-mflags-$(CONFIG_X86_VISWS)     := -Iinclude/asm-i386/mach-visws
-mcore-$(CONFIG_X86_VISWS)      := mach-visws
+mflags-$(CONFIG_X86_VISWS)     := -Iinclude/asm-x86/mach-visws
+mcore-$(CONFIG_X86_VISWS)      := arch/x86/mach-visws
 
 # NUMAQ subarch support
-mflags-$(CONFIG_X86_NUMAQ)     := -Iinclude/asm-i386/mach-numaq
-mcore-$(CONFIG_X86_NUMAQ)      := mach-default
+mflags-$(CONFIG_X86_NUMAQ)     := -Iinclude/asm-x86/mach-numaq
+mcore-$(CONFIG_X86_NUMAQ)      := arch/x86/mach-default
 
 # BIGSMP subarch support
-mflags-$(CONFIG_X86_BIGSMP)    := -Iinclude/asm-i386/mach-bigsmp
-mcore-$(CONFIG_X86_BIGSMP)     := mach-default
+mflags-$(CONFIG_X86_BIGSMP)    := -Iinclude/asm-x86/mach-bigsmp
+mcore-$(CONFIG_X86_BIGSMP)     := arch/x86/mach-default
 
 #Summit subarch support
-mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-i386/mach-summit
-mcore-$(CONFIG_X86_SUMMIT)  := mach-default
+mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-x86/mach-summit
+mcore-$(CONFIG_X86_SUMMIT)  := arch/x86/mach-default
 
 # generic subarchitecture
-mflags-$(CONFIG_X86_GENERICARCH) := -Iinclude/asm-i386/mach-generic
-mcore-$(CONFIG_X86_GENERICARCH) := mach-default
-core-$(CONFIG_X86_GENERICARCH) += arch/i386/mach-generic/
+mflags-$(CONFIG_X86_GENERICARCH) := -Iinclude/asm-x86/mach-generic
+mcore-$(CONFIG_X86_GENERICARCH) := arch/x86/mach-default
+core-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/
 
 # ES7000 subarch support
-mflags-$(CONFIG_X86_ES7000)    := -Iinclude/asm-i386/mach-es7000
-mcore-$(CONFIG_X86_ES7000)     := mach-default
-core-$(CONFIG_X86_ES7000)      := arch/i386/mach-es7000/
+mflags-$(CONFIG_X86_ES7000)    := -Iinclude/asm-x86/mach-es7000
+mcore-$(CONFIG_X86_ES7000)     := arch/x86/mach-default
+core-$(CONFIG_X86_ES7000)      := arch/x86/mach-es7000/
 
 # Xen paravirtualization support
-core-$(CONFIG_XEN)             += arch/i386/xen/
+core-$(CONFIG_XEN)             += arch/x86/xen/
 
 # default subarch .h files
-mflags-y += -Iinclude/asm-i386/mach-default
+mflags-y += -Iinclude/asm-x86/mach-default
 
-head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
+head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task_32.o
 
-libs-y                                         += arch/i386/lib/
-core-y                                 += arch/i386/kernel/ \
-                                          arch/i386/mm/ \
-                                          arch/i386/$(mcore-y)/ \
-                                          arch/i386/crypto/
-drivers-$(CONFIG_MATH_EMULATION)       += arch/i386/math-emu/
-drivers-$(CONFIG_PCI)                  += arch/i386/pci/
+libs-y                                         += arch/x86/lib/
+core-y                                 += arch/x86/kernel/ \
+                                          arch/x86/mm/ \
+                                          $(mcore-y)/ \
+                                          arch/x86/crypto/
+drivers-$(CONFIG_MATH_EMULATION)       += arch/x86/math-emu/
+drivers-$(CONFIG_PCI)                  += arch/x86/pci/
 # must be linked after kernel/
-drivers-$(CONFIG_OPROFILE)             += arch/i386/oprofile/
-drivers-$(CONFIG_PM)                   += arch/i386/power/
-drivers-$(CONFIG_FB)                    += arch/i386/video/
+drivers-$(CONFIG_OPROFILE)             += arch/x86/oprofile/
+drivers-$(CONFIG_PM)                   += arch/x86/power/
+drivers-$(CONFIG_FB)                    += arch/x86/video/
 
 CFLAGS += $(mflags-y)
 AFLAGS += $(mflags-y)
 
-boot := arch/i386/boot
+boot := arch/x86/boot
 
 PHONY += zImage bzImage compressed zlilo bzlilo \
          zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install
@@ -125,9 +128,11 @@ all: bzImage
 
 # KBUILD_IMAGE specify target image being built
                     KBUILD_IMAGE := $(boot)/bzImage
-zImage zlilo zdisk: KBUILD_IMAGE := arch/i386/boot/zImage
+zImage zlilo zdisk: KBUILD_IMAGE := arch/x86/boot/zImage
 
 zImage bzImage: vmlinux
+       $(Q)mkdir -p $(objtree)/arch/i386/boot
+       $(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
        $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
 
 compressed: zImage
@@ -145,7 +150,8 @@ install:
        $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
 
 archclean:
-       $(Q)$(MAKE) $(clean)=arch/i386/boot
+       $(Q)rm -rf $(objtree)/arch/i386/boot
+       $(Q)$(MAKE) $(clean)=arch/x86/boot
 
 define archhelp
   echo  '* bzImage     - Compressed kernel image (arch/$(ARCH)/boot/bzImage)'
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
deleted file mode 100644 (file)
index 9d33b00..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-extra-y := head.o init_task.o vmlinux.lds
-
-obj-y  := process.o signal.o entry.o traps.o irq.o \
-               ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
-               pci-dma.o i386_ksyms.o i387.o bootflag.o e820.o\
-               quirks.o i8237.o topology.o alternative.o i8253.o tsc.o
-
-obj-$(CONFIG_STACKTRACE)       += stacktrace.o
-obj-y                          += cpu/
-obj-y                          += acpi/
-obj-$(CONFIG_X86_BIOS_REBOOT)  += reboot.o
-obj-$(CONFIG_MCA)              += mca.o
-obj-$(CONFIG_X86_MSR)          += msr.o
-obj-$(CONFIG_X86_CPUID)                += cpuid.o
-obj-$(CONFIG_MICROCODE)                += microcode.o
-obj-$(CONFIG_APM)              += apm.o
-obj-$(CONFIG_X86_SMP)          += smp.o smpboot.o tsc_sync.o
-obj-$(CONFIG_SMP)              += smpcommon.o
-obj-$(CONFIG_X86_TRAMPOLINE)   += trampoline.o
-obj-$(CONFIG_X86_MPPARSE)      += mpparse.o
-obj-$(CONFIG_X86_LOCAL_APIC)   += apic.o nmi.o
-obj-$(CONFIG_X86_IO_APIC)      += io_apic.o
-obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o
-obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o crash.o
-obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
-obj-$(CONFIG_X86_NUMAQ)                += numaq.o
-obj-$(CONFIG_X86_SUMMIT_NUMA)  += summit.o
-obj-$(CONFIG_KPROBES)          += kprobes.o
-obj-$(CONFIG_MODULES)          += module.o
-obj-y                          += sysenter.o vsyscall.o
-obj-$(CONFIG_ACPI_SRAT)        += srat.o
-obj-$(CONFIG_EFI)              += efi.o efi_stub.o
-obj-$(CONFIG_DOUBLEFAULT)      += doublefault.o
-obj-$(CONFIG_VM86)             += vm86.o
-obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
-obj-$(CONFIG_HPET_TIMER)       += hpet.o
-obj-$(CONFIG_K8_NB)            += k8.o
-obj-$(CONFIG_MGEODE_LX)                += geode.o
-
-obj-$(CONFIG_VMI)              += vmi.o vmiclock.o
-obj-$(CONFIG_PARAVIRT)         += paravirt.o
-obj-y                          += pcspeaker.o
-
-obj-$(CONFIG_SCx200)           += scx200.o
-
-# vsyscall.o contains the vsyscall DSO images as __initdata.
-# We must build both images before we can assemble it.
-# Note: kbuild does not track this dependency due to usage of .incbin
-$(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so
-targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
-targets += vsyscall-note.o vsyscall.lds
-
-# The DSO images are built using a special linker script.
-quiet_cmd_syscall = SYSCALL $@
-      cmd_syscall = $(CC) -m elf_i386 -nostdlib $(SYSCFLAGS_$(@F)) \
-                         -Wl,-T,$(filter-out FORCE,$^) -o $@
-
-export CPPFLAGS_vsyscall.lds += -P -C -U$(ARCH)
-
-vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \
-                $(call ld-option, -Wl$(comma)--hash-style=sysv)
-SYSCFLAGS_vsyscall-sysenter.so = $(vsyscall-flags)
-SYSCFLAGS_vsyscall-int80.so    = $(vsyscall-flags)
-
-$(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so: \
-$(obj)/vsyscall-%.so: $(src)/vsyscall.lds \
-                     $(obj)/vsyscall-%.o $(obj)/vsyscall-note.o FORCE
-       $(call if_changed,syscall)
-
-# We also create a special relocatable object that should mirror the symbol
-# table and layout of the linked DSO.  With ld -R we can then refer to
-# these symbols in the kernel code rather than hand-coded addresses.
-extra-y += vsyscall-syms.o
-$(obj)/built-in.o: $(obj)/vsyscall-syms.o
-$(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o
-
-SYSCFLAGS_vsyscall-syms.o = -r
-$(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
-                       $(obj)/vsyscall-sysenter.o $(obj)/vsyscall-note.o FORCE
-       $(call if_changed,syscall)
-
-k8-y                      += ../../x86_64/kernel/k8.o
-stacktrace-y             += ../../x86_64/kernel/stacktrace.o
-
diff --git a/arch/i386/kernel/early_printk.c b/arch/i386/kernel/early_printk.c
deleted file mode 100644 (file)
index 92f812b..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-#include "../../x86_64/kernel/early_printk.c"
diff --git a/arch/i386/kernel/tsc_sync.c b/arch/i386/kernel/tsc_sync.c
deleted file mode 100644 (file)
index 1242462..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../x86_64/kernel/tsc_sync.c"
diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile
deleted file mode 100644 (file)
index 4d105fd..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for i386-specific library files..
-#
-
-
-lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \
-       bitops.o semaphore.o string.o
-
-lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
-
-obj-$(CONFIG_SMP)      += msr-on-cpu.o
diff --git a/arch/i386/mach-generic/Makefile b/arch/i386/mach-generic/Makefile
deleted file mode 100644 (file)
index 6914485..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for the generic architecture
-#
-
-EXTRA_CFLAGS   := -Iarch/i386/kernel
-
-obj-y                          := probe.o summit.o bigsmp.o es7000.o default.o ../mach-es7000/
diff --git a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile
deleted file mode 100644 (file)
index 80908b5..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Makefile for the linux i386-specific parts of the memory manager.
-#
-
-obj-y  := init.o pgtable.o fault.o ioremap.o extable.o pageattr.o mmap.o
-
-obj-$(CONFIG_NUMA) += discontig.o
-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_HIGHMEM) += highmem.o
-obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
index 8850fe40ea34240a340f11e10eb07e6af8641895..5e901c75df1bda93122aef924613d8a173cb722f 100644 (file)
@@ -1,4 +1,4 @@
-#include <asm-i386/unistd.h>
+#include <asm-x86/unistd_32.h>
 
 unsigned ia32_dir_class[] = {
 #include <asm-generic/audit_dir_write.h>
index 2497554b7b9547a7d176d658ae0f490d517d7144..12d4148dba39aa186aeddcff09be9a8c046a164e 100644 (file)
@@ -9,4 +9,4 @@
 
 #define old_mmap old_mmap_i386
 
-#include "../../i386/kernel/syscall_table.S"
+#include "../../x86/kernel/syscall_table_32.S"
index 5133988d36101c14d87155ed10ae29c28de836de..71b2ae4ad5de17985ee73b97bc43088f67ef2167 100644 (file)
@@ -36,7 +36,7 @@
 
 #define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ;
 #undef _ASM_X86_64_UNISTD_H_
-#include <asm-x86_64/unistd.h>
+#include <asm-x86/unistd_64.h>
 
 #undef __SYSCALL
 #define __SYSCALL(nr, sym) [ nr ] = sym,
@@ -49,5 +49,5 @@ extern void sys_ni_syscall(void);
 sys_call_ptr_t sys_call_table[UM_NR_syscall_max+1] __cacheline_aligned = {
        /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */
        [0 ... UM_NR_syscall_max] = &sys_ni_syscall,
-#include <asm-x86_64/unistd.h>
+#include <asm-x86/unistd_64.h>
 };
similarity index 99%
rename from arch/i386/boot/Makefile
rename to arch/x86/boot/Makefile
index 93386a4e40b49bfcb1b2b8c0be80251594fad283..cb1035f2b7e93654f534d84f1bde58954646a64c 100644 (file)
@@ -1,5 +1,5 @@
 #
-# arch/i386/boot/Makefile
+# arch/x86/boot/Makefile
 #
 # This file is subject to the terms and conditions of the GNU General Public
 # License.  See the file "COPYING" in the main directory of this archive
similarity index 100%
rename from arch/i386/boot/a20.c
rename to arch/x86/boot/a20.c
similarity index 100%
rename from arch/i386/boot/apm.c
rename to arch/x86/boot/apm.c
similarity index 100%
rename from arch/i386/boot/boot.h
rename to arch/x86/boot/boot.h
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
new file mode 100644 (file)
index 0000000..52c1db8
--- /dev/null
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/boot/compressed/Makefile_32
+else
+include ${srctree}/arch/x86/boot/compressed/Makefile_64
+endif
similarity index 80%
rename from arch/i386/boot/compressed/Makefile
rename to arch/x86/boot/compressed/Makefile_32
index 189fa1dbefcc27ece79bac59fc2d11b83d09e38f..22613c652d22d7a6ca5e250f8bfb8c11225ca144 100644 (file)
@@ -1,10 +1,10 @@
 #
-# linux/arch/i386/boot/compressed/Makefile
+# linux/arch/x86/boot/compressed/Makefile
 #
 # create a compressed vmlinux image from the original vmlinux
 #
 
-targets                := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o \
+targets                := vmlinux vmlinux.bin vmlinux.bin.gz head_32.o misc_32.o piggy.o \
                        vmlinux.bin.all vmlinux.relocs
 EXTRA_AFLAGS   := -traditional
 
@@ -17,7 +17,7 @@ CFLAGS  := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
           $(call cc-option,-fno-stack-protector)
 LDFLAGS := -m elf_i386
 
-$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
+$(obj)/vmlinux: $(src)/vmlinux_32.lds $(obj)/head_32.o $(obj)/misc_32.o $(obj)/piggy.o FORCE
        $(call if_changed,ld)
        @:
 
@@ -46,5 +46,5 @@ endif
 
 LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T
 
-$(obj)/piggy.o: $(src)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+$(obj)/piggy.o: $(src)/vmlinux_32.scr $(obj)/vmlinux.bin.gz FORCE
        $(call if_changed,ld)
similarity index 68%
rename from arch/x86_64/boot/compressed/Makefile
rename to arch/x86/boot/compressed/Makefile_64
index 877c0bdbbc67006473a1ca9754721f186910bf61..dc6b3380cc45c27933cd76b740aaf9aefa105701 100644 (file)
@@ -1,10 +1,10 @@
 #
-# linux/arch/x86_64/boot/compressed/Makefile
+# linux/arch/x86/boot/compressed/Makefile
 #
 # create a compressed vmlinux image from the original vmlinux
 #
 
-targets                := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
+targets                := vmlinux vmlinux.bin vmlinux.bin.gz head_64.o misc_64.o piggy.o
 
 CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2  \
          -fno-strict-aliasing -fPIC -mcmodel=small \
@@ -14,7 +14,7 @@ AFLAGS  := $(CFLAGS) -D__ASSEMBLY__
 LDFLAGS := -m elf_x86_64
 
 LDFLAGS_vmlinux := -T
-$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
+$(obj)/vmlinux: $(src)/vmlinux_64.lds $(obj)/head_64.o $(obj)/misc_64.o $(obj)/piggy.o FORCE
        $(call if_changed,ld)
        @:
 
@@ -26,5 +26,5 @@ $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
 
 LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T
 
-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE
+$(obj)/piggy.o: $(obj)/vmlinux_64.scr $(obj)/vmlinux.bin.gz FORCE
        $(call if_changed,ld)
similarity index 99%
rename from arch/x86_64/boot/compressed/head.S
rename to arch/x86/boot/compressed/head_64.S
index 9fd8030cc54ff2e48b05004ddf34e577fb494a85..49467640751fc0eb0a67c96ca7e9fa0b3d973fb0 100644 (file)
@@ -174,7 +174,7 @@ no_longmode:
        hlt
        jmp     1b
 
-#include "../../kernel/verify_cpu.S"
+#include "../../kernel/verify_cpu_64.S"
 
        /* Be careful here startup_64 needs to be at a predictable
         * address so I can export it in an ELF header.  Bootloaders
similarity index 100%
rename from arch/i386/boot/copy.S
rename to arch/x86/boot/copy.S
similarity index 100%
rename from arch/i386/boot/cpu.c
rename to arch/x86/boot/cpu.c
similarity index 100%
rename from arch/i386/boot/edd.c
rename to arch/x86/boot/edd.c
similarity index 100%
rename from arch/i386/boot/main.c
rename to arch/x86/boot/main.c
similarity index 100%
rename from arch/i386/boot/mca.c
rename to arch/x86/boot/mca.c
similarity index 100%
rename from arch/i386/boot/pm.c
rename to arch/x86/boot/pm.c
similarity index 100%
rename from arch/i386/boot/tty.c
rename to arch/x86/boot/tty.c
similarity index 100%
rename from arch/i386/boot/vesa.h
rename to arch/x86/boot/vesa.h
similarity index 100%
rename from arch/i386/boot/video.c
rename to arch/x86/boot/video.c
similarity index 100%
rename from arch/i386/boot/video.h
rename to arch/x86/boot/video.h
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
new file mode 100644 (file)
index 0000000..18dcdc6
--- /dev/null
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/crypto/Makefile_32
+else
+include ${srctree}/arch/x86/crypto/Makefile_64
+endif
similarity index 54%
rename from arch/i386/crypto/Makefile
rename to arch/x86/crypto/Makefile_32
index 3fd19af18e34265f9f937ddd7c5737a2adbd6617..2d873a2388edc15836347970f83235ae0a142af3 100644 (file)
@@ -1,5 +1,5 @@
 # 
-# i386/crypto/Makefile 
+# x86/crypto/Makefile 
 # 
 # Arch-specific CryptoAPI modules.
 # 
@@ -7,6 +7,6 @@
 obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
 obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
 
-aes-i586-y := aes-i586-asm.o aes.o
-twofish-i586-y := twofish-i586-asm.o twofish.o
+aes-i586-y := aes-i586-asm_32.o aes_32.o
+twofish-i586-y := twofish-i586-asm_32.o twofish_32.o
 
similarity index 54%
rename from arch/x86_64/crypto/Makefile
rename to arch/x86/crypto/Makefile_64
index 15b538a8b7f7e73a1b4a37ac9a8c37494850becb..b40896276e93df31d666b5b14090a5db3b7f0185 100644 (file)
@@ -1,5 +1,5 @@
 # 
-# x86_64/crypto/Makefile 
+# x86/crypto/Makefile 
 # 
 # Arch-specific CryptoAPI modules.
 # 
@@ -7,6 +7,6 @@
 obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
 obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
 
-aes-x86_64-y := aes-x86_64-asm.o aes.o
-twofish-x86_64-y := twofish-x86_64-asm.o twofish.o
+aes-x86_64-y := aes-x86_64-asm_64.o aes_64.o
+twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_64.o
 
similarity index 95%
rename from arch/x86_64/ia32/audit.c
rename to arch/x86/ia32/audit.c
index 8850fe40ea34240a340f11e10eb07e6af8641895..91b7b5922dfa8a150d3aaa189fec81e0080033b1 100644 (file)
@@ -1,4 +1,4 @@
-#include <asm-i386/unistd.h>
+#include <asm/unistd_32.h>
 
 unsigned ia32_dir_class[] = {
 #include <asm-generic/audit_dir_write.h>
similarity index 98%
rename from arch/x86_64/ia32/ipc32.c
rename to arch/x86/ia32/ipc32.c
index 369151dc3213e3b152bd6d135dc391b5c40ec623..2e1869ec4db4586b27646cbf6f13a72d757af786 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/ipc.h>
 #include <linux/compat.h>
 
-#include <asm-i386/ipc.h>
+#include <asm/ipc.h>
 
 asmlinkage long
 sys32_ipc(u32 call, int first, int second, int third,
similarity index 73%
rename from arch/x86_64/ia32/syscall32_syscall.S
rename to arch/x86/ia32/syscall32_syscall.S
index 8f8271bdf1355efb86050a38487c0f604d5886b5..933f0f08b1cfaa70526ecb0d571eb4e50069e0c3 100644 (file)
@@ -6,12 +6,12 @@
        .globl syscall32_syscall_end
 
 syscall32_syscall:
-       .incbin "arch/x86_64/ia32/vsyscall-syscall.so"
+       .incbin "arch/x86/ia32/vsyscall-syscall.so"
 syscall32_syscall_end:
 
        .globl syscall32_sysenter
        .globl syscall32_sysenter_end
 
 syscall32_sysenter:
-       .incbin "arch/x86_64/ia32/vsyscall-sysenter.so"
+       .incbin "arch/x86/ia32/vsyscall-sysenter.so"
 syscall32_sysenter_end:
similarity index 99%
rename from arch/x86_64/ia32/vsyscall-sigreturn.S
rename to arch/x86/ia32/vsyscall-sigreturn.S
index 1384367cdbe1f9d53097dd162b659b25e28dcf96..b383be00baec81eba722c5c8f63350a3cdadb245 100644 (file)
@@ -139,5 +139,5 @@ __kernel_rt_sigreturn:
        .align 4
 .LENDFDE3:
 
-#include "../../i386/kernel/vsyscall-note.S"
+#include "../../x86/kernel/vsyscall-note_32.S"
 
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
new file mode 100644 (file)
index 0000000..45855c9
--- /dev/null
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/kernel/Makefile_32
+else
+include ${srctree}/arch/x86/kernel/Makefile_64
+endif
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
new file mode 100644 (file)
index 0000000..c624193
--- /dev/null
@@ -0,0 +1,86 @@
+#
+# Makefile for the linux kernel.
+#
+
+extra-y := head_32.o init_task_32.o vmlinux.lds
+
+obj-y  := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
+               ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
+               pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\
+               quirks.o i8237.o topology.o alternative.o i8253_32.o tsc_32.o
+
+obj-$(CONFIG_STACKTRACE)       += stacktrace.o
+obj-y                          += cpu/
+obj-y                          += acpi/
+obj-$(CONFIG_X86_BIOS_REBOOT)  += reboot_32.o
+obj-$(CONFIG_MCA)              += mca_32.o
+obj-$(CONFIG_X86_MSR)          += msr.o
+obj-$(CONFIG_X86_CPUID)                += cpuid.o
+obj-$(CONFIG_MICROCODE)                += microcode.o
+obj-$(CONFIG_APM)              += apm_32.o
+obj-$(CONFIG_X86_SMP)          += smp_32.o smpboot_32.o tsc_sync.o
+obj-$(CONFIG_SMP)              += smpcommon_32.o
+obj-$(CONFIG_X86_TRAMPOLINE)   += trampoline_32.o
+obj-$(CONFIG_X86_MPPARSE)      += mpparse_32.o
+obj-$(CONFIG_X86_LOCAL_APIC)   += apic_32.o nmi_32.o
+obj-$(CONFIG_X86_IO_APIC)      += io_apic_32.o
+obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o
+obj-$(CONFIG_KEXEC)            += machine_kexec_32.o relocate_kernel_32.o crash_32.o
+obj-$(CONFIG_CRASH_DUMP)       += crash_dump_32.o
+obj-$(CONFIG_X86_NUMAQ)                += numaq_32.o
+obj-$(CONFIG_X86_SUMMIT_NUMA)  += summit_32.o
+obj-$(CONFIG_KPROBES)          += kprobes_32.o
+obj-$(CONFIG_MODULES)          += module_32.o
+obj-y                          += sysenter_32.o vsyscall_32.o
+obj-$(CONFIG_ACPI_SRAT)        += srat_32.o
+obj-$(CONFIG_EFI)              += efi_32.o efi_stub_32.o
+obj-$(CONFIG_DOUBLEFAULT)      += doublefault_32.o
+obj-$(CONFIG_VM86)             += vm86_32.o
+obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
+obj-$(CONFIG_HPET_TIMER)       += hpet_32.o
+obj-$(CONFIG_K8_NB)            += k8.o
+obj-$(CONFIG_MGEODE_LX)                += geode_32.o
+
+obj-$(CONFIG_VMI)              += vmi_32.o vmiclock_32.o
+obj-$(CONFIG_PARAVIRT)         += paravirt_32.o
+obj-y                          += pcspeaker.o
+
+obj-$(CONFIG_SCx200)           += scx200_32.o
+
+# vsyscall_32.o contains the vsyscall DSO images as __initdata.
+# We must build both images before we can assemble it.
+# Note: kbuild does not track this dependency due to usage of .incbin
+$(obj)/vsyscall_32.o: $(obj)/vsyscall-int80_32.so $(obj)/vsyscall-sysenter_32.so
+targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
+targets += vsyscall-note_32.o vsyscall_32.lds
+
+# The DSO images are built using a special linker script.
+quiet_cmd_syscall = SYSCALL $@
+      cmd_syscall = $(CC) -m elf_i386 -nostdlib $(SYSCFLAGS_$(@F)) \
+                         -Wl,-T,$(filter-out FORCE,$^) -o $@
+
+export CPPFLAGS_vsyscall_32.lds += -P -C -U$(ARCH)
+
+vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \
+                $(call ld-option, -Wl$(comma)--hash-style=sysv)
+SYSCFLAGS_vsyscall-sysenter_32.so      = $(vsyscall-flags)
+SYSCFLAGS_vsyscall-int80_32.so = $(vsyscall-flags)
+
+$(obj)/vsyscall-int80_32.so $(obj)/vsyscall-sysenter_32.so: \
+$(obj)/vsyscall-%.so: $(src)/vsyscall_32.lds \
+                     $(obj)/vsyscall-%.o $(obj)/vsyscall-note_32.o FORCE
+       $(call if_changed,syscall)
+
+# We also create a special relocatable object that should mirror the symbol
+# table and layout of the linked DSO.  With ld -R we can then refer to
+# these symbols in the kernel code rather than hand-coded addresses.
+extra-y += vsyscall-syms.o
+$(obj)/built-in.o: $(obj)/vsyscall-syms.o
+$(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o
+
+SYSCFLAGS_vsyscall-syms.o = -r
+$(obj)/vsyscall-syms.o: $(src)/vsyscall_32.lds \
+                       $(obj)/vsyscall-sysenter_32.o $(obj)/vsyscall-note_32.o FORCE
+       $(call if_changed,syscall)
+
+
diff --git a/arch/x86/kernel/Makefile_64 b/arch/x86/kernel/Makefile_64
new file mode 100644 (file)
index 0000000..3ab017a
--- /dev/null
@@ -0,0 +1,54 @@
+#
+# Makefile for the linux kernel.
+#
+
+extra-y        := head_64.o head64.o init_task_64.o vmlinux.lds
+EXTRA_AFLAGS   := -traditional
+obj-y  := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
+               ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \
+               x8664_ksyms_64.o i387_64.o syscall_64.o vsyscall_64.o \
+               setup64.o bootflag.o e820_64.o reboot_64.o quirks.o i8237.o \
+               pci-dma_64.o pci-nommu_64.o alternative.o hpet_64.o tsc_64.o bugs_64.o \
+               perfctr-watchdog.o
+
+obj-$(CONFIG_STACKTRACE)       += stacktrace.o
+obj-$(CONFIG_X86_MCE)          += mce_64.o therm_throt.o
+obj-$(CONFIG_X86_MCE_INTEL)    += mce_intel_64.o
+obj-$(CONFIG_X86_MCE_AMD)      += mce_amd_64.o
+obj-$(CONFIG_MTRR)             += cpu/mtrr/
+obj-$(CONFIG_ACPI)             += acpi/
+obj-$(CONFIG_X86_MSR)          += msr.o
+obj-$(CONFIG_MICROCODE)                += microcode.o
+obj-$(CONFIG_X86_CPUID)                += cpuid.o
+obj-$(CONFIG_SMP)              += smp_64.o smpboot_64.o trampoline_64.o tsc_sync.o
+obj-y                          += apic_64.o  nmi_64.o
+obj-y                          += io_apic_64.o mpparse_64.o genapic_64.o genapic_flat_64.o
+obj-$(CONFIG_KEXEC)            += machine_kexec_64.o relocate_kernel_64.o crash_64.o
+obj-$(CONFIG_CRASH_DUMP)       += crash_dump_64.o
+obj-$(CONFIG_PM)               += suspend_64.o
+obj-$(CONFIG_HIBERNATION)      += suspend_asm_64.o
+obj-$(CONFIG_CPU_FREQ)         += cpu/cpufreq/
+obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
+obj-$(CONFIG_IOMMU)            += pci-gart_64.o aperture_64.o
+obj-$(CONFIG_CALGARY_IOMMU)    += pci-calgary_64.o tce_64.o
+obj-$(CONFIG_SWIOTLB)          += pci-swiotlb_64.o
+obj-$(CONFIG_KPROBES)          += kprobes_64.o
+obj-$(CONFIG_X86_PM_TIMER)     += pmtimer_64.o
+obj-$(CONFIG_X86_VSMP)         += vsmp_64.o
+obj-$(CONFIG_K8_NB)            += k8.o
+obj-$(CONFIG_AUDIT)            += audit_64.o
+
+obj-$(CONFIG_MODULES)          += module_64.o
+obj-$(CONFIG_PCI)              += early-quirks_64.o
+
+obj-y                          += topology.o
+obj-y                          += intel_cacheinfo.o
+obj-y                          += addon_cpuid_features.o
+obj-y                          += pcspeaker.o
+
+CFLAGS_vsyscall_64.o           := $(PROFILING) -g0
+
+therm_throt-y                   += cpu/mcheck/therm_throt.o
+intel_cacheinfo-y              += cpu/intel_cacheinfo.o
+addon_cpuid_features-y         += cpu/addon_cpuid_features.o
+perfctr-watchdog-y             += cpu/perfctr-watchdog.o
diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile
new file mode 100644 (file)
index 0000000..3d56719
--- /dev/null
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/kernel/acpi/Makefile_32
+else
+include ${srctree}/arch/x86/kernel/acpi/Makefile_64
+endif
similarity index 58%
rename from arch/i386/kernel/acpi/Makefile
rename to arch/x86/kernel/acpi/Makefile_32
index 7f7be01f44e66cd27257870d540ed38d3f1e1661..a4852a2e9190c147f1faa66ac3ba271e9f3a8a6c 100644 (file)
@@ -1,8 +1,8 @@
 obj-$(CONFIG_ACPI)             += boot.o
 ifneq ($(CONFIG_PCI),)
-obj-$(CONFIG_X86_IO_APIC)      += earlyquirk.o
+obj-$(CONFIG_X86_IO_APIC)      += earlyquirk_32.o
 endif
-obj-$(CONFIG_ACPI_SLEEP)       += sleep.o wakeup.o
+obj-$(CONFIG_ACPI_SLEEP)       += sleep_32.o wakeup_32.o
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
 obj-y                          += cstate.o processor.o
diff --git a/arch/x86/kernel/acpi/Makefile_64 b/arch/x86/kernel/acpi/Makefile_64
new file mode 100644 (file)
index 0000000..629425b
--- /dev/null
@@ -0,0 +1,7 @@
+obj-y                  := boot.o
+obj-$(CONFIG_ACPI_SLEEP)       += sleep_64.o wakeup_64.o
+
+ifneq ($(CONFIG_ACPI_PROCESSOR),)
+obj-y                  += processor.o cstate.o
+endif
+
similarity index 99%
rename from arch/x86_64/kernel/acpi/wakeup.S
rename to arch/x86/kernel/acpi/wakeup_64.S
index a06f2bcabef9d5f3cfe0928c31d0b753894d6aca..8b4357e1efe0b97dc37b24e5d4cc66321ecfc0cb 100644 (file)
@@ -269,7 +269,7 @@ no_longmode:
        movb    $0xbc,%al       ;  outb %al,$0x80
        jmp no_longmode
 
-#include "../verify_cpu.S"
+#include "../verify_cpu_64.S"
        
 /* This code uses an extended set of video mode numbers. These include:
  * Aliases for standard modes
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
new file mode 100644 (file)
index 0000000..cfa82c8
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "asm-offsets_32.c"
+#else
+# include "asm-offsets_64.c"
+#endif
similarity index 99%
rename from arch/i386/kernel/asm-offsets.c
rename to arch/x86/kernel/asm-offsets_32.c
index 7288ac88d746b550b7cd36cb823213f4e7dc9b50..8029742c0fc127b40cc0249b1abc60a54ab42617 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/personality.h>
 #include <linux/suspend.h>
 #include <asm/ucontext.h>
-#include "sigframe.h"
+#include "sigframe_32.h"
 #include <asm/pgtable.h>
 #include <asm/fixmap.h>
 #include <asm/processor.h>
similarity index 98%
rename from arch/i386/kernel/cpu/mtrr/state.c
rename to arch/x86/kernel/cpu/mtrr/state.c
index c9014ca4a575d3bbd1766bf6a0873bd7e2953e1f..49e20c2afcdf7b4f4e24dc523315f7cb0a1970b0 100644 (file)
@@ -3,7 +3,7 @@
 #include <asm/io.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
-#include <asm-i386/processor-cyrix.h>
+#include <asm/processor-cyrix.h>
 #include "mtrr.h"
 
 
similarity index 99%
rename from arch/i386/kernel/entry.S
rename to arch/x86/kernel/entry_32.S
index a714d6b43506c957c9527aba9b0525b24ad6f925..290b7bc82da3c91d25c00aee470183f53a99c63c 100644 (file)
@@ -1107,6 +1107,6 @@ ENDPROC(xen_failsafe_callback)
 #endif /* CONFIG_XEN */
 
 .section .rodata,"a"
-#include "syscall_table.S"
+#include "syscall_table_32.S"
 
 syscall_table_size=(.-sys_call_table)
similarity index 99%
rename from arch/i386/kernel/head.S
rename to arch/x86/kernel/head_32.S
index 8f0382161c91ec8e0a1c4f75b8ed22824c35eb90..9150ca9b5f809285e987d1ed84db3b353357ae16 100644 (file)
@@ -537,7 +537,7 @@ fault_msg:
        .ascii "Int %d: CR2 %p  err %p  EIP %p  CS %p  flags %p\n"
        .asciz "Stack: %p %p %p %p %p %p %p %p\n"
 
-#include "../xen/xen-head.S"
+#include "../../x86/xen/xen-head.S"
 
 /*
  * The IDT and GDT 'descriptors' are a strange 48-bit object
similarity index 100%
rename from arch/x86_64/kernel/k8.c
rename to arch/x86/kernel/k8.c
similarity index 100%
rename from arch/i386/kernel/msr.c
rename to arch/x86/kernel/msr.c
similarity index 99%
rename from arch/i386/kernel/signal.c
rename to arch/x86/kernel/signal_32.c
index f5dd85656c1890eb93f8d25fc68fb2d97132e917..c03570f7fe8e16482a5c348745f679db6ec79aec 100644 (file)
@@ -25,7 +25,7 @@
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
-#include "sigframe.h"
+#include "sigframe_32.h"
 
 #define DEBUG_SIG 0
 
similarity index 90%
rename from arch/x86_64/kernel/syscall.c
rename to arch/x86/kernel/syscall_64.c
index 63d592c276cc45b6d5e1f761c7af4ce91b687431..9d498c2f8eea89635581d3deaac5a64c592f7882 100644 (file)
@@ -9,7 +9,7 @@
 
 #define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ; 
 #undef _ASM_X86_64_UNISTD_H_
-#include <asm-x86_64/unistd.h>
+#include <asm/unistd_64.h>
 
 #undef __SYSCALL
 #define __SYSCALL(nr, sym) [ nr ] = sym, 
@@ -22,5 +22,5 @@ extern void sys_ni_syscall(void);
 const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
        /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */ 
        [0 ... __NR_syscall_max] = &sys_ni_syscall,
-#include <asm-x86_64/unistd.h>
+#include <asm/unistd_64.h>
 };
similarity index 99%
rename from arch/x86_64/kernel/trampoline.S
rename to arch/x86/kernel/trampoline_64.S
index e7e2764c461b682eb1b7bf42be76fd137e88efc8..607983b0d27b9a5fd1b07d8e4beb41e7516417f1 100644 (file)
@@ -126,7 +126,7 @@ startup_64:
 no_longmode:
        hlt
        jmp no_longmode
-#include "verify_cpu.S"
+#include "verify_cpu_64.S"
 
        # Careful these need to be in the same 64K segment as the above;
 tidt:
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
new file mode 100644 (file)
index 0000000..849ee61
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "vmlinux_32.lds.S"
+#else
+# include "vmlinux_64.lds.S"
+#endif
similarity index 97%
rename from arch/i386/kernel/vsyscall-int80.S
rename to arch/x86/kernel/vsyscall-int80_32.S
index 530d0525e5e23e66d510a837f09853fd4bb5088d..103cab6aa7c031141042a0e131a1f04d33d9bcd7 100644 (file)
@@ -50,4 +50,4 @@ __kernel_vsyscall:
 /*
  * Get the common code for the sigreturn entry points.
  */
-#include "vsyscall-sigreturn.S"
+#include "vsyscall-sigreturn_32.S"
similarity index 95%
rename from arch/i386/kernel/vsyscall-note.S
rename to arch/x86/kernel/vsyscall-note_32.S
index 07c0daf78237bcb1b80ea1401ada31f0f1065cb2..fcf376a37f79c142bb35216234e56e15adf0b41c 100644 (file)
@@ -33,7 +33,7 @@ ELFNOTE_END
  * at boot time we set VDSO_NOTE_NONEGSEG_BIT if running under Xen.
  */
 
-#include "../xen/vdso.h"       /* Defines VDSO_NOTE_NONEGSEG_BIT.  */
+#include "../../x86/xen/vdso.h"        /* Defines VDSO_NOTE_NONEGSEG_BIT.  */
 
        .globl VDSO_NOTE_MASK
 ELFNOTE_START(GNU, 2, "a")
similarity index 99%
rename from arch/i386/kernel/vsyscall-sysenter.S
rename to arch/x86/kernel/vsyscall-sysenter_32.S
index 1a36d26e15eb0c6d370832ee166dd0fba3700f59..ed879bf42995aa6a51ad955c2feff15d7644b28f 100644 (file)
@@ -119,4 +119,4 @@ SYSENTER_RETURN:
 /*
  * Get the common code for the sigreturn entry points.
  */
-#include "vsyscall-sigreturn.S"
+#include "vsyscall-sigreturn_32.S"
similarity index 70%
rename from arch/i386/kernel/vsyscall.S
rename to arch/x86/kernel/vsyscall_32.S
index b403890fe39b35a54ea8f1312790d6fc6434cc6f..a5ab3dc4fd251aeb933bf129d0e883c4af4263b5 100644 (file)
@@ -4,12 +4,12 @@ __INITDATA
 
        .globl vsyscall_int80_start, vsyscall_int80_end
 vsyscall_int80_start:
-       .incbin "arch/i386/kernel/vsyscall-int80.so"
+       .incbin "arch/x86/kernel/vsyscall-int80_32.so"
 vsyscall_int80_end:
 
        .globl vsyscall_sysenter_start, vsyscall_sysenter_end
 vsyscall_sysenter_start:
-       .incbin "arch/i386/kernel/vsyscall-sysenter.so"
+       .incbin "arch/x86/kernel/vsyscall-sysenter_32.so"
 vsyscall_sysenter_end:
 
 __FINIT
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
new file mode 100644 (file)
index 0000000..329da27
--- /dev/null
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/lib/Makefile_32
+else
+include ${srctree}/arch/x86/lib/Makefile_64
+endif
diff --git a/arch/x86/lib/Makefile_32 b/arch/x86/lib/Makefile_32
new file mode 100644 (file)
index 0000000..98d1f1e
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# Makefile for i386-specific library files..
+#
+
+
+lib-y = checksum_32.o delay_32.o usercopy_32.o getuser_32.o putuser_32.o memcpy_32.o strstr_32.o \
+       bitops_32.o semaphore_32.o string_32.o
+
+lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
+
+obj-$(CONFIG_SMP)      += msr-on-cpu.o
diff --git a/arch/x86/lib/Makefile_64 b/arch/x86/lib/Makefile_64
new file mode 100644 (file)
index 0000000..bbabad3
--- /dev/null
@@ -0,0 +1,13 @@
+#
+# Makefile for x86_64-specific library files.
+#
+
+CFLAGS_csum-partial_64.o := -funroll-loops
+
+obj-y := io_64.o iomap_copy_64.o
+obj-$(CONFIG_SMP)      += msr-on-cpu.o
+
+lib-y := csum-partial_64.o csum-copy_64.o csum-wrappers_64.o delay_64.o \
+       usercopy_64.o getuser_64.o putuser_64.o  \
+       thunk_64.o clear_page_64.o copy_page_64.o bitstr_64.o bitops_64.o
+lib-y += memcpy_64.o memmove_64.o memset_64.o copy_user_64.o rwlock_64.o copy_user_nocache_64.o
similarity index 100%
rename from arch/x86_64/lib/io.c
rename to arch/x86/lib/io_64.c
similarity index 100%
rename from arch/i386/lib/mmx.c
rename to arch/x86/lib/mmx_32.c
diff --git a/arch/x86/mach-generic/Makefile b/arch/x86/mach-generic/Makefile
new file mode 100644 (file)
index 0000000..19d6d40
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the generic architecture
+#
+
+EXTRA_CFLAGS   := -Iarch/x86/kernel
+
+obj-y          := probe.o summit.o bigsmp.o es7000.o default.o 
+obj-y          += ../../x86/mach-es7000/
similarity index 80%
rename from arch/i386/mach-voyager/Makefile
rename to arch/x86/mach-voyager/Makefile
index 33b74cf0dd220da24d09d3559fc2b4047d9abf9c..15c250b371d3b580058dccd33b50489965016368 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-EXTRA_CFLAGS   := -Iarch/i386/kernel
+EXTRA_CFLAGS   := -Iarch/x86/kernel
 obj-y                  := setup.o voyager_basic.o voyager_thread.o
 
 obj-$(CONFIG_SMP)      += voyager_smp.o voyager_cat.o
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
new file mode 100644 (file)
index 0000000..9832910
--- /dev/null
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/mm/Makefile_32
+else
+include ${srctree}/arch/x86/mm/Makefile_64
+endif
diff --git a/arch/x86/mm/Makefile_32 b/arch/x86/mm/Makefile_32
new file mode 100644 (file)
index 0000000..362b4ad
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Makefile for the linux i386-specific parts of the memory manager.
+#
+
+obj-y  := init_32.o pgtable_32.o fault_32.o ioremap_32.o extable_32.o pageattr_32.o mmap_32.o
+
+obj-$(CONFIG_NUMA) += discontig_32.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+obj-$(CONFIG_HIGHMEM) += highmem_32.o
+obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap_32.o
diff --git a/arch/x86/mm/Makefile_64 b/arch/x86/mm/Makefile_64
new file mode 100644 (file)
index 0000000..6bcb479
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Makefile for the linux x86_64-specific parts of the memory manager.
+#
+
+obj-y   := init_64.o fault_64.o ioremap_64.o extable_64.o pageattr_64.o mmap_64.o
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+obj-$(CONFIG_NUMA) += numa_64.o
+obj-$(CONFIG_K8_NUMA) += k8topology_64.o
+obj-$(CONFIG_ACPI_NUMA) += srat_64.o
+
similarity index 100%
rename from arch/i386/mm/fault.c
rename to arch/x86/mm/fault_32.c
similarity index 100%
rename from arch/i386/mm/init.c
rename to arch/x86/mm/init_32.c
similarity index 100%
rename from arch/x86_64/mm/init.c
rename to arch/x86/mm/init_64.c
similarity index 100%
rename from arch/i386/mm/mmap.c
rename to arch/x86/mm/mmap_32.c
similarity index 100%
rename from arch/x86_64/mm/mmap.c
rename to arch/x86/mm/mmap_64.c
similarity index 100%
rename from arch/x86_64/mm/numa.c
rename to arch/x86/mm/numa_64.c
similarity index 100%
rename from arch/x86_64/mm/srat.c
rename to arch/x86/mm/srat_64.c
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
new file mode 100644 (file)
index 0000000..c5c8e48
--- /dev/null
@@ -0,0 +1,5 @@
+ifeq ($(CONFIG_X86_32),y)
+include ${srctree}/arch/x86/pci/Makefile_32
+else
+include ${srctree}/arch/x86/pci/Makefile_64
+endif
similarity index 81%
rename from arch/i386/pci/Makefile
rename to arch/x86/pci/Makefile_32
index 44650e03308b0ad6d849abc0dcc0645800292be5..cdd6828b5abb4015f91091cf4ccc5d1a6432ded0 100644 (file)
@@ -1,7 +1,7 @@
 obj-y                          := i386.o init.o
 
 obj-$(CONFIG_PCI_BIOS)         += pcbios.o
-obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig.o direct.o mmconfig-shared.o
+obj-$(CONFIG_PCI_MMCONFIG)     += mmconfig_32.o direct.o mmconfig-shared.o
 obj-$(CONFIG_PCI_DIRECT)       += direct.o
 
 pci-y                          := fixup.o
diff --git a/arch/x86/pci/Makefile_64 b/arch/x86/pci/Makefile_64
new file mode 100644 (file)
index 0000000..7d8c467
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# Makefile for X86_64 specific PCI routines
+#
+# Reuse the i386 PCI subsystem
+#
+EXTRA_CFLAGS += -Iarch/x86/pci
+
+obj-y          := i386.o
+obj-$(CONFIG_PCI_DIRECT)+= direct.o
+obj-y          += fixup.o init.o
+obj-$(CONFIG_ACPI)     += acpi.o
+obj-y                  += legacy.o irq.o common.o early.o
+# mmconfig has a 64bit special
+obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o
+
+obj-$(CONFIG_NUMA)     += k8-bus_64.o
+
similarity index 100%
rename from arch/i386/pci/acpi.c
rename to arch/x86/pci/acpi.c
similarity index 100%
rename from arch/i386/pci/common.c
rename to arch/x86/pci/common.c
similarity index 100%
rename from arch/i386/pci/direct.c
rename to arch/x86/pci/direct.c
similarity index 100%
rename from arch/i386/pci/early.c
rename to arch/x86/pci/early.c
similarity index 100%
rename from arch/i386/pci/fixup.c
rename to arch/x86/pci/fixup.c
similarity index 100%
rename from arch/i386/pci/i386.c
rename to arch/x86/pci/i386.c
similarity index 100%
rename from arch/i386/pci/init.c
rename to arch/x86/pci/init.c
similarity index 100%
rename from arch/i386/pci/irq.c
rename to arch/x86/pci/irq.c
similarity index 100%
rename from arch/i386/pci/legacy.c
rename to arch/x86/pci/legacy.c
similarity index 100%
rename from arch/i386/pci/numa.c
rename to arch/x86/pci/numa.c
similarity index 100%
rename from arch/i386/pci/pcbios.c
rename to arch/x86/pci/pcbios.c
similarity index 100%
rename from arch/i386/pci/pci.h
rename to arch/x86/pci/pci.h
similarity index 100%
rename from arch/i386/pci/visws.c
rename to arch/x86/pci/visws.c
similarity index 100%
rename from arch/i386/power/cpu.c
rename to arch/x86/power/cpu.c
diff --git a/arch/x86/vdso/vdso.S b/arch/x86/vdso/vdso.S
new file mode 100644 (file)
index 0000000..4b1620a
--- /dev/null
@@ -0,0 +1,2 @@
+       .section ".vdso","a"
+       .incbin "arch/x86/vdso/vdso.so"
similarity index 100%
rename from arch/x86_64/vdso/vma.c
rename to arch/x86/vdso/vma.c
similarity index 100%
rename from arch/x86_64/vdso/vvar.c
rename to arch/x86/vdso/vvar.c
similarity index 100%
rename from arch/i386/xen/Kconfig
rename to arch/x86/xen/Kconfig
similarity index 100%
rename from arch/i386/xen/Makefile
rename to arch/x86/xen/Makefile
similarity index 100%
rename from arch/i386/xen/events.c
rename to arch/x86/xen/events.c
similarity index 100%
rename from arch/i386/xen/manage.c
rename to arch/x86/xen/manage.c
similarity index 100%
rename from arch/i386/xen/mmu.c
rename to arch/x86/xen/mmu.c
similarity index 100%
rename from arch/i386/xen/mmu.h
rename to arch/x86/xen/mmu.h
similarity index 100%
rename from arch/i386/xen/setup.c
rename to arch/x86/xen/setup.c
similarity index 100%
rename from arch/i386/xen/smp.c
rename to arch/x86/xen/smp.c
similarity index 100%
rename from arch/i386/xen/time.c
rename to arch/x86/xen/time.c
similarity index 100%
rename from arch/i386/xen/vdso.h
rename to arch/x86/xen/vdso.h
index b4d9089a6a06736cf5c8b9fc2ac1955a8ad19360..b1b98e614f7cd2982ae9646c2b6188d234d233d4 100644 (file)
@@ -704,7 +704,7 @@ source kernel/power/Kconfig
 
 source "drivers/acpi/Kconfig"
 
-source "arch/x86_64/kernel/cpufreq/Kconfig"
+source "arch/x86/kernel/cpufreq/Kconfig"
 
 endmenu
 
@@ -778,7 +778,7 @@ source fs/Kconfig
 menu "Instrumentation Support"
         depends on EXPERIMENTAL
 
-source "arch/x86_64/oprofile/Kconfig"
+source "arch/x86/oprofile/Kconfig"
 
 config KPROBES
        bool "Kprobes"
index b024e4a86895cea767fa5090074f75b60e0d7078..8bffb94c71b50d72605306651f59cdad46ff2e27 100644 (file)
@@ -21,6 +21,9 @@
 #
 # $Id: Makefile,v 1.31 2002/03/22 15:56:07 ak Exp $
 
+# Fill in SRCARCH
+SRCARCH        := x86
+
 LDFLAGS                := -m elf_x86_64
 OBJCOPYFLAGS   := -O binary -R .note -R .comment -S
 LDFLAGS_vmlinux :=
@@ -71,18 +74,18 @@ CFLAGS += $(cflags-y)
 CFLAGS_KERNEL += $(cflags-kernel-y)
 AFLAGS += -m64
 
-head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
+head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task_64.o
 
-libs-y                                         += arch/x86_64/lib/
-core-y                                 += arch/x86_64/kernel/ \
-                                          arch/x86_64/mm/ \
-                                          arch/x86_64/crypto/ \
-                                          arch/x86_64/vdso/
-core-$(CONFIG_IA32_EMULATION)          += arch/x86_64/ia32/
-drivers-$(CONFIG_PCI)                  += arch/x86_64/pci/
-drivers-$(CONFIG_OPROFILE)             += arch/x86_64/oprofile/
+libs-y                                         += arch/x86/lib/
+core-y                                 += arch/x86/kernel/ \
+                                          arch/x86/mm/ \
+                                          arch/x86/crypto/ \
+                                          arch/x86/vdso/
+core-$(CONFIG_IA32_EMULATION)          += arch/x86/ia32/
+drivers-$(CONFIG_PCI)                  += arch/x86/pci/
+drivers-$(CONFIG_OPROFILE)             += arch/x86/oprofile/
 
-boot := arch/x86_64/boot
+boot := arch/x86/boot
 
 PHONY += bzImage bzlilo install archmrproper \
         fdimage fdimage144 fdimage288 isoimage archclean
@@ -90,10 +93,12 @@ PHONY += bzImage bzlilo install archmrproper \
 #Default target when executing "make"
 all: bzImage
 
-BOOTIMAGE                     := arch/x86_64/boot/bzImage
+BOOTIMAGE                     := arch/x86/boot/bzImage
 KBUILD_IMAGE                  := $(BOOTIMAGE)
 
 bzImage: vmlinux
+       $(Q)mkdir -p $(objtree)/arch/x86_64/boot
+       $(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
        $(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
 
 bzlilo: vmlinux
@@ -109,6 +114,7 @@ install:
        $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ 
 
 archclean:
+       $(Q)rm -rf $(objtree)/arch/x86_64/boot
        $(Q)$(MAKE) $(clean)=$(boot)
 
 define archhelp
diff --git a/arch/x86_64/boot/.gitignore b/arch/x86_64/boot/.gitignore
deleted file mode 100644 (file)
index 1846514..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-bootsect
-bzImage
-setup
-setup.bin
-setup.elf
diff --git a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile
deleted file mode 100644 (file)
index 6709638..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# arch/x86_64/boot/Makefile
-#
-# The actual boot code is shared with i386 including the Makefile.
-# So tell kbuild that we fetch the code from i386 and include the
-# Makefile from i386 too.
-
-src := arch/i386/boot
-include $(src)/Makefile
diff --git a/arch/x86_64/boot/tools/.gitignore b/arch/x86_64/boot/tools/.gitignore
deleted file mode 100644 (file)
index 378eac2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-build
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
deleted file mode 100644 (file)
index ff5d8c9..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-extra-y        := head.o head64.o init_task.o vmlinux.lds
-EXTRA_AFLAGS   := -traditional
-obj-y  := process.o signal.o entry.o traps.o irq.o \
-               ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \
-               x8664_ksyms.o i387.o syscall.o vsyscall.o \
-               setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \
-               pci-dma.o pci-nommu.o alternative.o hpet.o tsc.o bugs.o \
-               perfctr-watchdog.o
-
-obj-$(CONFIG_STACKTRACE)       += stacktrace.o
-obj-$(CONFIG_X86_MCE)          += mce.o therm_throt.o
-obj-$(CONFIG_X86_MCE_INTEL)    += mce_intel.o
-obj-$(CONFIG_X86_MCE_AMD)      += mce_amd.o
-obj-$(CONFIG_MTRR)             += ../../i386/kernel/cpu/mtrr/
-obj-$(CONFIG_ACPI)             += acpi/
-obj-$(CONFIG_X86_MSR)          += msr.o
-obj-$(CONFIG_MICROCODE)                += microcode.o
-obj-$(CONFIG_X86_CPUID)                += cpuid.o
-obj-$(CONFIG_SMP)              += smp.o smpboot.o trampoline.o tsc_sync.o
-obj-y                          += apic.o  nmi.o
-obj-y                          += io_apic.o mpparse.o genapic.o genapic_flat.o
-obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o crash.o
-obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
-obj-$(CONFIG_PM)               += suspend.o
-obj-$(CONFIG_HIBERNATION)      += suspend_asm.o
-obj-$(CONFIG_CPU_FREQ)         += cpufreq/
-obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
-obj-$(CONFIG_IOMMU)            += pci-gart.o aperture.o
-obj-$(CONFIG_CALGARY_IOMMU)    += pci-calgary.o tce.o
-obj-$(CONFIG_SWIOTLB)          += pci-swiotlb.o
-obj-$(CONFIG_KPROBES)          += kprobes.o
-obj-$(CONFIG_X86_PM_TIMER)     += pmtimer.o
-obj-$(CONFIG_X86_VSMP)         += vsmp.o
-obj-$(CONFIG_K8_NB)            += k8.o
-obj-$(CONFIG_AUDIT)            += audit.o
-
-obj-$(CONFIG_MODULES)          += module.o
-obj-$(CONFIG_PCI)              += early-quirks.o
-
-obj-y                          += topology.o
-obj-y                          += intel_cacheinfo.o
-obj-y                          += addon_cpuid_features.o
-obj-y                          += pcspeaker.o
-
-CFLAGS_vsyscall.o              := $(PROFILING) -g0
-
-therm_throt-y                   += ../../i386/kernel/cpu/mcheck/therm_throt.o
-bootflag-y                     += ../../i386/kernel/bootflag.o
-cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  += ../../i386/kernel/cpuid.o
-topology-y                     += ../../i386/kernel/topology.o
-microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
-intel_cacheinfo-y              += ../../i386/kernel/cpu/intel_cacheinfo.o
-addon_cpuid_features-y         += ../../i386/kernel/cpu/addon_cpuid_features.o
-quirks-y                       += ../../i386/kernel/quirks.o
-i8237-y                                += ../../i386/kernel/i8237.o
-msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
-alternative-y                  += ../../i386/kernel/alternative.o
-pcspeaker-y                    += ../../i386/kernel/pcspeaker.o
-perfctr-watchdog-y             += ../../i386/kernel/cpu/perfctr-watchdog.o
diff --git a/arch/x86_64/kernel/acpi/Makefile b/arch/x86_64/kernel/acpi/Makefile
deleted file mode 100644 (file)
index 080b996..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-obj-y                  := boot.o
-boot-y                 := ../../../i386/kernel/acpi/boot.o
-obj-$(CONFIG_ACPI_SLEEP)       += sleep.o wakeup.o
-
-ifneq ($(CONFIG_ACPI_PROCESSOR),)
-obj-y                  += processor.o
-processor-y            := ../../../i386/kernel/acpi/processor.o ../../../i386/kernel/acpi/cstate.o
-endif
-
diff --git a/arch/x86_64/kernel/cpufreq/Makefile b/arch/x86_64/kernel/cpufreq/Makefile
deleted file mode 100644 (file)
index 753ce1d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Reuse the i386 cpufreq drivers
-#
-
-SRCDIR := ../../../i386/kernel/cpu/cpufreq
-
-obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
-obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
-obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
-obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
-obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o
-
-powernow-k8-objs := ${SRCDIR}/powernow-k8.o
-speedstep-centrino-objs := ${SRCDIR}/speedstep-centrino.o
-acpi-cpufreq-objs := ${SRCDIR}/acpi-cpufreq.o
-p4-clockmod-objs := ${SRCDIR}/p4-clockmod.o
-speedstep-lib-objs := ${SRCDIR}/speedstep-lib.o
diff --git a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile
deleted file mode 100644 (file)
index c943271..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Makefile for x86_64-specific library files.
-#
-
-CFLAGS_csum-partial.o := -funroll-loops
-
-obj-y := io.o iomap_copy.o
-obj-$(CONFIG_SMP)      += msr-on-cpu.o
-
-lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \
-       usercopy.o getuser.o putuser.o  \
-       thunk.o clear_page.o copy_page.o bitstr.o bitops.o
-lib-y += memcpy.o memmove.o memset.o copy_user.o rwlock.o copy_user_nocache.o
diff --git a/arch/x86_64/lib/msr-on-cpu.c b/arch/x86_64/lib/msr-on-cpu.c
deleted file mode 100644 (file)
index 47e0ec4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../i386/lib/msr-on-cpu.c"
diff --git a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile
deleted file mode 100644 (file)
index d25ac86..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the linux x86_64-specific parts of the memory manager.
-#
-
-obj-y   := init.o fault.o ioremap.o extable.o pageattr.o mmap.o
-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_NUMA) += numa.o
-obj-$(CONFIG_K8_NUMA) += k8topology.o
-obj-$(CONFIG_ACPI_NUMA) += srat.o
-
-hugetlbpage-y = ../../i386/mm/hugetlbpage.o
diff --git a/arch/x86_64/oprofile/Kconfig b/arch/x86_64/oprofile/Kconfig
deleted file mode 100644 (file)
index d8a8408..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-config PROFILING
-       bool "Profiling support (EXPERIMENTAL)"
-       help
-         Say Y here to enable the extended profiling support mechanisms used
-         by profilers such as OProfile.
-         
-
-config OPROFILE
-       tristate "OProfile system profiling (EXPERIMENTAL)"
-       depends on PROFILING
-       help
-         OProfile is a profiling system capable of profiling the
-         whole system, include the kernel, kernel modules, libraries,
-         and applications.
-
-         If unsure, say N.
-
diff --git a/arch/x86_64/oprofile/Makefile b/arch/x86_64/oprofile/Makefile
deleted file mode 100644 (file)
index 6be3268..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# oprofile for x86-64.
-# Just reuse the one from i386. 
-#
-
-obj-$(CONFIG_OPROFILE) += oprofile.o
-DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
-       oprof.o cpu_buffer.o buffer_sync.o \
-       event_buffer.o oprofile_files.o \
-       oprofilefs.o oprofile_stats.o \
-       timer_int.o )
-
-OPROFILE-y := init.o backtrace.o
-OPROFILE-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o op_model_p4.o \
-                                    op_model_ppro.o
-OPROFILE-$(CONFIG_X86_IO_APIC)    += nmi_timer_int.o 
-
-oprofile-y = $(DRIVER_OBJS) $(addprefix ../../i386/oprofile/, $(OPROFILE-y))
diff --git a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile
deleted file mode 100644 (file)
index c9eddc8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Makefile for X86_64 specific PCI routines
-#
-# Reuse the i386 PCI subsystem
-#
-EXTRA_CFLAGS += -Iarch/i386/pci
-
-obj-y          := i386.o
-obj-$(CONFIG_PCI_DIRECT)+= direct.o
-obj-y          += fixup.o init.o
-obj-$(CONFIG_ACPI)     += acpi.o
-obj-y                  += legacy.o irq.o common.o early.o
-# mmconfig has a 64bit special
-obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o mmconfig-shared.o
-
-obj-$(CONFIG_NUMA)     += k8-bus.o
-
-direct-y += ../../i386/pci/direct.o
-acpi-y   += ../../i386/pci/acpi.o
-legacy-y += ../../i386/pci/legacy.o
-irq-y    += ../../i386/pci/irq.o
-common-y += ../../i386/pci/common.o
-fixup-y  += ../../i386/pci/fixup.o
-i386-y  += ../../i386/pci/i386.o
-init-y += ../../i386/pci/init.o
-early-y += ../../i386/pci/early.o
-mmconfig-shared-y += ../../i386/pci/mmconfig-shared.o
diff --git a/arch/x86_64/vdso/vdso.S b/arch/x86_64/vdso/vdso.S
deleted file mode 100644 (file)
index 92e80c1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-       .section ".vdso","a"
-       .incbin "arch/x86_64/vdso/vdso.so"
index d9d033e07e197cb0496218fc3f334bc1b33f06cf..dd9bd4310c848cabf6c5a6b415695ef299209868 100644 (file)
@@ -69,13 +69,79 @@ source "drivers/media/common/Kconfig"
 config VIDEO_TUNER
        tristate
        depends on I2C
+       select TUNER_MT20XX if !VIDEO_TUNER_CUSTOMIZE
+       select TUNER_TDA8290 if !VIDEO_TUNER_CUSTOMIZE
+       select TUNER_TEA5761 if !VIDEO_TUNER_CUSTOMIZE
+       select TUNER_TEA5767 if !VIDEO_TUNER_CUSTOMIZE
+       select TUNER_SIMPLE if !VIDEO_TUNER_CUSTOMIZE
+
+menuconfig VIDEO_TUNER_CUSTOMIZE
+       bool "Customize analog tuner modules to build"
+       depends on VIDEO_TUNER
+       help
+         This allows the user to deselect tuner drivers unnecessary
+         for their hardware from the build. Use this option with care
+         as deselecting tuner drivers which are in fact necessary will
+         result in V4L devices which cannot be tuned due to lack of
+         driver support
+
+         If unsure say N.
+
+if VIDEO_TUNER_CUSTOMIZE
+
+config TUNER_MT20XX
+       tristate "Microtune 2032 / 2050 tuners"
+       depends on I2C
+       default m if VIDEO_TUNER_CUSTOMIZE
+       help
+         Say Y here to include support for the MT2032 / MT2050 tuner.
+
+config TUNER_TDA8290
+       tristate "TDA 8290+8275(a) tuner combo"
+       depends on I2C
+       default m if VIDEO_TUNER_CUSTOMIZE
+       help
+         Say Y here to include support for Philips TDA8290+8275(a) tuner.
+
+config TUNER_TEA5761
+       tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
+       depends on I2C && EXPERIMENTAL
+       default m if VIDEO_TUNER_CUSTOMIZE
+       help
+         Say Y here to include support for the Philips TEA5761 radio tuner.
+
+config TUNER_TEA5767
+       tristate "TEA 5767 radio tuner"
+       depends on I2C
+       default m if VIDEO_TUNER_CUSTOMIZE
+       help
+         Say Y here to include support for the Philips TEA5767 radio tuner.
+
+config TUNER_SIMPLE
+       tristate "Simple tuner support"
+       depends on I2C
+       default m if VIDEO_TUNER_CUSTOMIZE
+       help
+         Say Y here to include support for various simple tuners.
 
-config VIDEO_BUF
+endif # VIDEO_TUNER_CUSTOMIZE
+
+config VIDEOBUF_GEN
+       tristate
+
+config VIDEOBUF_DMA_SG
        depends on PCI
+       select VIDEOBUF_GEN
+       tristate
+
+config VIDEOBUF_VMALLOC
+       select VIDEOBUF_GEN
        tristate
 
-config VIDEO_BUF_DVB
+config VIDEOBUF_DVB
        tristate
+       select VIDEOBUF_GEN
+       select VIDEOBUF_DMA_SG
 
 config VIDEO_BTCX
        tristate
index 5c63c8e24ee74babe23ec1dcdd2434a8e45b30dd..c5092ef1082f1436d4fe6f4ef8f5e8bc7d8f6791 100644 (file)
@@ -5,5 +5,5 @@ config VIDEO_SAA7146
 config VIDEO_SAA7146_VV
        tristate
        depends on VIDEO_DEV
-       select VIDEO_BUF
+       select VIDEOBUF_DMA_SG
        select VIDEO_SAA7146
index a3292e955aaaa136822a0ed5b863cd1f1b3c5508..e7c3ab951a44a25e9b37e06ea7eba22226e80725 100644 (file)
@@ -21,7 +21,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/jiffies.h>
 #include <media/ir-common.h>
index cbd1184b5219becd3723ccc14fc4eb42d33c36f5..aefcf28da1cae1ee0a8dbeddb29e3c026d702d65 100644 (file)
@@ -20,7 +20,6 @@
 
  */
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 
 #include <linux/input.h>
 #include <media/ir-common.h>
@@ -1783,3 +1782,64 @@ IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
 };
 
 EXPORT_SYMBOL_GPL(ir_codes_tt_1500);
+
+/* DViCO FUSION HDTV MCE remote */
+IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE] = {
+
+       [ 0x0b ] = KEY_1,
+       [ 0x17 ] = KEY_2,
+       [ 0x1b ] = KEY_3,
+       [ 0x07 ] = KEY_4,
+       [ 0x50 ] = KEY_5,
+       [ 0x54 ] = KEY_6,
+       [ 0x48 ] = KEY_7,
+       [ 0x4c ] = KEY_8,
+       [ 0x58 ] = KEY_9,
+       [ 0x03 ] = KEY_0,
+
+       [ 0x5e ] = KEY_OK,
+       [ 0x51 ] = KEY_UP,
+       [ 0x53 ] = KEY_DOWN,
+       [ 0x5b ] = KEY_LEFT,
+       [ 0x5f ] = KEY_RIGHT,
+
+       [ 0x02 ] = KEY_TV,              /* Labeled DTV on remote */
+       [ 0x0e ] = KEY_MP3,
+       [ 0x1a ] = KEY_DVD,
+       [ 0x1e ] = KEY_FAVORITES,       /* Labeled CPF on remote */
+       [ 0x16 ] = KEY_SETUP,
+       [ 0x46 ] = KEY_POWER2,          /* TV On/Off button on remote */
+       [ 0x0a ] = KEY_EPG,             /* Labeled Guide on remote */
+
+       [ 0x49 ] = KEY_BACK,
+       [ 0x59 ] = KEY_INFO,            /* Labeled MORE on remote */
+       [ 0x4d ] = KEY_MENU,            /* Labeled DVDMENU on remote */
+       [ 0x55 ] = KEY_CYCLEWINDOWS,    /* Labeled ALT-TAB on remote */
+
+       [ 0x0f ] = KEY_PREVIOUSSONG,    /* Labeled |<< REPLAY on remote */
+       [ 0x12 ] = KEY_NEXTSONG,        /* Labeled >>| SKIP on remote */
+       [ 0x42 ] = KEY_ENTER,           /* Labeled START with a green
+                                        * MS windows logo on remote */
+
+       [ 0x15 ] = KEY_VOLUMEUP,
+       [ 0x05 ] = KEY_VOLUMEDOWN,
+       [ 0x11 ] = KEY_CHANNELUP,
+       [ 0x09 ] = KEY_CHANNELDOWN,
+
+       [ 0x52 ] = KEY_CAMERA,
+       [ 0x5a ] = KEY_TUNER,
+       [ 0x19 ] = KEY_OPEN,
+
+       [ 0x13 ] = KEY_MODE,            /* 4:3 16:9 select */
+       [ 0x1f ] = KEY_ZOOM,
+
+       [ 0x43 ] = KEY_REWIND,
+       [ 0x47 ] = KEY_PLAYPAUSE,
+       [ 0x4f ] = KEY_FASTFORWARD,
+       [ 0x57 ] = KEY_MUTE,
+       [ 0x0d ] = KEY_STOP,
+       [ 0x01 ] = KEY_RECORD,
+       [ 0x4e ] = KEY_POWER,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce);
index ba6701e97671ad0d37c474f5f3498f2f10b1d2b4..365a22118a0914c3eb3102af30463694e7cdb6c1 100644 (file)
@@ -100,7 +100,7 @@ int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
  * general helper functions
  ****************************************************************************/
 
-/* this is videobuf_vmalloc_to_sg() from video-buf.c
+/* this is videobuf_vmalloc_to_sg() from videobuf-dma-sg.c
    make sure virt has been allocated with vmalloc_32(), otherwise the BUG()
    may be triggered on highmem machines */
 static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
@@ -248,10 +248,11 @@ int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt
 static irqreturn_t interrupt_hw(int irq, void *dev_id)
 {
        struct saa7146_dev *dev = dev_id;
-       u32 isr = 0;
+       u32 isr;
+       u32 ack_isr;
 
        /* read out the interrupt status register */
-       isr = saa7146_read(dev, ISR);
+       ack_isr = isr = saa7146_read(dev, ISR);
 
        /* is this our interrupt? */
        if ( 0 == isr ) {
@@ -259,8 +260,6 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
                return IRQ_NONE;
        }
 
-       saa7146_write(dev, ISR, isr);
-
        if( 0 != (dev->ext)) {
                if( 0 != (dev->ext->irq_mask & isr )) {
                        if( 0 != dev->ext->irq_func ) {
@@ -283,21 +282,16 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
                isr &= ~MASK_28;
        }
        if (0 != (isr & (MASK_16|MASK_17))) {
-               u32 status = saa7146_read(dev, I2C_STATUS);
-               if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) {
-                       SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
-                       /* only wake up if we expect something */
-                       if( 0 != dev->i2c_op ) {
-                               u32 psr = (saa7146_read(dev, PSR) >> 16) & 0x2;
-                               u32 ssr = (saa7146_read(dev, SSR) >> 17) & 0x1f;
-                               DEB_I2C(("irq: i2c, status: 0x%08x, psr:0x%02x, ssr:0x%02x).\n",status,psr,ssr));
-                               dev->i2c_op = 0;
-                               wake_up(&dev->i2c_wq);
-                       } else {
-                               DEB_I2C(("unexpected irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
-                       }
+               SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
+               /* only wake up if we expect something */
+               if (0 != dev->i2c_op) {
+                       dev->i2c_op = 0;
+                       wake_up(&dev->i2c_wq);
                } else {
-                       DEB_I2C(("unhandled irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
+                       u32 psr = saa7146_read(dev, PSR);
+                       u32 ssr = saa7146_read(dev, SSR);
+                       printk(KERN_WARNING "%s: unexpected i2c irq: isr %08x psr %08x ssr %08x\n",
+                              dev->name, isr, psr, ssr);
                }
                isr &= ~(MASK_16|MASK_17);
        }
@@ -306,6 +300,7 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
                ERR(("disabling interrupt source(s)!\n"));
                SAA7146_IER_DISABLE(dev,isr);
        }
+       saa7146_write(dev, ISR, ack_isr);
        return IRQ_HANDLED;
 }
 
@@ -548,7 +543,6 @@ EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
 
 EXPORT_SYMBOL_GPL(saa7146_setgpio);
 
-EXPORT_SYMBOL_GPL(saa7146_i2c_transfer);
 EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);
 
 EXPORT_SYMBOL_GPL(saa7146_debug);
index b4770aecc01db56afd363b9fcedbdfe49be90a20..67d1b1b1b25420245ca5e28de9e45cf4dd65e95b 100644 (file)
@@ -53,13 +53,14 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
 void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
                                                struct saa7146_buf *buf)
 {
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
        DEB_EE(("dev:%p, buf:%p\n",dev,buf));
 
        BUG_ON(in_interrupt());
 
        videobuf_waiton(&buf->vb,0,0);
-       videobuf_dma_unmap(q, &buf->vb.dma);
-       videobuf_dma_free(&buf->vb.dma);
+       videobuf_dma_unmap(q, dma);
+       videobuf_dma_free(dma);
        buf->vb.state = STATE_NEEDS_INIT;
 }
 
index 8c85efc26527fe9bf5bdd85473f014b568871876..7e7689afae629c0a012979dc56a2dc6f30ade7d3 100644 (file)
@@ -202,7 +202,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
                                /* a signal arrived */
                                return -ERESTARTSYS;
 
-                       printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for end of xfer\n");
+                       printk(KERN_WARNING "%s %s [irq]: timed out waiting for end of xfer\n",
+                               dev->name, __FUNCTION__);
                        return -EIO;
                }
                status = saa7146_read(dev, I2C_STATUS);
@@ -219,7 +220,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
                                break;
                        }
                        if (time_after(jiffies,timeout)) {
-                               printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for MC2\n");
+                               printk(KERN_WARNING "%s %s: timed out waiting for MC2\n",
+                                       dev->name, __FUNCTION__);
                                return -EIO;
                        }
                }
@@ -235,7 +237,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
                                /* this is normal when probing the bus
                                 * (no answer from nonexisistant device...)
                                 */
-                               DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n"));
+                               printk(KERN_WARNING "%s %s [poll]: timed out waiting for end of xfer\n",
+                                       dev->name, __FUNCTION__);
                                return -EIO;
                        }
                        if (++trial < 50 && short_delay)
@@ -246,8 +249,16 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
        }
 
        /* give a detailed status report */
-       if ( 0 != (status & SAA7146_I2C_ERR)) {
-
+       if ( 0 != (status & (SAA7146_I2C_SPERR | SAA7146_I2C_APERR |
+                            SAA7146_I2C_DTERR | SAA7146_I2C_DRERR |
+                            SAA7146_I2C_AL    | SAA7146_I2C_ERR   |
+                            SAA7146_I2C_BUSY)) ) {
+
+               if ( 0 == (status & SAA7146_I2C_ERR) ||
+                    0 == (status & SAA7146_I2C_BUSY) ) {
+                       /* it may take some time until ERR goes high - ignore */
+                       DEB_I2C(("unexpected i2c status %04x\n", status));
+               }
                if( 0 != (status & SAA7146_I2C_SPERR) ) {
                        DEB_I2C(("error due to invalid start/stop condition.\n"));
                }
@@ -277,7 +288,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
        return 0;
 }
 
-int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries)
+static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries)
 {
        int i = 0, count = 0;
        u32* buffer = dev->d_i2c.cpu_addr;
index 063608462ebe19222923c2a57ae010257eaca55e..6103484e4442bb4564809ddb33be6a3a838e2c2c 100644 (file)
@@ -165,7 +165,7 @@ static void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf
        /* we don't wait here for the first field anymore. this is different from the video
           capture and might cause that the first buffer is only half filled (with only
           one field). but since this is some sort of streaming data, this is not that negative.
-          but by doing this, we can use the whole engine from video-buf.c... */
+          but by doing this, we can use the whole engine from videobuf-dma-sg.c... */
 
 /*
        WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait);
@@ -239,6 +239,8 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
                saa7146_dma_free(dev,q,buf);
 
        if (STATE_NEEDS_INIT == buf->vb.state) {
+               struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
+
                buf->vb.width  = llength;
                buf->vb.height = lines;
                buf->vb.size   = size;
@@ -250,7 +252,8 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
                err = videobuf_iolock(q,&buf->vb, NULL);
                if (err)
                        goto oops;
-               err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen);
+               err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
+                                                dma->sglist, dma->sglen);
                if (0 != err)
                        return err;
        }
@@ -404,7 +407,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
        fh->vbi_fmt.start[1] = 312;
        fh->vbi_fmt.count[1] = 16;
 
-       videobuf_queue_init(&fh->vbi_q, &vbi_qops,
+       videobuf_queue_pci_init(&fh->vbi_q, &vbi_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VBI_CAPTURE,
                            V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
index 664280c78ff299ef6bfd1c9425c8a0a63a1b7e4f..f245a3b2ef470e6819fcdc90d1458372646fa198 100644 (file)
@@ -594,8 +594,9 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
 static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
 {
        struct pci_dev *pci = dev->pci;
-       struct scatterlist *list = buf->vb.dma.sglist;
-       int length = buf->vb.dma.sglen;
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
+       struct scatterlist *list = dma->sglist;
+       int length = dma->sglen;
        struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
 
        DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
@@ -655,7 +656,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
 
                /* if we have a user buffer, the first page may not be
                   aligned to a page boundary. */
-               pt1->offset = buf->vb.dma.sglist->offset;
+               pt1->offset = list->offset;
                pt2->offset = pt1->offset+o1;
                pt3->offset = pt1->offset+o2;
 
@@ -1211,6 +1212,8 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
                        mutex_unlock(&q->lock);
                        return err;
                }
+
+               gbuffers = err;
                memset(mbuf,0,sizeof(*mbuf));
                mbuf->frames = gbuffers;
                mbuf->size   = gbuffers * gbufsize;
@@ -1411,7 +1414,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
        sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
        fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
 
-       videobuf_queue_init(&fh->video_q, &video_qops,
+       videobuf_queue_pci_init(&fh->video_q, &video_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_INTERLACED,
index df72b4b8ee103d5284790e0c8c85169272a6a912..eca602d9b3dec38c7971426e1114fd5b38b4ac3c 100644 (file)
@@ -28,7 +28,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <asm/io.h>
index f685bc1296097846e7ed959342307fc75d048763..d593bc145628e3f0311875132dea279900a47f8d 100644 (file)
@@ -149,11 +149,10 @@ void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
 void bt878_stop(struct bt878 *bt);
 
 #if defined(__powerpc__)       /* big-endian */
-extern __inline__ void io_st_le32(volatile unsigned __iomem *addr, unsigned val)
+static inline void io_st_le32(volatile unsigned __iomem *addr, unsigned val)
 {
-       __asm__ __volatile__("stwbrx %1,0,%2":"=m"(*addr):"r"(val),
-                            "r"(addr));
-       __asm__ __volatile__("eieio":::"memory");
+       st_le32(addr, val);
+       eieio();
 }
 
 #define bmtwrite(dat,adr)  io_st_le32((adr),(dat))
index 67613eb6fa3d5cc1327642b160afe544455b152f..dedd30a8356bbaad2f78ef936a8352413f4acf41 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <linux/bitops.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
index 28929b618e20bb07cfb4f271b5a9da9c207ebcda..5a12b5679556a78a2fc70be51beaa3f0433d2fd7 100644 (file)
@@ -548,19 +548,19 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct
 {
        struct dvb_device *dvbdev = file->private_data;
        struct cinergyt2 *cinergyt2 = dvbdev->priv;
-       unsigned int mask = 0;
+       unsigned int mask = 0;
 
        if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
                return -ERESTARTSYS;
 
        poll_wait(file, &cinergyt2->poll_wq, wait);
 
-       if (cinergyt2->pending_fe_events != 0)
+       if (cinergyt2->pending_fe_events != 0)
                mask |= (POLLIN | POLLRDNORM | POLLPRI);
 
        mutex_unlock(&cinergyt2->sem);
 
-       return mask;
+       return mask;
 }
 
 
@@ -1008,6 +1008,8 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
        cinergyt2_sleep(cinergyt2, 1);
        mutex_unlock(&cinergyt2->sem);
 
+       mutex_unlock(&cinergyt2->wq_sem);
+
        return 0;
 }
 
index 5394de2e4ce05f2d54fe1e727d51055388c9839b..f94bc31e3b3334d020b7e5dc95759f25a3e70ca8 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/poll.h>
 #include <linux/ioctl.h>
 #include <linux/wait.h>
index 4fadddb264d67d902a077e5d6bbbd73929ea6cf6..084a508a03da8e1202b01fd77ee6a8209fc2f729 100644 (file)
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/sched.h>
+#include <linux/kthread.h>
 
 #include "dvb_ca_en50221.h"
 #include "dvb_ringbuffer.h"
@@ -140,13 +140,7 @@ struct dvb_ca_private {
        wait_queue_head_t wait_queue;
 
        /* PID of the monitoring thread */
-       pid_t thread_pid;
-
-       /* Wait queue used when shutting thread down */
-       wait_queue_head_t thread_queue;
-
-       /* Flag indicating when thread should exit */
-       unsigned int exit:1;
+       struct task_struct *thread;
 
        /* Flag indicating if the CA device is open */
        unsigned int open:1;
@@ -902,27 +896,9 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
 
        ca->wakeup = 1;
        mb();
-       wake_up_interruptible(&ca->thread_queue);
+       wake_up_process(ca->thread);
 }
 
-/**
- * Used by the CA thread to determine if an early wakeup is necessary
- *
- * @param ca CA instance.
- */
-static int dvb_ca_en50221_thread_should_wakeup(struct dvb_ca_private *ca)
-{
-       if (ca->wakeup) {
-               ca->wakeup = 0;
-               return 1;
-       }
-       if (ca->exit)
-               return 1;
-
-       return 0;
-}
-
-
 /**
  * Update the delay used by the thread.
  *
@@ -982,7 +958,6 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
 static int dvb_ca_en50221_thread(void *data)
 {
        struct dvb_ca_private *ca = data;
-       char name[15];
        int slot;
        int flags;
        int status;
@@ -991,28 +966,17 @@ static int dvb_ca_en50221_thread(void *data)
 
        dprintk("%s\n", __FUNCTION__);
 
-       /* setup kernel thread */
-       snprintf(name, sizeof(name), "kdvb-ca-%i:%i", ca->dvbdev->adapter->num, ca->dvbdev->id);
-
-       lock_kernel();
-       daemonize(name);
-       sigfillset(&current->blocked);
-       unlock_kernel();
-
        /* choose the correct initial delay */
        dvb_ca_en50221_thread_update_delay(ca);
 
        /* main loop */
-       while (!ca->exit) {
+       while (!kthread_should_stop()) {
                /* sleep for a bit */
-               if (!ca->wakeup) {
-                       flags = wait_event_interruptible_timeout(ca->thread_queue,
-                                                                dvb_ca_en50221_thread_should_wakeup(ca),
-                                                                ca->delay);
-                       if ((flags == -ERESTARTSYS) || ca->exit) {
-                               /* got signal or quitting */
-                               break;
-                       }
+               while (!ca->wakeup) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       schedule_timeout(ca->delay);
+                       if (kthread_should_stop())
+                               return 0;
                }
                ca->wakeup = 0;
 
@@ -1181,10 +1145,6 @@ static int dvb_ca_en50221_thread(void *data)
                }
        }
 
-       /* completed */
-       ca->thread_pid = 0;
-       mb();
-       wake_up_interruptible(&ca->thread_queue);
        return 0;
 }
 
@@ -1536,8 +1496,10 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
                return -EIO;
 
        err = dvb_generic_open(inode, file);
-       if (err < 0)
+       if (err < 0) {
+               module_put(ca->pub->owner);
                return err;
+       }
 
        for (i = 0; i < ca->slot_count; i++) {
 
@@ -1570,7 +1532,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
 {
        struct dvb_device *dvbdev = file->private_data;
        struct dvb_ca_private *ca = dvbdev->priv;
-       int err = 0;
+       int err;
 
        dprintk("%s\n", __FUNCTION__);
 
@@ -1582,7 +1544,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
 
        module_put(ca->pub->owner);
 
-       return 0;
+       return err;
 }
 
 
@@ -1682,9 +1644,6 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
                goto error;
        }
        init_waitqueue_head(&ca->wait_queue);
-       ca->thread_pid = 0;
-       init_waitqueue_head(&ca->thread_queue);
-       ca->exit = 0;
        ca->open = 0;
        ca->wakeup = 0;
        ca->next_read_slot = 0;
@@ -1710,14 +1669,14 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
        mb();
 
        /* create a kthread for monitoring this CA device */
-
-       ret = kernel_thread(dvb_ca_en50221_thread, ca, 0);
-
-       if (ret < 0) {
-               printk("dvb_ca_init: failed to start kernel_thread (%d)\n", ret);
+       ca->thread = kthread_run(dvb_ca_en50221_thread, ca, "kdvb-ca-%i:%i",
+                                ca->dvbdev->adapter->num, ca->dvbdev->id);
+       if (IS_ERR(ca->thread)) {
+               ret = PTR_ERR(ca->thread);
+               printk("dvb_ca_init: failed to start kernel_thread (%d)\n",
+                       ret);
                goto error;
        }
-       ca->thread_pid = ret;
        return 0;
 
 error:
@@ -1748,17 +1707,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
        dprintk("%s\n", __FUNCTION__);
 
        /* shutdown the thread if there was one */
-       if (ca->thread_pid) {
-               if (kill_proc(ca->thread_pid, 0, 1) == -ESRCH) {
-                       printk("dvb_ca_release adapter %d: thread PID %d already died\n",
-                              ca->dvbdev->adapter->num, ca->thread_pid);
-               } else {
-                       ca->exit = 1;
-                       mb();
-                       dvb_ca_en50221_thread_wakeup(ca);
-                       wait_event_interruptible(ca->thread_queue, ca->thread_pid == 0);
-               }
-       }
+       kthread_stop(ca->thread);
 
        for (i = 0; i < ca->slot_count; i++) {
                dvb_ca_en50221_slot_shutdown(ca, i);
index cb6987fce26cb1b0da73b16d375e3cc5dc530d1e..7959020f9317d2ee5f1f0824370ab730542f09c3 100644 (file)
@@ -373,13 +373,10 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
 static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
 {
        struct dvb_demux_feed *feed;
-       struct list_head *pos, *head = &demux->feed_list;
        u16 pid = ts_pid(buf);
        int dvr_done = 0;
 
-       list_for_each(pos, head) {
-               feed = list_entry(pos, struct dvb_demux_feed, list_head);
-
+       list_for_each_entry(feed, &demux->feed_list, list_head) {
                if ((feed->pid != pid) && (feed->pid != 0x2000))
                        continue;
 
index b6c7f6610ec53205f407e8e2b85c397af3974155..b203640ef1c587e7c4f294a7b0be8f2bd9f923a8 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/list.h>
 #include <linux/freezer.h>
 #include <linux/jiffies.h>
@@ -43,7 +42,7 @@
 #include "dvbdev.h"
 
 static int dvb_frontend_debug;
-static int dvb_shutdown_timeout = 5;
+static int dvb_shutdown_timeout;
 static int dvb_force_auto_inversion;
 static int dvb_override_tune_delay;
 static int dvb_powerdown_on_sleep = 1;
@@ -138,7 +137,7 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
 
        dprintk ("%s\n", __FUNCTION__);
 
-       if (down_interruptible (&events->sem))
+       if (mutex_lock_interruptible (&events->mtx))
                return;
 
        wp = (events->eventw + 1) % MAX_EVENT;
@@ -159,7 +158,7 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
 
        events->eventw = wp;
 
-       up (&events->sem);
+       mutex_unlock(&events->mtx);
 
        e->status = status;
 
@@ -197,7 +196,7 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
                        return ret;
        }
 
-       if (down_interruptible (&events->sem))
+       if (mutex_lock_interruptible (&events->mtx))
                return -ERESTARTSYS;
 
        memcpy (event, &events->events[events->eventr],
@@ -205,7 +204,7 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
 
        events->eventr = (events->eventr + 1) % MAX_EVENT;
 
-       up (&events->sem);
+       mutex_unlock(&events->mtx);
 
        return 0;
 }
@@ -574,10 +573,9 @@ restart:
                        dvb_frontend_swzigzag(fe);
        }
 
-       if (dvb_shutdown_timeout) {
-               if (dvb_powerdown_on_sleep)
-                       if (fe->ops.set_voltage)
-                               fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
+       if (dvb_powerdown_on_sleep) {
+               if (fe->ops.set_voltage)
+                       fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
                if (fe->ops.tuner_ops.sleep) {
                        fe->ops.tuner_ops.sleep(fe);
                        if (fe->ops.i2c_gate_ctrl)
@@ -697,6 +695,65 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
        return 0;
 }
 
+static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe,
+                                       u32 *freq_min, u32 *freq_max)
+{
+       *freq_min = max(fe->ops.info.frequency_min, fe->ops.tuner_ops.info.frequency_min);
+
+       if (fe->ops.info.frequency_max == 0)
+               *freq_max = fe->ops.tuner_ops.info.frequency_max;
+       else if (fe->ops.tuner_ops.info.frequency_max == 0)
+               *freq_max = fe->ops.info.frequency_max;
+       else
+               *freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max);
+
+       if (*freq_min == 0 || *freq_max == 0)
+               printk(KERN_WARNING "DVB: frontend %u frequency limits undefined - fix the driver\n",
+                      fe->dvb->num);
+}
+
+static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
+                               struct dvb_frontend_parameters *parms)
+{
+       u32 freq_min;
+       u32 freq_max;
+
+       /* range check: frequency */
+       dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max);
+       if ((freq_min && parms->frequency < freq_min) ||
+           (freq_max && parms->frequency > freq_max)) {
+               printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n",
+                      fe->dvb->num, parms->frequency, freq_min, freq_max);
+               return -EINVAL;
+       }
+
+       /* range check: symbol rate */
+       if (fe->ops.info.type == FE_QPSK) {
+               if ((fe->ops.info.symbol_rate_min &&
+                    parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) ||
+                   (fe->ops.info.symbol_rate_max &&
+                    parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) {
+                       printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
+                              fe->dvb->num, parms->u.qpsk.symbol_rate,
+                              fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
+                       return -EINVAL;
+               }
+
+       } else if (fe->ops.info.type == FE_QAM) {
+               if ((fe->ops.info.symbol_rate_min &&
+                    parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) ||
+                   (fe->ops.info.symbol_rate_max &&
+                    parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) {
+                       printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
+                              fe->dvb->num, parms->u.qam.symbol_rate,
+                              fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
 static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
                        unsigned int cmd, void *parg)
 {
@@ -707,7 +764,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
 
        dprintk ("%s\n", __FUNCTION__);
 
-       if (!fe || fepriv->exit)
+       if (fepriv->exit)
                return -ENODEV;
 
        if ((file->f_flags & O_ACCMODE) == O_RDONLY &&
@@ -722,6 +779,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
        case FE_GET_INFO: {
                struct dvb_frontend_info* info = parg;
                memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info));
+               dvb_frontend_get_frequeny_limits(fe, &info->frequency_min, &info->frequency_max);
 
                /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
                 * do it, it is done for it. */
@@ -883,6 +941,11 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
        case FE_SET_FRONTEND: {
                struct dvb_frontend_tune_settings fetunesettings;
 
+               if (dvb_frontend_check_parameters(fe, parg) < 0) {
+                       err = -EINVAL;
+                       break;
+               }
+
                memcpy (&fepriv->parameters, parg,
                        sizeof (struct dvb_frontend_parameters));
 
@@ -992,18 +1055,15 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 
        dprintk ("%s\n", __FUNCTION__);
 
-       if ((ret = dvb_generic_open (inode, file)) < 0)
-               return ret;
-
-       if (fe->ops.ts_bus_ctrl) {
-               if ((ret = fe->ops.ts_bus_ctrl (fe, 1)) < 0) {
-                       dvb_generic_release (inode, file);
+       if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
+               if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
                        return ret;
-               }
        }
 
-       if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+       if ((ret = dvb_generic_open (inode, file)) < 0)
+               goto err1;
 
+       if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
                /* normal tune mode when opened R/W */
                fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
                fepriv->tone = -1;
@@ -1011,13 +1071,20 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 
                ret = dvb_frontend_start (fe);
                if (ret)
-                       dvb_generic_release (inode, file);
+                       goto err2;
 
                /*  empty event queue */
                fepriv->events.eventr = fepriv->events.eventw = 0;
        }
 
        return ret;
+
+err2:
+       dvb_generic_release(inode, file);
+err1:
+       if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
+               fe->ops.ts_bus_ctrl(fe, 0);
+       return ret;
 }
 
 static int dvb_frontend_release(struct inode *inode, struct file *file)
@@ -1032,16 +1099,18 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
        if ((file->f_flags & O_ACCMODE) != O_RDONLY)
                fepriv->release_jiffies = jiffies;
 
-       if (fe->ops.ts_bus_ctrl)
-               fe->ops.ts_bus_ctrl (fe, 0);
-
        ret = dvb_generic_release (inode, file);
 
-       if (dvbdev->users==-1 && fepriv->exit==1) {
-               fops_put(file->f_op);
-               file->f_op = NULL;
-               wake_up(&dvbdev->wait_queue);
+       if (dvbdev->users == -1) {
+               if (fepriv->exit == 1) {
+                       fops_put(file->f_op);
+                       file->f_op = NULL;
+                       wake_up(&dvbdev->wait_queue);
+               }
+               if (fe->ops.ts_bus_ctrl)
+                       fe->ops.ts_bus_ctrl(fe, 0);
        }
+
        return ret;
 }
 
@@ -1080,7 +1149,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
        init_MUTEX (&fepriv->sem);
        init_waitqueue_head (&fepriv->wait_queue);
        init_waitqueue_head (&fepriv->events.wait_queue);
-       init_MUTEX (&fepriv->events.sem);
+       mutex_init(&fepriv->events.mtx);
        fe->dvb = dvb;
        fepriv->inversion = INVERSION_OFF;
 
index a770a87b9a93d0f68ed5610316e20f6d2374649d..a5262e852c822bd0d280cb0d52100a9d5cd22c3d 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
+#include <linux/mutex.h>
 
 #include <linux/dvb/frontend.h>
 
@@ -61,6 +62,13 @@ struct dvb_tuner_info {
        u32 bandwidth_step;
 };
 
+struct analog_parameters {
+       unsigned int frequency;
+       unsigned int mode;
+       unsigned int audmode;
+       u64 std;
+};
+
 struct dvb_tuner_ops {
 
        struct dvb_tuner_info info;
@@ -71,6 +79,7 @@ struct dvb_tuner_ops {
 
        /** This is for simple PLLs - set all parameters in one go. */
        int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
+       int (*set_analog_params)(struct dvb_frontend *fe, struct analog_parameters *p);
 
        /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */
        int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len);
@@ -79,7 +88,9 @@ struct dvb_tuner_ops {
        int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
 
 #define TUNER_STATUS_LOCKED 1
+#define TUNER_STATUS_STEREO 2
        int (*get_status)(struct dvb_frontend *fe, u32 *status);
+       int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
 
        /** These are provided seperately from set_params in order to facilitate silicon
         * tuners which require sophisticated tuning loops, controlling each parameter seperately. */
@@ -142,7 +153,7 @@ struct dvb_fe_events {
        int                       eventr;
        int                       overflow;
        wait_queue_head_t         wait_queue;
-       struct semaphore          sem;
+       struct mutex              mtx;
 };
 
 struct dvb_frontend {
index bdd797071cb0e6d4d3d56be1f9acb957792620d5..2117377c141d206cce3d2710a1deeb93916efdb1 100644 (file)
@@ -357,11 +357,6 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
        static unsigned char *ule_where = ule_hist, ule_dump = 0;
 #endif
 
-       if (dev == NULL) {
-               printk( KERN_ERR "NO netdev struct!\n" );
-               return;
-       }
-
        /* For all TS cells in current buffer.
         * Appearently, we are called for every single TS cell.
         */
@@ -800,8 +795,8 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
 }
 
 
-static void dvb_net_sec(struct net_device *dev, const u8 *pkt, int
-pkt_len)
+static void dvb_net_sec(struct net_device *dev,
+                       const u8 *pkt, int pkt_len)
 {
        u8 *eth;
        struct sk_buff *skb;
@@ -1446,18 +1441,9 @@ static int dvb_net_close(struct inode *inode, struct file *file)
        struct dvb_device *dvbdev = file->private_data;
        struct dvb_net *dvbnet = dvbdev->priv;
 
-       if (!dvbdev)
-               return -ENODEV;
-
-       if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
-               dvbdev->readers++;
-       } else {
-               dvbdev->writers++;
-       }
-
-       dvbdev->users++;
+       dvb_generic_release(inode, file);
 
-       if(dvbdev->users == 1 && dvbnet->exit==1) {
+       if(dvbdev->users == 1 && dvbnet->exit == 1) {
                fops_put(file->f_op);
                file->f_op = NULL;
                wake_up(&dvbdev->wait_queue);
index 9ef0c00605ee80a3d4a08b14f4be7f826a50d91f..56231d8edc079a5306a3a487bdf04373db83b757 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -59,18 +58,13 @@ static struct class *dvb_class;
 
 static struct dvb_device* dvbdev_find_device (int minor)
 {
-       struct list_head *entry;
+       struct dvb_adapter *adap;
 
-       list_for_each (entry, &dvb_adapter_list) {
-               struct list_head *entry0;
-               struct dvb_adapter *adap;
-               adap = list_entry (entry, struct dvb_adapter, list_head);
-               list_for_each (entry0, &adap->device_list) {
-                       struct dvb_device *dev;
-                       dev = list_entry (entry0, struct dvb_device, list_head);
+       list_for_each_entry(adap, &dvb_adapter_list, list_head) {
+               struct dvb_device *dev;
+               list_for_each_entry(dev, &adap->device_list, list_head)
                        if (nums2minor(adap->num, dev->type, dev->id) == minor)
                                return dev;
-               }
        }
 
        return NULL;
@@ -180,13 +174,10 @@ static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
        u32 id = 0;
 
        while (id < DVB_MAX_IDS) {
-               struct list_head *entry;
-               list_for_each (entry, &adap->device_list) {
-                       struct dvb_device *dev;
-                       dev = list_entry (entry, struct dvb_device, list_head);
+               struct dvb_device *dev;
+               list_for_each_entry(dev, &adap->device_list, list_head)
                        if (dev->type == type && dev->id == id)
                                goto skip;
-               }
                return id;
 skip:
                id++;
@@ -200,7 +191,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 {
        struct dvb_device *dvbdev;
        struct file_operations *dvbdevfops;
-       struct class_device *clsdev;
+       struct device *clsdev;
        int id;
 
        mutex_lock(&dvbdev_register_lock);
@@ -242,10 +233,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 
        mutex_unlock(&dvbdev_register_lock);
 
-       clsdev = class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR,
-                                    nums2minor(adap->num, type, id)),
-                                    adap->device, "dvb%d.%s%d", adap->num,
-                                    dnames[type], id);
+       clsdev = device_create(dvb_class, adap->device,
+                              MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
+                              "dvb%d.%s%d", adap->num, dnames[type], id);
        if (IS_ERR(clsdev)) {
                printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
                       __FUNCTION__, adap->num, dnames[type], id, PTR_ERR(clsdev));
@@ -266,8 +256,8 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
        if (!dvbdev)
                return;
 
-       class_device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
-                                       dvbdev->type, dvbdev->id)));
+       device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
+                      dvbdev->type, dvbdev->id)));
 
        list_del (&dvbdev->list_head);
        kfree (dvbdev->fops);
@@ -281,13 +271,10 @@ static int dvbdev_get_free_adapter_num (void)
        int num = 0;
 
        while (num < DVB_MAX_ADAPTERS) {
-               struct list_head *entry;
-               list_for_each (entry, &dvb_adapter_list) {
-                       struct dvb_adapter *adap;
-                       adap = list_entry (entry, struct dvb_adapter, list_head);
+               struct dvb_adapter *adap;
+               list_for_each_entry(adap, &dvb_adapter_list, list_head)
                        if (adap->num == num)
                                goto skip;
-               }
                return num;
 skip:
                num++;
index 40e41f2f5afea2fce7abe356ec53164d0870757c..d73934dd4c573790790c9cd885db3ef7063f02f7 100644 (file)
@@ -74,6 +74,8 @@ config DVB_USB_DIB0700
        select DVB_DIB7000M
        select DVB_DIB3000MC
        select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
+       select DVB_TUNER_MT2266 if !DVB_FE_CUSTOMISE
+       select DVB_TUNER_DIB0070
        help
          Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
          USB bridge is also present in devices having the DiB7700 DVB-T-USB
index cda3adea24fb2fdf121cbc3053f7aaaf1f720a63..4a903ea958965d5bc7cbadbd96f2282e89dedf34 100644 (file)
@@ -30,17 +30,19 @@ extern int dvb_usb_dib0700_debug;
        // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
        // 2 Byte: MPEG2 mode:  4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
        // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines)    4LSB(     "                "           )
+#define REQUEST_SET_RC       0x11
 #define REQUEST_GET_VERSION  0x15
 
 struct dib0700_state {
        u8 channel_state;
        u16 mt2060_if1[2];
-
+       u8 rc_toggle;
        u8 is_dib7000pc;
 };
 
 extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
 extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3);
+extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen);
 extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw);
 extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
 extern struct i2c_algorithm dib0700_i2c_algo;
@@ -50,5 +52,4 @@ extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device
 extern int dib0700_device_count;
 extern struct dvb_usb_device_properties dib0700_devices[];
 extern struct usb_device_id dib0700_usb_id_table[];
-
 #endif
index dddf164f269adec21f2a55a90343993c5e787584..3ea294eb96bdedc4a7b6e12dfa3af42143cedb6c 100644 (file)
@@ -13,6 +13,10 @@ int dvb_usb_dib0700_debug;
 module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);
 
+static int dvb_usb_dib0700_ir_proto = 1;
+module_param(dvb_usb_dib0700_ir_proto, int, 0644);
+MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6).");
+
 /* expecting rx buffer: request data[0] data[1] ... data[2] */
 static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
 {
@@ -32,7 +36,7 @@ static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
 }
 
 /* expecting tx buffer: request data[0] ... data[n] (n <= 4) */
-static int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
+int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
 {
        u16 index, value;
        int status;
@@ -260,14 +264,29 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
        return dib0700_ctrl_wr(adap->dev, b, 4);
 }
 
+static int dib0700_rc_setup(struct dvb_usb_device *d)
+{
+       u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0};
+       int i = dib0700_ctrl_wr(d, rc_setup, 3);
+       if (i<0) {
+               err("ir protocol setup failed");
+               return -1;
+       }
+       return 0;
+}
+
 static int dib0700_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
 {
        int i;
+       struct dvb_usb_device *dev;
 
        for (i = 0; i < dib0700_device_count; i++)
-               if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, NULL) == 0)
+               if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, &dev) == 0)
+               {
+                       dib0700_rc_setup(dev);
                        return 0;
+               }
 
        return -ENODEV;
 }
index 2208757d90173e55aafe001f7f3e1c57dae610c4..e8c4a869453249cbbcbfe27793e6369c53feae90 100644 (file)
@@ -4,7 +4,7 @@
  *     under the terms of the GNU General Public License as published by the Free
  *     Software Foundation, version 2.
  *
- *  Copyright (C) 2005-6 DiBcom, SA
+ *  Copyright (C) 2005-7 DiBcom, SA
  */
 #include "dib0700.h"
 
 #include "dib7000m.h"
 #include "dib7000p.h"
 #include "mt2060.h"
+#include "mt2266.h"
+#include "dib0070.h"
 
 static int force_lna_activation;
 module_param(force_lna_activation, int, 0644);
 MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
                "if applicable for the device (default: 0=automatic/off).");
 
-/* Hauppauge Nova-T 500
+struct dib0700_adapter_state {
+       int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *);
+};
+
+/* Hauppauge Nova-T 500 (aka Bristol)
  *  has a LNA on GPIO0 which is enabled by setting 1 */
 static struct mt2060_config bristol_mt2060_config[2] = {
        {
@@ -96,6 +102,321 @@ static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
                st->mt2060_if1[adap->id]) == NULL ? -ENODEV : 0;
 }
 
+/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
+
+/* MT226x */
+static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
+       {
+               BAND_UHF, // band_caps
+
+               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
+               * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
+               (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
+
+               1130,  // inv_gain
+               21,  // time_stabiliz
+
+               0,  // alpha_level
+               118,  // thlock
+
+               0,     // wbd_inv
+               3530,  // wbd_ref
+               1,     // wbd_sel
+               0,     // wbd_alpha
+
+               65535,  // agc1_max
+               33770,  // agc1_min
+               65535,  // agc2_max
+               23592,  // agc2_min
+
+               0,    // agc1_pt1
+               62,   // agc1_pt2
+               255,  // agc1_pt3
+               64,   // agc1_slope1
+               64,   // agc1_slope2
+               132,  // agc2_pt1
+               192,  // agc2_pt2
+               80,   // agc2_slope1
+               80,   // agc2_slope2
+
+               17,  // alpha_mant
+               27,  // alpha_exp
+               23,  // beta_mant
+               51,  // beta_exp
+
+               1,  // perform_agc_softsplit
+       }, {
+               BAND_VHF | BAND_LBAND, // band_caps
+
+               /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
+               * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
+               (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup
+
+               2372, // inv_gain
+               21,   // time_stabiliz
+
+               0,    // alpha_level
+               118,  // thlock
+
+               0,    // wbd_inv
+               3530, // wbd_ref
+               1,     // wbd_sel
+               0,    // wbd_alpha
+
+               65535, // agc1_max
+               0,     // agc1_min
+               65535, // agc2_max
+               23592, // agc2_min
+
+               0,    // agc1_pt1
+               128,  // agc1_pt2
+               128,  // agc1_pt3
+               128,  // agc1_slope1
+               0,    // agc1_slope2
+               128,  // agc2_pt1
+               253,  // agc2_pt2
+               81,   // agc2_slope1
+               0,    // agc2_slope2
+
+               17,  // alpha_mant
+               27,  // alpha_exp
+               23,  // beta_mant
+               51,  // beta_exp
+
+               1,  // perform_agc_softsplit
+       }
+};
+
+static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
+       60000, 30000, // internal, sampling
+       1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
+       0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
+       (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
+       0, // ifreq
+       20452225, // timf
+};
+
+static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
+       {       .output_mpeg2_in_188_bytes = 1,
+               .hostbus_diversity = 1,
+               .tuner_is_baseband = 1,
+
+               .agc_config_count = 2,
+               .agc = stk7700d_7000p_mt2266_agc_config,
+               .bw  = &stk7700d_mt2266_pll_config,
+
+               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+       },
+       {       .output_mpeg2_in_188_bytes = 1,
+               .hostbus_diversity = 1,
+               .tuner_is_baseband = 1,
+
+               .agc_config_count = 2,
+               .agc = stk7700d_7000p_mt2266_agc_config,
+               .bw  = &stk7700d_mt2266_pll_config,
+
+               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+       }
+};
+
+static struct mt2266_config stk7700d_mt2266_config[2] = {
+       {       .i2c_address = 0x60
+       },
+       {       .i2c_address = 0x60
+       }
+};
+
+static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       if (adap->id == 0) {
+               dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+               msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+               dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+               dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+               msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+               msleep(10);
+               dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+               dib7000p_i2c_enumeration(&adap->dev->i2c_adap,2,18,stk7700d_dib7000p_mt2266_config);
+       }
+
+       adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
+                               &stk7700d_dib7000p_mt2266_config[adap->id]);
+
+       return adap->fe == NULL ? -ENODEV : 0;
+}
+
+static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct i2c_adapter *tun_i2c;
+       tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+       return dvb_attach(mt2266_attach, adap->fe, tun_i2c,
+               &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;;
+}
+
+#define DEFAULT_RC_INTERVAL 150
+
+static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
+
+static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+       u8 key[4];
+       int i;
+       struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
+       struct dib0700_state *st = d->priv;
+       *event = 0;
+       *state = REMOTE_NO_KEY_PRESSED;
+       i=dib0700_ctrl_rd(d,rc_request,2,key,4);
+       if (i<=0) {
+               err("RC Query Failed");
+               return -1;
+       }
+       if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0;
+       if (key[3-1]!=st->rc_toggle) {
+               for (i=0;i<d->props.rc_key_map_size; i++) {
+                       if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
+                               *event = keymap[i].event;
+                               *state = REMOTE_KEY_PRESSED;
+                               st->rc_toggle=key[3-1];
+                               return 0;
+                       }
+               }
+               err("Unknown remote controller key : %2X %2X",(int)key[3-2],(int)key[3-3]);
+       }
+       return 0;
+}
+
+static struct dvb_usb_rc_key dib0700_rc_keys[] = {
+       /* Key codes for the tiny Pinnacle remote*/
+       { 0x07, 0x00, KEY_MUTE },
+       { 0x07, 0x01, KEY_MENU }, // Pinnacle logo
+       { 0x07, 0x39, KEY_POWER },
+       { 0x07, 0x03, KEY_VOLUMEUP },
+       { 0x07, 0x09, KEY_VOLUMEDOWN },
+       { 0x07, 0x06, KEY_CHANNELUP },
+       { 0x07, 0x0c, KEY_CHANNELDOWN },
+       { 0x07, 0x0f, KEY_1 },
+       { 0x07, 0x15, KEY_2 },
+       { 0x07, 0x10, KEY_3 },
+       { 0x07, 0x18, KEY_4 },
+       { 0x07, 0x1b, KEY_5 },
+       { 0x07, 0x1e, KEY_6 },
+       { 0x07, 0x11, KEY_7 },
+       { 0x07, 0x21, KEY_8 },
+       { 0x07, 0x12, KEY_9 },
+       { 0x07, 0x27, KEY_0 },
+       { 0x07, 0x24, KEY_SCREEN }, // 'Square' key
+       { 0x07, 0x2a, KEY_TEXT },   // 'T' key
+       { 0x07, 0x2d, KEY_REWIND },
+       { 0x07, 0x30, KEY_PLAY },
+       { 0x07, 0x33, KEY_FASTFORWARD },
+       { 0x07, 0x36, KEY_RECORD },
+       { 0x07, 0x3c, KEY_STOP },
+       { 0x07, 0x3f, KEY_CANCEL }, // '?' key
+       /* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */
+       { 0xeb, 0x01, KEY_POWER },
+       { 0xeb, 0x02, KEY_1 },
+       { 0xeb, 0x03, KEY_2 },
+       { 0xeb, 0x04, KEY_3 },
+       { 0xeb, 0x05, KEY_4 },
+       { 0xeb, 0x06, KEY_5 },
+       { 0xeb, 0x07, KEY_6 },
+       { 0xeb, 0x08, KEY_7 },
+       { 0xeb, 0x09, KEY_8 },
+       { 0xeb, 0x0a, KEY_9 },
+       { 0xeb, 0x0b, KEY_VIDEO },
+       { 0xeb, 0x0c, KEY_0 },
+       { 0xeb, 0x0d, KEY_REFRESH },
+       { 0xeb, 0x0f, KEY_EPG },
+       { 0xeb, 0x10, KEY_UP },
+       { 0xeb, 0x11, KEY_LEFT },
+       { 0xeb, 0x12, KEY_OK },
+       { 0xeb, 0x13, KEY_RIGHT },
+       { 0xeb, 0x14, KEY_DOWN },
+       { 0xeb, 0x16, KEY_INFO },
+       { 0xeb, 0x17, KEY_RED },
+       { 0xeb, 0x18, KEY_GREEN },
+       { 0xeb, 0x19, KEY_YELLOW },
+       { 0xeb, 0x1a, KEY_BLUE },
+       { 0xeb, 0x1b, KEY_CHANNELUP },
+       { 0xeb, 0x1c, KEY_VOLUMEUP },
+       { 0xeb, 0x1d, KEY_MUTE },
+       { 0xeb, 0x1e, KEY_VOLUMEDOWN },
+       { 0xeb, 0x1f, KEY_CHANNELDOWN },
+       { 0xeb, 0x40, KEY_PAUSE },
+       { 0xeb, 0x41, KEY_HOME },
+       { 0xeb, 0x42, KEY_MENU }, /* DVD Menu */
+       { 0xeb, 0x43, KEY_SUBTITLE },
+       { 0xeb, 0x44, KEY_TEXT }, /* Teletext */
+       { 0xeb, 0x45, KEY_DELETE },
+       { 0xeb, 0x46, KEY_TV },
+       { 0xeb, 0x47, KEY_DVD },
+       { 0xeb, 0x48, KEY_STOP },
+       { 0xeb, 0x49, KEY_VIDEO },
+       { 0xeb, 0x4a, KEY_AUDIO }, /* Music */
+       { 0xeb, 0x4b, KEY_SCREEN }, /* Pic */
+       { 0xeb, 0x4c, KEY_PLAY },
+       { 0xeb, 0x4d, KEY_BACK },
+       { 0xeb, 0x4e, KEY_REWIND },
+       { 0xeb, 0x4f, KEY_FASTFORWARD },
+       { 0xeb, 0x54, KEY_PREVIOUS },
+       { 0xeb, 0x58, KEY_RECORD },
+       { 0xeb, 0x5c, KEY_NEXT },
+
+       /* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */
+       { 0x1e, 0x00, KEY_0 },
+       { 0x1e, 0x01, KEY_1 },
+       { 0x1e, 0x02, KEY_2 },
+       { 0x1e, 0x03, KEY_3 },
+       { 0x1e, 0x04, KEY_4 },
+       { 0x1e, 0x05, KEY_5 },
+       { 0x1e, 0x06, KEY_6 },
+       { 0x1e, 0x07, KEY_7 },
+       { 0x1e, 0x08, KEY_8 },
+       { 0x1e, 0x09, KEY_9 },
+       { 0x1e, 0x0a, KEY_KPASTERISK },
+       { 0x1e, 0x0b, KEY_RED },
+       { 0x1e, 0x0c, KEY_RADIO },
+       { 0x1e, 0x0d, KEY_MENU },
+       { 0x1e, 0x0e, KEY_GRAVE }, /* # */
+       { 0x1e, 0x0f, KEY_MUTE },
+       { 0x1e, 0x10, KEY_VOLUMEUP },
+       { 0x1e, 0x11, KEY_VOLUMEDOWN },
+       { 0x1e, 0x12, KEY_CHANNEL },
+       { 0x1e, 0x14, KEY_UP },
+       { 0x1e, 0x15, KEY_DOWN },
+       { 0x1e, 0x16, KEY_LEFT },
+       { 0x1e, 0x17, KEY_RIGHT },
+       { 0x1e, 0x18, KEY_VIDEO },
+       { 0x1e, 0x19, KEY_AUDIO },
+       { 0x1e, 0x1a, KEY_MEDIA },
+       { 0x1e, 0x1b, KEY_EPG },
+       { 0x1e, 0x1c, KEY_TV },
+       { 0x1e, 0x1e, KEY_NEXT },
+       { 0x1e, 0x1f, KEY_BACK },
+       { 0x1e, 0x20, KEY_CHANNELUP },
+       { 0x1e, 0x21, KEY_CHANNELDOWN },
+       { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
+       { 0x1e, 0x25, KEY_OK },
+       { 0x1e, 0x29, KEY_BLUE},
+       { 0x1e, 0x2e, KEY_GREEN },
+       { 0x1e, 0x30, KEY_PAUSE },
+       { 0x1e, 0x32, KEY_REWIND },
+       { 0x1e, 0x34, KEY_FASTFORWARD },
+       { 0x1e, 0x35, KEY_PLAY },
+       { 0x1e, 0x36, KEY_STOP },
+       { 0x1e, 0x37, KEY_RECORD },
+       { 0x1e, 0x38, KEY_YELLOW },
+       { 0x1e, 0x3b, KEY_GOTO },
+       { 0x1e, 0x3d, KEY_POWER },
+};
+
 /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
 static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
        BAND_UHF | BAND_VHF,       // band_caps
@@ -194,6 +515,7 @@ static struct dibx000_bandwidth_config stk7700p_pll_config = {
        (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
        60258167, // ifreq
        20452225, // timf
+       30000000, // xtal
 };
 
 static struct dib7000m_config stk7700p_dib7000m_config = {
@@ -213,6 +535,7 @@ static struct dib7000m_config stk7700p_dib7000m_config = {
 static struct dib7000p_config stk7700p_dib7000p_config = {
        .output_mpeg2_in_188_bytes = 1,
 
+       .agc_config_count = 1,
        .agc = &stk7700p_7000p_mt2060_agc_config,
        .bw  = &stk7700p_pll_config,
 
@@ -267,27 +590,245 @@ static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
                st->mt2060_if1[0]) == NULL ? -ENODEV : 0;
 }
 
+/* DIB7070 generic */
+static struct dibx000_agc_config dib7070_agc_config = {
+       BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
+       /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
+        * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
+       (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup
+
+       600, // inv_gain
+       10,  // time_stabiliz
+
+       0,  // alpha_level
+       118,  // thlock
+
+       0,     // wbd_inv
+       3530,  // wbd_ref
+       1,     // wbd_sel
+       5,     // wbd_alpha
+
+       65535,  // agc1_max
+               0,  // agc1_min
+
+       65535,  // agc2_max
+       0,      // agc2_min
+
+       0,      // agc1_pt1
+       40,     // agc1_pt2
+       183,    // agc1_pt3
+       206,    // agc1_slope1
+       255,    // agc1_slope2
+       72,     // agc2_pt1
+       152,    // agc2_pt2
+       88,     // agc2_slope1
+       90,     // agc2_slope2
+
+       17,  // alpha_mant
+       27,  // alpha_exp
+       23,  // beta_mant
+       51,  // beta_exp
+
+       0,  // perform_agc_softsplit
+};
+
+static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
+{
+       return dib7000p_set_gpio(fe, 8, 0, !onoff);
+}
+
+static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+       return dib7000p_set_gpio(fe, 9, 0, onoff);
+}
+
+static struct dib0070_config dib7070p_dib0070_config[2] = {
+       {
+               .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+               .reset = dib7070_tuner_reset,
+               .sleep = dib7070_tuner_sleep,
+               .clock_khz = 12000,
+               .clock_pad_drive = 4
+       }, {
+               .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+               .reset = dib7070_tuner_reset,
+               .sleep = dib7070_tuner_sleep,
+               .clock_khz = 12000,
+
+       }
+};
+
+static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+       struct dvb_usb_adapter *adap = fe->dvb->priv;
+       struct dib0700_adapter_state *state = adap->priv;
+
+       u16 offset;
+       u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
+       switch (band) {
+               case BAND_VHF: offset = 950; break;
+               case BAND_UHF:
+               default: offset = 550; break;
+       }
+       deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
+       dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
+       return state->set_param_save(fe, fep);
+}
+
+static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
+{
+       struct dib0700_adapter_state *st = adap->priv;
+       struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
+
+       if (adap->id == 0) {
+               if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
+                       return -ENODEV;
+       } else {
+               if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
+                       return -ENODEV;
+       }
+
+       st->set_param_save = adap->fe->ops.tuner_ops.set_params;
+       adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
+       return 0;
+}
+
+static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
+       60000, 15000, // internal, sampling
+       1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass
+       0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo
+       (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k
+       (0 << 25) | 0, // ifreq = 0.000000 MHz
+       20452225, // timf
+       12000000, // xtal_hz
+};
+
+static struct dib7000p_config dib7070p_dib7000p_config = {
+       .output_mpeg2_in_188_bytes = 1,
+
+       .agc_config_count = 1,
+       .agc = &dib7070_agc_config,
+       .bw  = &dib7070_bw_config_12_mhz,
+
+       .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+       .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+       .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+       .hostbus_diversity = 1,
+};
+
+/* STK7070P */
+static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
+{
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, &dib7070p_dib7000p_config);
+
+       adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &dib7070p_dib7000p_config);
+       return adap->fe == NULL ? -ENODEV : 0;
+}
+
+/* STK7070PD */
+static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
+       {
+               .output_mpeg2_in_188_bytes = 1,
+
+               .agc_config_count = 1,
+               .agc = &dib7070_agc_config,
+               .bw  = &dib7070_bw_config_12_mhz,
+
+               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+               .hostbus_diversity = 1,
+       }, {
+               .output_mpeg2_in_188_bytes = 1,
+
+               .agc_config_count = 1,
+               .agc = &dib7070_agc_config,
+               .bw  = &dib7070_bw_config_12_mhz,
+
+               .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
+               .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
+               .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
+
+               .hostbus_diversity = 1,
+       }
+};
+
+static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
+{
+       dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+       dib0700_ctrl_clock(adap->dev, 72, 1);
+
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+       msleep(10);
+       dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+       dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config);
+
+       adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
+       return adap->fe == NULL ? -ENODEV : 0;
+}
+
+static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
+{
+       adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
+       return adap->fe == NULL ? -ENODEV : 0;
+}
+
+/* DVB-USB and USB stuff follows */
 struct usb_device_id dib0700_usb_id_table[] = {
-               { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
+/* 0 */        { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
                { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P_PC) },
 
                { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
                { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
                { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
-               { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
+/* 5 */        { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
                { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500) },
                { USB_DEVICE(USB_VID_UNIWILL,   USB_PID_UNIWILL_STK7700P) },
                { USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
                { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
-               { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
-               { }             /* Terminating entry */
+/* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
+               { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV2000E) },
+               { USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
+               { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
+               { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700D) },
+/* 15 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070P) },
+               { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
+               { USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070PD) },
+               { USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
+               { USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500_PC) },
+/* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
+               { 0 }           /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
 
 #define DIB0700_DEFAULT_DEVICE_PROPERTIES \
        .caps              = DVB_USB_IS_AN_I2C_ADAPTER, \
        .usb_ctrl          = DEVICE_SPECIFIC, \
-       .firmware          = "dvb-usb-dib0700-01.fw", \
+       .firmware          = "dvb-usb-dib0700-03-pre1.fw", \
        .download_firmware = dib0700_download_firmware, \
        .no_reconnect      = 1, \
        .size_of_priv      = sizeof(struct dib0700_state), \
@@ -321,7 +862,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        },
                },
 
-               .num_device_descs = 6,
+               .num_device_descs = 7,
                .devices = {
                        {   "DiBcom STK7700P reference design",
                                { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
@@ -336,7 +877,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                                { NULL },
                        },
                        {   "Compro Videomate U500",
-                               { &dib0700_usb_id_table[6], NULL },
+                               { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
                                { NULL },
                        },
                        {   "Uniwill STK7700P based (Hama and others)",
@@ -346,8 +887,17 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                        {   "Leadtek Winfast DTV Dongle (STK7700P based)",
                                { &dib0700_usb_id_table[8], NULL },
                                { NULL },
+                       },
+                       {   "AVerMedia AVerTV DVB-T Express",
+                               { &dib0700_usb_id_table[20] },
+                               { NULL },
                        }
-               }
+               },
+
+               .rc_interval      = DEFAULT_RC_INTERVAL,
+               .rc_key_map       = dib0700_rc_keys,
+               .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
+               .rc_query         = dib0700_rc_query
        }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
 
                .num_adapters = 2,
@@ -371,8 +921,112 @@ struct dvb_usb_device_properties dib0700_devices[] = {
                                { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
                                { NULL },
                        },
+               },
+
+               .rc_interval      = DEFAULT_RC_INTERVAL,
+               .rc_key_map       = dib0700_rc_keys,
+               .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
+               .rc_query         = dib0700_rc_query
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 2,
+               .adapter = {
+                       {
+                               .frontend_attach  = stk7700d_frontend_attach,
+                               .tuner_attach     = stk7700d_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+                       }, {
+                               .frontend_attach  = stk7700d_frontend_attach,
+                               .tuner_attach     = stk7700d_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+                       }
+               },
+
+               .num_device_descs = 4,
+               .devices = {
+                       {   "Pinnacle PCTV 2000e",
+                               { &dib0700_usb_id_table[11], NULL },
+                               { NULL },
+                       },
+                       {   "Terratec Cinergy DT XS Diversity",
+                               { &dib0700_usb_id_table[12], NULL },
+                               { NULL },
+                       },
+                       {   "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
+                               { &dib0700_usb_id_table[13], NULL },
+                               { NULL },
+                       },
+                       {   "DiBcom STK7700D reference design",
+                               { &dib0700_usb_id_table[14], NULL },
+                               { NULL },
+                       },
+               },
+
+               .rc_interval      = DEFAULT_RC_INTERVAL,
+               .rc_key_map       = dib0700_rc_keys,
+               .rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
+               .rc_query         = dib0700_rc_query
+
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 1,
+               .adapter = {
+                       {
+                               .frontend_attach  = stk7070p_frontend_attach,
+                               .tuner_attach     = dib7070p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
+                       },
+               },
+
+               .num_device_descs = 2,
+               .devices = {
+                       {   "DiBcom STK7070P reference design",
+                               { &dib0700_usb_id_table[15], NULL },
+                               { NULL },
+                       },
+                       {   "Pinnacle PCTV DVB-T Flash Stick",
+                               { &dib0700_usb_id_table[16], NULL },
+                               { NULL },
+                       },
                }
-       }
+       }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+               .num_adapters = 2,
+               .adapter = {
+                       {
+                               .frontend_attach  = stk7070pd_frontend_attach0,
+                               .tuner_attach     = dib7070p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
+                       }, {
+                               .frontend_attach  = stk7070pd_frontend_attach1,
+                               .tuner_attach     = dib7070p_tuner_attach,
+
+                               DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+
+                               .size_of_priv     = sizeof(struct dib0700_adapter_state),
+                       }
+               },
+
+               .num_device_descs = 2,
+               .devices = {
+                       {   "DiBcom STK7070PD reference design",
+                               { &dib0700_usb_id_table[17], NULL },
+                               { NULL },
+                       },
+                       {   "Pinnacle PCTV Dual DVB-T Diversity Stick",
+                               { &dib0700_usb_id_table[18], NULL },
+                               { NULL },
+                       },
+               }
+       },
 };
 
 int dib0700_device_count = ARRAY_SIZE(dib0700_devices);
index 7dbe14321019a36c2c89ee24ea37ca3bff23bc06..d86cf9bee91c23fdd8ec0b528994b51b95cd6f7b 100644 (file)
@@ -1,5 +1,5 @@
 /* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
- * Typhoon/ Yuan DVB-T USB2.0 receiver.
+ * Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver.
  *
  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
  *
@@ -96,6 +96,7 @@ static struct dvb_usb_device_properties dtt200u_properties;
 static struct dvb_usb_device_properties wt220u_fc_properties;
 static struct dvb_usb_device_properties wt220u_properties;
 static struct dvb_usb_device_properties wt220u_zl0353_properties;
+static struct dvb_usb_device_properties wt220u_miglia_properties;
 
 static int dtt200u_usb_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
@@ -103,7 +104,8 @@ static int dtt200u_usb_probe(struct usb_interface *intf,
        if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 ||
                dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0 ||
                dvb_usb_device_init(intf,&wt220u_fc_properties,THIS_MODULE,NULL) == 0 ||
-               dvb_usb_device_init(intf,&wt220u_zl0353_properties,THIS_MODULE,NULL) == 0)
+               dvb_usb_device_init(intf,&wt220u_zl0353_properties,THIS_MODULE,NULL) == 0 ||
+               dvb_usb_device_init(intf,&wt220u_miglia_properties,THIS_MODULE,NULL) == 0)
                return 0;
 
        return -ENODEV;
@@ -119,6 +121,7 @@ static struct usb_device_id dtt200u_usb_table [] = {
        { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD)  },
        { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM)  },
        { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD)  },
+       { USB_DEVICE(USB_VID_MIGLIA, USB_PID_WT220U_ZAP250_COLD)  },
        { 0 },
 };
 MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
@@ -303,6 +306,25 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = {
        }
 };
 
+static struct dvb_usb_device_properties wt220u_miglia_properties = {
+       .usb_ctrl = CYPRESS_FX2,
+       .firmware = "dvb-usb-wt220u-miglia-01.fw",
+
+       .num_adapters = 1,
+       .generic_bulk_ctrl_endpoint = 0x01,
+
+       .num_device_descs = 1,
+       .devices = {
+               { .name = "WideView WT-220U PenType Receiver (Miglia)",
+                 .cold_ids = { &dtt200u_usb_table[9], NULL },
+                 /* This device turns into WT220U_ZL0353_WARM when fw
+                    has been uploaded */
+                 .warm_ids = { NULL },
+               },
+               { NULL },
+       }
+};
+
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver dtt200u_usb_driver = {
        .name           = "dvb_usb_dtt200u",
@@ -333,6 +355,6 @@ module_init(dtt200u_usb_module_init);
 module_exit(dtt200u_usb_module_exit);
 
 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
-MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D DVB-T USB2.0 devices");
+MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
index 4dfab02a8a0d526394bb14f3a89af2a5bd04d273..4fa3e895028a0596c7a792cb5e451aadceddc634 100644 (file)
@@ -12,7 +12,7 @@
 /* Vendor IDs */
 #define USB_VID_ADSTECH                                0x06e1
 #define USB_VID_AFATECH                                0x15a4
-#define USB_VID_ALCOR_MICRO            0x058f
+#define USB_VID_ALCOR_MICRO                    0x058f
 #define USB_VID_ALINK                          0x05e3
 #define USB_VID_ANCHOR                         0x0547
 #define USB_VID_ANUBIS_ELECTRONIC              0x10fd
@@ -34,6 +34,7 @@
 #define USB_VID_LEADTEK                                0x0413
 #define USB_VID_LITEON                         0x04ca
 #define USB_VID_MEDION                         0x1660
+#define USB_VID_MIGLIA                         0x18f3
 #define USB_VID_MSI                            0x0db0
 #define USB_VID_OPERA1                         0x695c
 #define USB_VID_PINNACLE                       0x2304
@@ -58,6 +59,7 @@
 #define USB_PID_COMPRO_DVBU2000_UNK_COLD               0x010c
 #define USB_PID_COMPRO_DVBU2000_UNK_WARM               0x010d
 #define USB_PID_COMPRO_VIDEOMATE_U500                  0x1e78
+#define USB_PID_COMPRO_VIDEOMATE_U500_PC               0x1e80
 #define USB_PID_DIBCOM_HOOK_DEFAULT                    0x0064
 #define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM             0x0065
 #define USB_PID_DIBCOM_MOD3000_COLD                    0x0bb8
@@ -66,6 +68,9 @@
 #define USB_PID_DIBCOM_MOD3001_WARM                    0x0bc7
 #define USB_PID_DIBCOM_STK7700P                                0x1e14
 #define USB_PID_DIBCOM_STK7700P_PC                     0x1e78
+#define USB_PID_DIBCOM_STK7700D                                0x1ef0
+#define USB_PID_DIBCOM_STK7070P                                0x1ebc
+#define USB_PID_DIBCOM_STK7070PD                       0x1ebe
 #define USB_PID_DIBCOM_ANCHOR_2135_COLD                        0x2131
 #define USB_PID_DPOSH_M9206_COLD                       0x9206
 #define USB_PID_DPOSH_M9206_WARM                       0xa090
 #define USB_PID_HAUPPAUGE_NOVA_T_500_2                 0x9950
 #define USB_PID_HAUPPAUGE_NOVA_T_STICK                 0x7050
 #define USB_PID_HAUPPAUGE_NOVA_T_STICK_2               0x7060
+#define USB_PID_HAUPPAUGE_NOVA_TD_STICK                        0x9580
+#define USB_PID_AVERMEDIA_EXPRESS                      0xb568
 #define USB_PID_AVERMEDIA_VOLAR                                0xa807
 #define USB_PID_AVERMEDIA_VOLAR_2                      0xb808
+#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY       0x005a
+#define USB_PID_PINNACLE_PCTV2000E                     0x022c
+#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH              0x0228
+#define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T     0x0229
+#define USB_PID_PCTV_200E                              0x020e
+#define USB_PID_PCTV_400E                              0x020f
+#define USB_PID_PCTV_450E                              0x0222
 #define USB_PID_NEBULA_DIGITV                          0x0201
 #define USB_PID_DVICO_BLUEBIRD_LGDT                    0xd820
 #define USB_PID_DVICO_BLUEBIRD_LG064F_COLD             0xd500
 #define USB_PID_MSI_MEGASKY580_55801                   0x5581
 #define USB_PID_KYE_DVB_T_COLD                         0x701e
 #define USB_PID_KYE_DVB_T_WARM                         0x701f
-#define USB_PID_PCTV_200E                              0x020e
-#define USB_PID_PCTV_400E                              0x020f
-#define USB_PID_PCTV_450E                              0x0222
 #define USB_PID_LITEON_DVB_T_COLD                      0xf000
 #define USB_PID_LITEON_DVB_T_WARM                      0xf001
 #define USB_PID_DIGIVOX_MINI_SL_COLD                   0xe360
 #define USB_PID_WINFAST_DTV_DONGLE_COLD                        0x6025
 #define USB_PID_WINFAST_DTV_DONGLE_WARM                        0x6026
 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P            0x6f00
-#define USB_PID_GENPIX_8PSK_COLD                       0x0200
-#define USB_PID_GENPIX_8PSK_WARM                       0x0201
+#define USB_PID_GENPIX_8PSK_REV_1_COLD                 0x0200
+#define USB_PID_GENPIX_8PSK_REV_1_WARM                 0x0201
+#define USB_PID_GENPIX_8PSK_REV_2                      0x0202
+#define USB_PID_GENPIX_SKYWALKER_1                     0x0203
+#define USB_PID_GENPIX_SKYWALKER_CW3K                  0x0204
 #define USB_PID_SIGMATEK_DVB_110                       0x6610
 #define USB_PID_MSI_DIGI_VOX_MINI_II                   0x1513
 #define USB_PID_OPERA1_COLD                            0x2830
index ffdde83d1e77be6be34e5068f9a1b34adbdcd5e6..cdd717c3fe45ac79c099a49397d529cf0ffdda5c 100644 (file)
@@ -24,7 +24,7 @@ MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0
 
 static int dvb_usb_force_pid_filter_usage;
 module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444);
-MODULE_PARM_DESC(disable_rc_polling, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
+MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
 
 static int dvb_usb_adapter_init(struct dvb_usb_device *d)
 {
index 6ccbdc9cd7725a58c444f9275d67a86f7c9a5c09..e37142d9271a83aa0f1b3e3575e21dc3c5a8a6f3 100644 (file)
@@ -1,7 +1,8 @@
 /* DVB USB compliant Linux driver for the
- *  - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *  - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
  *
- * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
+ * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
  *
  * Thanks to GENPIX for the sample code used to implement this module.
  *
 
 struct gp8psk_fe_state {
        struct dvb_frontend fe;
-
        struct dvb_usb_device *d;
-
+       u8 lock;
        u16 snr;
-
-       unsigned long next_snr_check;
+       unsigned long next_status_check;
+       unsigned long status_check_interval;
 };
 
+static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
+{
+       u8 buf[6];
+       if (time_after(jiffies,st->next_status_check)) {
+               gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
+               gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6);
+               st->snr = (buf[1]) << 8 | buf[0];
+               st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
+       }
+       return 0;
+}
+
 static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
 {
        struct gp8psk_fe_state *st = fe->demodulator_priv;
-       u8 lock;
+       gp8psk_fe_update_status(st);
 
-       if (gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0, 0, &lock,1))
-               return -EINVAL;
-
-       if (lock)
+       if (st->lock)
                *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
        else
                *status = 0;
 
+       if (*status & FE_HAS_LOCK)
+               st->status_check_interval = 1000;
+       else
+               st->status_check_interval = 100;
        return 0;
 }
 
@@ -60,33 +73,29 @@ static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
 static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
 {
        struct gp8psk_fe_state *st = fe->demodulator_priv;
-       u8 buf[2];
-
-       if (time_after(jiffies,st->next_snr_check)) {
-               gp8psk_usb_in_op(st->d,GET_SIGNAL_STRENGTH,0,0,buf,2);
-               *snr = (int)(buf[1]) << 8 | buf[0];
-               /* snr is reported in dBu*256 */
-               /* snr / 38.4 ~= 100% strength */
-               /* snr * 17 returns 100% strength as 65535 */
-               if (*snr <= 3855)
-                       *snr = (*snr<<4) + *snr; // snr * 17
-               else
-                       *snr = 65535;
-               st->next_snr_check = jiffies + (10*HZ)/1000;
-       } else {
-               *snr = st->snr;
-       }
+       gp8psk_fe_update_status(st);
+       /* snr is reported in dBu*256 */
+       *snr = st->snr;
        return 0;
 }
 
 static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
 {
-       return gp8psk_fe_read_snr(fe, strength);
+       struct gp8psk_fe_state *st = fe->demodulator_priv;
+       gp8psk_fe_update_status(st);
+       /* snr is reported in dBu*256 */
+       /* snr / 38.4 ~= 100% strength */
+       /* snr * 17 returns 100% strength as 65535 */
+       if (st->snr > 0xf00)
+               *strength = 0xffff;
+       else
+               *strength = (st->snr << 4) + st->snr; /* snr*17 */
+       return 0;
 }
 
 static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
 {
-       tune->min_delay_ms = 800;
+       tune->min_delay_ms = 200;
        return 0;
 }
 
@@ -124,7 +133,9 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
 
        gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10);
 
-       state->next_snr_check = jiffies;
+       state->lock = 0;
+       state->next_status_check = jiffies;
+       state->status_check_interval = 200;
 
        return 0;
 }
@@ -190,6 +201,12 @@ static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t volt
        return 0;
 }
 
+static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff)
+{
+       struct gp8psk_fe_state* state = fe->demodulator_priv;
+       return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0);
+}
+
 static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
 {
        struct gp8psk_fe_state* state = fe->demodulator_priv;
@@ -235,10 +252,10 @@ success:
 
 static struct dvb_frontend_ops gp8psk_fe_ops = {
        .info = {
-               .name                   = "Genpix 8psk-USB DVB-S",
+               .name                   = "Genpix 8psk-to-USB2 DVB-S",
                .type                   = FE_QPSK,
-               .frequency_min          = 950000,
-               .frequency_max          = 2150000,
+               .frequency_min          = 800000,
+               .frequency_max          = 2250000,
                .frequency_stepsize     = 100,
                .symbol_rate_min        = 1000000,
                .symbol_rate_max        = 45000000,
@@ -269,4 +286,5 @@ static struct dvb_frontend_ops gp8psk_fe_ops = {
        .set_tone = gp8psk_fe_set_tone,
        .set_voltage = gp8psk_fe_set_voltage,
        .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd,
+       .enable_high_lnb_voltage = gp8psk_fe_enable_high_lnb_voltage
 };
index 518d67fca5e89d4636a11810b6edf2a21539765a..92147ee3e14ffe69a134f5bfea59df244a951c51 100644 (file)
@@ -1,7 +1,8 @@
 /* DVB USB compliant Linux driver for the
- *  - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *  - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
  *
- * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
+ * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
  *
  * Thanks to GENPIX for the sample code used to implement this module.
  *
@@ -40,7 +41,7 @@ int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
        }
 
        if (ret < 0 || ret != blen) {
-               warn("usb in operation failed.");
+               warn("usb in %d operation failed.", req);
                ret = -EIO;
        } else
                ret = 0;
@@ -97,10 +98,10 @@ static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
        if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
                goto out_rel_fw;
 
-       info("downloaidng bcm4500 firmware from file '%s'",bcm4500_firmware);
+       info("downloading bcm4500 firmware from file '%s'",bcm4500_firmware);
 
        ptr = fw->data;
-       buf = kmalloc(512, GFP_KERNEL | GFP_DMA);
+       buf = kmalloc(64, GFP_KERNEL | GFP_DMA);
 
        while (ptr[0] != 0xff) {
                u16 buflen = ptr[0] + 4;
@@ -129,25 +130,34 @@ out_rel_fw:
 static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
 {
        u8 status, buf;
+       int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
+
        if (onoff) {
                gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
-               if (! (status & 0x01))  /* started */
+               if (! (status & bm8pskStarted)) {  /* started */
+                       if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
+                               gp8psk_usb_out_op(d, CW3K_INIT, 1, 0, NULL, 0);
                        if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
                                return -EINVAL;
+               }
 
-               if (! (status & 0x02)) /* BCM4500 firmware loaded */
-                       if(gp8psk_load_bcm4500fw(d))
-                               return EINVAL;
+               if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+                       if (! (status & bm8pskFW_Loaded)) /* BCM4500 firmware loaded */
+                               if(gp8psk_load_bcm4500fw(d))
+                                       return EINVAL;
 
-               if (! (status & 0x04)) /* LNB Power */
+               if (! (status & bmIntersilOn)) /* LNB Power */
                        if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
                                        &buf, 1))
                                return EINVAL;
 
-               /* Set DVB mode */
-               if(gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
-                       return -EINVAL;
-               gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
+               /* Set DVB mode to 1 */
+               if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+                       if (gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
+                               return EINVAL;
+               /* Abort possible TS (if previous tune crashed) */
+               if (gp8psk_usb_out_op(d, ARM_TRANSFER, 0, 0, NULL, 0))
+                       return EINVAL;
        } else {
                /* Turn off LNB power */
                if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
@@ -155,11 +165,28 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
                /* Turn off 8psk power */
                if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
                        return -EINVAL;
-
+               if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
+                       gp8psk_usb_out_op(d, CW3K_INIT, 0, 0, NULL, 0);
        }
        return 0;
 }
 
+int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
+{
+       u8 buf;
+       int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
+       /* Turn off 8psk power */
+       if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
+               return -EINVAL;
+       /* Turn On 8psk power */
+       if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
+               return -EINVAL;
+       /* load BCM4500 firmware */
+       if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
+               if (gp8psk_load_bcm4500fw(d))
+                       return EINVAL;
+       return 0;
+}
 
 static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
@@ -177,12 +204,22 @@ static struct dvb_usb_device_properties gp8psk_properties;
 static int gp8psk_usb_probe(struct usb_interface *intf,
                const struct usb_device_id *id)
 {
-       return dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL);
+       int ret;
+       struct usb_device *udev = interface_to_usbdev(intf);
+       ret =  dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL);
+       if (ret == 0) {
+               info("found Genpix USB device pID = %x (hex)",
+                       le16_to_cpu(udev->descriptor.idProduct));
+       }
+       return ret;
 }
 
 static struct usb_device_id gp8psk_usb_table [] = {
-           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_COLD) },
-           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_WARM) },
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_COLD) },
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) },
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) },
+           { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) },
            { 0 },
 };
 MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
@@ -213,12 +250,24 @@ static struct dvb_usb_device_properties gp8psk_properties = {
 
        .generic_bulk_ctrl_endpoint = 0x01,
 
-       .num_device_descs = 1,
+       .num_device_descs = 4,
        .devices = {
-               { .name = "Genpix 8PSK-USB DVB-S USB2.0 receiver",
+               { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
                  .cold_ids = { &gp8psk_usb_table[0], NULL },
                  .warm_ids = { &gp8psk_usb_table[1], NULL },
                },
+               { .name = "Genpix 8PSK-to-USB2 Rev.2 DVB-S receiver",
+                 .cold_ids = { NULL },
+                 .warm_ids = { &gp8psk_usb_table[2], NULL },
+               },
+               { .name = "Genpix SkyWalker-1 DVB-S receiver",
+                 .cold_ids = { NULL },
+                 .warm_ids = { &gp8psk_usb_table[3], NULL },
+               },
+               { .name = "Genpix SkyWalker-CW3K DVB-S receiver",
+                 .cold_ids = { NULL },
+                 .warm_ids = { &gp8psk_usb_table[4], NULL },
+               },
                { NULL },
        }
 };
@@ -253,6 +302,6 @@ module_init(gp8psk_usb_module_init);
 module_exit(gp8psk_usb_module_exit);
 
 MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
-MODULE_DESCRIPTION("Driver for Genpix 8psk-USB DVB-S USB2.0");
-MODULE_VERSION("1.0");
+MODULE_DESCRIPTION("Driver for Genpix 8psk-to-USB2 DVB-S");
+MODULE_VERSION("1.1");
 MODULE_LICENSE("GPL");
index 3eba7061011c72e9e4c7b5ce9892097f70a0c8cb..e83a57506cfa945b2f97d16fb8fc9808221f981d 100644 (file)
@@ -1,7 +1,8 @@
 /* DVB USB compliant Linux driver for the
- *  - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *  - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
  *
  * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
  *
  * Thanks to GENPIX for the sample code used to implement this module.
  *
@@ -30,21 +31,37 @@ extern int dvb_usb_gp8psk_debug;
 #define TH_COMMAND_IN                     0xC0
 #define TH_COMMAND_OUT                    0xC1
 
-/* command bytes */
-#define GET_8PSK_CONFIG                 0x80
+/* gp8psk commands */
+
+#define GET_8PSK_CONFIG                 0x80    /* in */
 #define SET_8PSK_CONFIG                 0x81
+#define I2C_WRITE                      0x83
+#define I2C_READ                       0x84
 #define ARM_TRANSFER                    0x85
 #define TUNE_8PSK                       0x86
-#define GET_SIGNAL_STRENGTH             0x87
+#define GET_SIGNAL_STRENGTH             0x87    /* in */
 #define LOAD_BCM4500                    0x88
-#define BOOT_8PSK                       0x89
-#define START_INTERSIL                  0x8A
+#define BOOT_8PSK                       0x89    /* in */
+#define START_INTERSIL                  0x8A    /* in */
 #define SET_LNB_VOLTAGE                 0x8B
 #define SET_22KHZ_TONE                  0x8C
 #define SEND_DISEQC_COMMAND             0x8D
 #define SET_DVB_MODE                    0x8E
 #define SET_DN_SWITCH                   0x8F
-#define GET_SIGNAL_LOCK                 0x90
+#define GET_SIGNAL_LOCK                 0x90    /* in */
+#define GET_SERIAL_NUMBER               0x93    /* in */
+#define USE_EXTRA_VOLT                  0x94
+#define CW3K_INIT                      0x9d
+
+/* PSK_configuration bits */
+#define bm8pskStarted                   0x01
+#define bm8pskFW_Loaded                 0x02
+#define bmIntersilOn                    0x04
+#define bmDVBmode                       0x08
+#define bm22kHz                         0x10
+#define bmSEL18V                        0x20
+#define bmDCtuned                       0x40
+#define bmArmed                         0x80
 
 /* Satellite modulation modes */
 #define ADV_MOD_DVB_QPSK 0     /* DVB-S QPSK */
@@ -75,5 +92,6 @@ extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
 extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
 extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
                             u16 index, u8 *b, int blen);
+extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
 
 #endif
index 69a46b3607a2a1d63e42dc2daacb2983896039c8..5bbd2d5192f0a4130cd47a28808b3ff94c707040 100644 (file)
@@ -159,7 +159,7 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
                return 0;
        }
 
-       for (i = 0; i < sizeof(vp7045_rc_keys)/sizeof(struct dvb_usb_rc_key); i++)
+       for (i = 0; i < ARRAY_SIZE(vp7045_rc_keys); i++)
                if (vp7045_rc_keys[i].data == key) {
                        *state = REMOTE_KEY_PRESSED;
                        *event = vp7045_rc_keys[i].event;
index ff448761dcef49f18f6416c901176d9ca0f0c385..59b9ed1f1aec6b5f8769d17bc11389d195577e7f 100644 (file)
@@ -283,6 +283,14 @@ config DVB_LGDT330X
          An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
          to support this frontend.
 
+config DVB_S5H1409
+       tristate "Samsung S5H1409 based"
+       depends on DVB_CORE && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+         to support this frontend.
+
 comment "Tuners/PLL support"
        depends on DVB_CORE
 
@@ -291,7 +299,7 @@ config DVB_PLL
        depends on DVB_CORE && I2C
        default m if DVB_FE_CUSTOMISE
        help
-         This module driver a number of tuners based on PLL chips with a
+         This module drives a number of tuners based on PLL chips with a
          common I2C interface. Say Y when you want to support these tuners.
 
 config DVB_TDA826X
@@ -322,6 +330,29 @@ config DVB_TUNER_MT2060
        help
          A driver for the silicon IF tuner MT2060 from Microtune.
 
+config DVB_TUNER_MT2266
+       tristate "Microtune MT2266 silicon tuner"
+       depends on I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for the silicon baseband tuner MT2266 from Microtune.
+
+config DVB_TUNER_MT2131
+       tristate "Microtune MT2131 silicon tuner"
+       depends on I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for the silicon baseband tuner MT2131 from Microtune.
+
+config DVB_TUNER_DIB0070
+       tristate "DiBcom DiB0070 silicon base-band tuner"
+       depends on I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         A driver for the silicon baseband tuner DiB0070 from DiBcom.
+         This device is only used inside a SiP called togther with a
+         demodulator for now.
+
 comment "Miscellaneous devices"
        depends on DVB_CORE
 
index 156b062e02c40d800b78f6c66fd3b3b7396d5da3..4b8ad1f132aa380a656940070b5a80e520cf3ff4 100644 (file)
@@ -40,5 +40,9 @@ obj-$(CONFIG_DVB_TDA10086) += tda10086.o
 obj-$(CONFIG_DVB_TDA826X) += tda826x.o
 obj-$(CONFIG_DVB_TDA827X) += tda827x.o
 obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
+obj-$(CONFIG_DVB_TUNER_MT2266) += mt2266.o
+obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
 obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o
 obj-$(CONFIG_DVB_TUA6100) += tua6100.o
+obj-$(CONFIG_DVB_TUNER_MT2131) += mt2131.o
+obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
index baeb311de8931b82a12bfa00dbe3513051ec8a0b..a913f49c062b98a46d4fdbf75b38b62b1590083f 100644 (file)
@@ -33,7 +33,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/jiffies.h>
index 13ad1bfae663f0c0386960d7314b7c65d4ff6ca7..11a4968f18cb301be6b5df5676ac2d769ae50631 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include "dvb_frontend.h"
index 10fc0c8316dd2dab1d1bb48171a367c8f25a0fc9..b03d8283c37d93233dc0d4722dc1fb60a0c9989d 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 
 #include "dvb_frontend.h"
index 0834c0677fef8f86ba807b272e21b782d6ebb394..d74fdbd63361f77e621d1cf1e6d7f4c1b8d5f322 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 
 #include "dvb_frontend.h"
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
new file mode 100644 (file)
index 0000000..481eaa6
--- /dev/null
@@ -0,0 +1,580 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
+ *
+ * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ */
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "dib0070.h"
+#include "dibx000_common.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB0070: "); printk(args); printk("\n"); } } while (0)
+
+#define DIB0070_P1D  0x00
+#define DIB0070_P1F  0x01
+#define DIB0070_P1G  0x03
+#define DIB0070S_P1A 0x02
+
+struct dib0070_state {
+       struct i2c_adapter *i2c;
+       struct dvb_frontend *fe;
+       const struct dib0070_config *cfg;
+       u16 wbd_ff_offset;
+       u8 revision;
+};
+
+static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
+{
+       u8 b[2];
+       struct i2c_msg msg[2] = {
+               { .addr = state->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
+               { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b,  .len = 2 },
+       };
+       if (i2c_transfer(state->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "DiB0070 I2C read failed\n");
+               return 0;
+       }
+       return (b[0] << 8) | b[1];
+}
+
+static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
+{
+       u8 b[3] = { reg, val >> 8, val & 0xff };
+       struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
+       if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "DiB0070 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+#define HARD_RESET(state) do { if (state->cfg->reset) { state->cfg->reset(state->fe,1); msleep(10); state->cfg->reset(state->fe,0); msleep(10); } } while (0)
+
+static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
+{
+       struct dib0070_state *st = fe->tuner_priv;
+       u16 tmp = 0;
+       tmp = dib0070_read_reg(st, 0x02) & 0x3fff;
+
+    switch(BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)) {
+               case  8000:
+                       tmp |= (0 << 14);
+                       break;
+               case  7000:
+                       tmp |= (1 << 14);
+                       break;
+       case  6000:
+                       tmp |= (2 << 14);
+                       break;
+       case 5000:
+               default:
+                       tmp |= (3 << 14);
+                       break;
+       }
+       dib0070_write_reg(st, 0x02, tmp);
+       return 0;
+}
+
+static void dib0070_captrim(struct dib0070_state *st, u16 LO4)
+{
+       int8_t captrim, fcaptrim, step_sign, step;
+       u16 adc, adc_diff = 3000;
+
+
+
+       dib0070_write_reg(st, 0x0f, 0xed10);
+       dib0070_write_reg(st, 0x17,    0x0034);
+
+       dib0070_write_reg(st, 0x18, 0x0032);
+       msleep(2);
+
+       step = captrim = fcaptrim = 64;
+
+       do {
+               step /= 2;
+               dib0070_write_reg(st, 0x14, LO4 | captrim);
+               msleep(1);
+               adc = dib0070_read_reg(st, 0x19);
+
+               dprintk( "CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", captrim, adc, (u32) adc*(u32)1800/(u32)1024);
+
+               if (adc >= 400) {
+                       adc -= 400;
+                       step_sign = -1;
+               } else {
+                       adc = 400 - adc;
+                       step_sign = 1;
+               }
+
+               if (adc < adc_diff) {
+                       dprintk( "CAPTRIM=%hd is closer to target (%hd/%hd)", captrim, adc, adc_diff);
+                       adc_diff = adc;
+                       fcaptrim = captrim;
+
+
+
+               }
+               captrim += (step_sign * step);
+       } while (step >= 1);
+
+       dib0070_write_reg(st, 0x14, LO4 | fcaptrim);
+       dib0070_write_reg(st, 0x18, 0x07ff);
+}
+
+#define LPF    100                       // define for the loop filter 100kHz by default 16-07-06
+#define LO4_SET_VCO_HFDIV(l, v, h)   l |= ((v) << 11) | ((h) << 7)
+#define LO4_SET_SD(l, s)             l |= ((s) << 14) | ((s) << 12)
+#define LO4_SET_CTRIM(l, c)          l |=  (c) << 10
+static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
+{
+       struct dib0070_state *st = fe->tuner_priv;
+       u32 freq = ch->frequency/1000 + (BAND_OF_FREQUENCY(ch->frequency/1000) == BAND_VHF ? st->cfg->freq_offset_khz_vhf : st->cfg->freq_offset_khz_uhf);
+
+       u8 band = BAND_OF_FREQUENCY(freq), c;
+
+       /*******************VCO***********************************/
+       u16 lo4 = 0;
+
+       u8 REFDIV, PRESC = 2;
+       u32 FBDiv, Rest, FREF, VCOF_kHz;
+       u16 Num, Den;
+       /*******************FrontEnd******************************/
+       u16 value = 0;
+
+       dprintk( "Tuning for Band: %hd (%d kHz)", band, freq);
+
+
+       dib0070_write_reg(st, 0x17, 0x30);
+
+       dib0070_set_bandwidth(fe, ch);  /* c is used as HF */
+       switch (st->revision) {
+               case DIB0070S_P1A:
+                       switch (band) {
+                               case BAND_LBAND:
+                                       LO4_SET_VCO_HFDIV(lo4, 1, 1);
+                                       c = 2;
+                                       break;
+                               case BAND_SBAND:
+                                       LO4_SET_VCO_HFDIV(lo4, 0, 0);
+                                       LO4_SET_CTRIM(lo4, 1);;
+                                       c = 1;
+                                       break;
+                               case BAND_UHF:
+                               default:
+                                       if (freq < 570000) {
+                                               LO4_SET_VCO_HFDIV(lo4, 1, 3);
+                                               PRESC = 6; c = 6;
+                                       } else if (freq < 680000) {
+                                               LO4_SET_VCO_HFDIV(lo4, 0, 2);
+                                               c = 4;
+                                       } else {
+                                               LO4_SET_VCO_HFDIV(lo4, 1, 2);
+                                               c = 4;
+                                       }
+                                       break;
+                       } break;
+
+               case DIB0070_P1G:
+               case DIB0070_P1F:
+               default:
+                       switch (band) {
+                               case BAND_FM:
+                                               LO4_SET_VCO_HFDIV(lo4, 0, 7);
+                                               c = 24;
+                                       break;
+                               case BAND_LBAND:
+                                               LO4_SET_VCO_HFDIV(lo4, 1, 0);
+                                               c = 2;
+                                       break;
+                               case BAND_VHF:
+                                       if (freq < 180000) {
+                                               LO4_SET_VCO_HFDIV(lo4, 0, 3);
+                                               c = 16;
+                                       } else if (freq < 190000) {
+                                               LO4_SET_VCO_HFDIV(lo4, 1, 3);
+                                               c = 16;
+                                       } else {
+                                               LO4_SET_VCO_HFDIV(lo4, 0, 6);
+                                               c = 12;
+                                       }
+                                       break;
+
+                               case BAND_UHF:
+                               default:
+                                       if (freq < 570000) {
+                                               LO4_SET_VCO_HFDIV(lo4, 1, 5);
+                                               c = 6;
+                                       } else if (freq < 700000) {
+                                               LO4_SET_VCO_HFDIV(lo4, 0, 1);
+                                               c = 4;
+                                       } else {
+                                               LO4_SET_VCO_HFDIV(lo4, 1, 1);
+                                               c = 4;
+                                       }
+                                       break;
+                       }
+               break;
+       }
+
+       dprintk( "HFDIV code: %hd", (lo4 >> 7) & 0xf);
+       dprintk( "VCO = %hd", (lo4 >> 11) & 0x3);
+
+
+       VCOF_kHz = (c * freq) * 2;
+       dprintk( "VCOF in kHz: %d ((%hd*%d) << 1))",VCOF_kHz, c, freq);
+
+       switch (band) {
+               case BAND_VHF:
+                       REFDIV = (u8) ((st->cfg->clock_khz + 9999) / 10000);
+                       break;
+               case BAND_FM:
+                       REFDIV = (u8) ((st->cfg->clock_khz) / 1000);
+                       break;
+               default:
+                       REFDIV = (u8) ( st->cfg->clock_khz  / 10000);
+                       break;
+       }
+       FREF = st->cfg->clock_khz / REFDIV;
+
+       dprintk( "REFDIV: %hd, FREF: %d", REFDIV, FREF);
+
+
+
+       switch (st->revision) {
+               case DIB0070S_P1A:
+                       FBDiv = (VCOF_kHz / PRESC / FREF);
+                       Rest  = (VCOF_kHz / PRESC) - FBDiv * FREF;
+                       break;
+
+               case DIB0070_P1G:
+               case DIB0070_P1F:
+               default:
+                       FBDiv = (freq / (FREF / 2));
+                       Rest  = 2 * freq - FBDiv * FREF;
+                       break;
+       }
+
+
+            if (Rest < LPF)              Rest = 0;
+       else if (Rest < 2 * LPF)          Rest = 2 * LPF;
+       else if (Rest > (FREF - LPF))   { Rest = 0 ; FBDiv += 1; }
+       else if (Rest > (FREF - 2 * LPF)) Rest = FREF - 2 * LPF;
+       Rest = (Rest * 6528) / (FREF / 10);
+       dprintk( "FBDIV: %d, Rest: %d", FBDiv, Rest);
+
+       Num = 0;
+       Den = 1;
+
+       if (Rest > 0) {
+               LO4_SET_SD(lo4, 1);
+               Den = 255;
+               Num = (u16)Rest;
+       }
+       dprintk( "Num: %hd, Den: %hd, SD: %hd",Num, Den, (lo4 >> 12) & 0x1);
+
+
+
+       dib0070_write_reg(st, 0x11, (u16)FBDiv);
+
+
+       dib0070_write_reg(st, 0x12, (Den << 8) | REFDIV);
+
+
+       dib0070_write_reg(st, 0x13, Num);
+
+
+       value = 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001;
+
+       switch (band) {
+               case BAND_UHF:   value |= 0x4000 | 0x0800; break;
+               case BAND_LBAND: value |= 0x2000 | 0x0400; break;
+               default:         value |= 0x8000 | 0x1000; break;
+       }
+       dib0070_write_reg(st, 0x20, value);
+
+       dib0070_captrim(st, lo4);
+       if (st->revision == DIB0070S_P1A) {
+               if (band == BAND_SBAND)
+                       dib0070_write_reg(st, 0x15, 0x16e2);
+               else
+                       dib0070_write_reg(st, 0x15, 0x56e5);
+       }
+
+
+
+       switch (band) {
+               case BAND_UHF:   value = 0x7c82; break;
+               case BAND_LBAND: value = 0x7c84; break;
+               default:         value = 0x7c81; break;
+       }
+       dib0070_write_reg(st, 0x0f, value);
+       dib0070_write_reg(st, 0x06, 0x3fff);
+
+       /* Front End */
+       /* c == TUNE, value = SWITCH */
+       c = 0;
+       value = 0;
+       switch (band) {
+               case BAND_FM:
+                       c = 0; value = 1;
+               break;
+
+               case BAND_VHF:
+                       if (freq <= 180000) c = 0;
+                       else if (freq <= 188200) c = 1;
+                       else if (freq <= 196400) c = 2;
+                       else c = 3;
+                       value = 1;
+               break;
+
+               case BAND_LBAND:
+                       if (freq <= 1500000) c = 0;
+                       else if (freq <= 1600000) c = 1;
+                       else c = 3;
+               break;
+
+               case BAND_SBAND:
+                       c = 7;
+                       dib0070_write_reg(st, 0x1d,0xFFFF);
+               break;
+
+               case BAND_UHF:
+               default:
+                       if (st->cfg->flip_chip) {
+                               if (freq <= 550000) c = 0;
+                               else if (freq <= 590000) c = 1;
+                               else if (freq <= 666000) c = 3;
+                               else c = 5;
+                       } else {
+                               if (freq <= 550000) c = 2;
+                               else if (freq <= 650000) c = 3;
+                               else if (freq <= 750000) c = 5;
+                               else if (freq <= 850000) c = 6;
+                               else c = 7;
+                       }
+                       value = 2;
+               break;
+       }
+
+       /* default: LNA_MATCH=7, BIAS=3 */
+       dib0070_write_reg(st, 0x07, (value << 11) | (7 << 8) | (c << 3) | (3 << 0));
+       dib0070_write_reg(st, 0x08, (c << 10) | (3 << 7) | (127));
+       dib0070_write_reg(st, 0x0d, 0x0d80);
+
+
+       dib0070_write_reg(st, 0x18,   0x07ff);
+       dib0070_write_reg(st, 0x17, 0x0033);
+
+       return 0;
+}
+
+static int dib0070_wakeup(struct dvb_frontend *fe)
+{
+       struct dib0070_state *st = fe->tuner_priv;
+       if (st->cfg->sleep)
+               st->cfg->sleep(fe, 0);
+       return 0;
+}
+
+static int dib0070_sleep(struct dvb_frontend *fe)
+{
+       struct dib0070_state *st = fe->tuner_priv;
+       if (st->cfg->sleep)
+               st->cfg->sleep(fe, 1);
+       return 0;
+}
+
+static u16 dib0070_p1f_defaults[] =
+
+{
+       7, 0x02,
+               0x0008,
+               0x0000,
+               0x0000,
+               0x0000,
+               0x0000,
+               0x0002,
+               0x0100,
+
+       3, 0x0d,
+               0x0d80,
+               0x0001,
+               0x0000,
+
+       4, 0x11,
+               0x0000,
+               0x0103,
+               0x0000,
+               0x0000,
+
+       3, 0x16,
+               0x0004 | 0x0040,
+               0x0030,
+               0x07ff,
+
+       6, 0x1b,
+               0x4112,
+               0xff00,
+               0xc07f,
+               0x0000,
+               0x0180,
+               0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
+
+       0,
+};
+
+static void dib0070_wbd_calibration(struct dib0070_state *state)
+{
+       u16 wbd_offs;
+       dib0070_write_reg(state, 0x0f, 0x6d81);
+       dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
+       msleep(9);
+       wbd_offs = dib0070_read_reg(state, 0x19);
+       dib0070_write_reg(state, 0x20, 0);
+       state->wbd_ff_offset = ((wbd_offs * 8 * 18 / 33 + 1) / 2);
+       dprintk( "WBDStart = %d (Vargen) - FF = %hd", (u32) wbd_offs * 1800/1024, state->wbd_ff_offset);
+}
+
+u16 dib0070_wbd_offset(struct dvb_frontend *fe)
+{
+       struct dib0070_state *st = fe->tuner_priv;
+       return st->wbd_ff_offset;
+}
+
+EXPORT_SYMBOL(dib0070_wbd_offset);
+static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
+{
+       struct dib0070_state *state = fe->tuner_priv;
+    u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
+       dprintk( "CTRL_LO5: 0x%x", lo5);
+       return dib0070_write_reg(state, 0x15, lo5);
+}
+
+#define pgm_read_word(w) (*w)
+static int dib0070_reset(struct dib0070_state *state)
+{
+       u16 l, r, *n;
+
+       HARD_RESET(state);
+
+
+#ifndef FORCE_SBAND_TUNER
+       if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
+               state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
+       else
+#endif
+               state->revision = DIB0070S_P1A;
+
+       /* P1F or not */
+       dprintk( "Revision: %x", state->revision);
+
+       if (state->revision == DIB0070_P1D) {
+               dprintk( "Error: this driver is not to be used meant for P1D or earlier");
+               return -EINVAL;
+       }
+
+       n = (u16 *) dib0070_p1f_defaults;
+       l = pgm_read_word(n++);
+       while (l) {
+               r = pgm_read_word(n++);
+               do {
+                       dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
+                       r++;
+               } while (--l);
+               l = pgm_read_word(n++);
+       }
+
+       if (state->cfg->force_crystal_mode != 0)
+               r = state->cfg->force_crystal_mode;
+       else if (state->cfg->clock_khz >= 24000)
+               r = 1;
+       else
+               r = 2;
+
+       r |= state->cfg->osc_buffer_state << 3;
+
+       dib0070_write_reg(state, 0x10, r);
+       dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 4));
+
+       if (state->cfg->invert_iq) {
+               r = dib0070_read_reg(state, 0x02) & 0xffdf;
+               dib0070_write_reg(state, 0x02, r | (1 << 5));
+       }
+
+
+       if (state->revision == DIB0070S_P1A)
+               dib0070_set_ctrl_lo5(state->fe, 4, 7, 3, 1);
+       else
+               dib0070_set_ctrl_lo5(state->fe, 4, 4, 2, 0);
+
+       dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
+       return 0;
+}
+
+
+static int dib0070_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static struct dvb_tuner_ops dib0070_ops = {
+       .info = {
+               .name           = "DiBcom DiB0070",
+               .frequency_min  =  45000000,
+               .frequency_max  = 860000000,
+               .frequency_step =      1000,
+       },
+       .release       = dib0070_release,
+
+       .init          = dib0070_wakeup,
+       .sleep         = dib0070_sleep,
+       .set_params    = dib0070_tune_digital,
+//     .get_frequency = dib0070_get_frequency,
+//     .get_bandwidth = dib0070_get_bandwidth
+};
+
+struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
+{
+       struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL);
+       if (state == NULL)
+               return NULL;
+
+       state->cfg = cfg;
+       state->i2c = i2c;
+       state->fe  = fe;
+       fe->tuner_priv = state;
+
+       if (dib0070_reset(state) != 0)
+               goto free_mem;
+
+       dib0070_wbd_calibration(state);
+
+       printk(KERN_INFO "DiB0070: successfully identified\n");
+       memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = state;
+       return fe;
+
+free_mem:
+       kfree(state);
+       fe->tuner_priv = NULL;
+       return NULL;
+}
+EXPORT_SYMBOL(dib0070_attach);
+
+MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
new file mode 100644 (file)
index 0000000..786e37d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
+ *
+ * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
+ *
+ * This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation, version 2.
+ */
+#ifndef DIB0070_H
+#define DIB0070_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+#define DEFAULT_DIB0070_I2C_ADDRESS 0x60
+
+struct dib0070_config {
+       u8 i2c_address;
+
+       /* tuner pins controlled externally */
+       int (*reset) (struct dvb_frontend *, int);
+       int (*sleep) (struct dvb_frontend *, int);
+
+       /*  offset in kHz */
+       int freq_offset_khz_uhf;
+       int freq_offset_khz_vhf;
+
+       u8 osc_buffer_state; /* 0= normal, 1= tri-state */
+       u32  clock_khz;
+       u8 clock_pad_drive; /* (Drive + 1) * 2mA */
+
+       u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */
+
+       u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */
+
+       u8 flip_chip;
+};
+
+extern struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
+extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open);
+extern u16 dib0070_wbd_offset(struct dvb_frontend *);
+
+#endif
index b6adea5ffeb89b04851c0d55ccd952b6077ade91..136b9d2164d734c6fab4dbf433d797afadc4407f 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/string.h>
index 054d7e6d9662d5715e59b1d7e30ce1f0bbab4701..edae0be063f5819f73e63e6ffb238ddbba8961a4 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Driver for DiBcom DiB3000MC/P-demodulator.
  *
- * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
+ * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
  * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
  *
  * This code is partially based on the previous dib3000mc.c .
 
 #include <linux/kernel.h>
 #include <linux/i2c.h>
-//#include <linux/init.h>
-//#include <linux/delay.h>
-//#include <linux/string.h>
-//#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 
@@ -26,7 +22,11 @@ static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
 
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); } } while (0)
+static int buggy_sfn_workaround;
+module_param(buggy_sfn_workaround, int, 0644);
+MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
 
 struct dib3000mc_state {
        struct dvb_frontend demod;
@@ -42,6 +42,8 @@ struct dib3000mc_state {
        fe_bandwidth_t current_bandwidth;
 
        u16 dev_id;
+
+       u8 sfn_workaround_active :1;
 };
 
 static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
@@ -71,7 +73,6 @@ static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
        return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
-
 static int dib3000mc_identify(struct dib3000mc_state *state)
 {
        u16 value;
@@ -92,7 +93,7 @@ static int dib3000mc_identify(struct dib3000mc_state *state)
        return 0;
 }
 
-static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset)
+static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
 {
        u32 timf;
 
@@ -103,7 +104,7 @@ static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw,
        } else
                timf = state->timf;
 
-       timf *= (BW_INDEX_TO_KHZ(bw) / 1000);
+       timf *= (bw / 1000);
 
        if (update_offset) {
                s16 tim_offs = dib3000mc_read_word(state, 416);
@@ -111,17 +112,17 @@ static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw,
                if (tim_offs &  0x2000)
                        tim_offs -= 0x4000;
 
-               if (nfft == 0)
+               if (nfft == TRANSMISSION_MODE_2K)
                        tim_offs *= 4;
 
                timf += tim_offs;
-               state->timf = timf / (BW_INDEX_TO_KHZ(bw) / 1000);
+               state->timf = timf / (bw / 1000);
        }
 
        dprintk("timf: %d\n", timf);
 
-       dib3000mc_write_word(state, 23, timf >> 16);
-       dib3000mc_write_word(state, 24, timf & 0xffff);
+       dib3000mc_write_word(state, 23, (u16) (timf >> 16));
+       dib3000mc_write_word(state, 24, (u16) (timf      ) & 0xffff);
 
        return 0;
 }
@@ -209,31 +210,30 @@ static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
        return ret;
 }
 
-static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw)
+static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
 {
-       struct dib3000mc_state *state = demod->demodulator_priv;
        u16 bw_cfg[6] = { 0 };
        u16 imp_bw_cfg[3] = { 0 };
        u16 reg;
 
 /* settings here are for 27.7MHz */
        switch (bw) {
-               case BANDWIDTH_8_MHZ:
+               case 8000:
                        bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
                        imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
                        break;
 
-               case BANDWIDTH_7_MHZ:
+               case 7000:
                        bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
                        imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
                        break;
 
-               case BANDWIDTH_6_MHZ:
+               case 6000:
                        bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
                        imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
                        break;
 
-               case 255 /* BANDWIDTH_5_MHZ */:
+               case 5000:
                        bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
                        imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
                        break;
@@ -257,7 +257,7 @@ static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw)
                dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
 
        // Timing configuration
-       dib3000mc_set_timing(state, 0, bw, 0);
+       dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
 
        return 0;
 }
@@ -276,7 +276,7 @@ static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode,
        for (i = 58; i < 87; i++)
                dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
 
-       if (nfft == 1) {
+       if (nfft == TRANSMISSION_MODE_8K) {
                dib3000mc_write_word(state, 58, 0x3b);
                dib3000mc_write_word(state, 84, 0x00);
                dib3000mc_write_word(state, 85, 0x8200);
@@ -376,7 +376,7 @@ static int dib3000mc_init(struct dvb_frontend *demod)
        // P_search_maxtrial=1
        dib3000mc_write_word(state, 5, 1);
 
-       dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
+       dib3000mc_set_bandwidth(state, 8000);
 
        // div_lock_mask
        dib3000mc_write_word(state,  4, 0x814);
@@ -397,7 +397,7 @@ static int dib3000mc_init(struct dvb_frontend *demod)
        dib3000mc_write_word(state, 180, 0x2FF0);
 
        // Impulse noise configuration
-       dib3000mc_set_impulse_noise(state, 0, 1);
+       dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
 
        // output mode set-up
        dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
@@ -423,13 +423,13 @@ static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
 {
        u16 cfg[4] = { 0 },reg;
        switch (qam) {
-               case 0:
+               case QPSK:
                        cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
                        break;
-               case 1:
+               case QAM_16:
                        cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
                        break;
-               case 2:
+               case QAM_64:
                        cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
                        break;
        }
@@ -437,11 +437,11 @@ static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
                dib3000mc_write_word(state, reg, cfg[reg - 129]);
 }
 
-static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq)
+static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_frontend_parameters *ch, u16 seq)
 {
-       u16 tmp;
-
-       dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0);
+       u16 value;
+    dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
+       dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 0);
 
 //     if (boost)
 //             dib3000mc_write_word(state, 100, (11 << 6) + 6);
@@ -455,7 +455,7 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx
        dib3000mc_write_word(state, 26,  0x6680);
        dib3000mc_write_word(state, 29,  0x1273);
        dib3000mc_write_word(state, 33,       5);
-       dib3000mc_set_adp_cfg(state, 1);
+       dib3000mc_set_adp_cfg(state, QAM_16);
        dib3000mc_write_word(state, 133,  15564);
 
        dib3000mc_write_word(state, 12 , 0x0);
@@ -470,52 +470,98 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx
        dib3000mc_write_word(state, 97,0);
        dib3000mc_write_word(state, 98,0);
 
-       dib3000mc_set_impulse_noise(state, 0, chan->nfft);
-
-       tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha;
-       dib3000mc_write_word(state, 0, tmp);
+       dib3000mc_set_impulse_noise(state, 0, ch->u.ofdm.transmission_mode);
 
+       value = 0;
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
+               default:
+               case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
+       }
+       switch (ch->u.ofdm.guard_interval) {
+               case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
+               case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
+               case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
+               default:
+               case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
+       }
+       switch (ch->u.ofdm.constellation) {
+               case QPSK:  value |= (0 << 3); break;
+               case QAM_16: value |= (1 << 3); break;
+               default:
+               case QAM_64: value |= (2 << 3); break;
+       }
+       switch (HIERARCHY_1) {
+               case HIERARCHY_2: value |= 2; break;
+               case HIERARCHY_4: value |= 4; break;
+               default:
+               case HIERARCHY_1: value |= 1; break;
+       }
+       dib3000mc_write_word(state, 0, value);
        dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
 
-       tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp);
-       if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp))
-               tmp |= chan->vit_code_rate_hp << 1;
-       else
-               tmp |= chan->vit_code_rate_lp << 1;
-       dib3000mc_write_word(state, 181, tmp);
+       value = 0;
+       if (ch->u.ofdm.hierarchy_information == 1)
+               value |= (1 << 4);
+       if (1 == 1)
+               value |= 1;
+       switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
+               case FEC_2_3: value |= (2 << 1); break;
+               case FEC_3_4: value |= (3 << 1); break;
+               case FEC_5_6: value |= (5 << 1); break;
+               case FEC_7_8: value |= (7 << 1); break;
+               default:
+               case FEC_1_2: value |= (1 << 1); break;
+       }
+       dib3000mc_write_word(state, 181, value);
 
-       // diversity synchro delay
-       tmp = dib3000mc_read_word(state, 180) & 0x000f;
-       tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin
-       dib3000mc_write_word(state, 180, tmp);
+       // diversity synchro delay add 50% SFN margin
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_8K: value = 256; break;
+               case TRANSMISSION_MODE_2K:
+               default: value = 64; break;
+       }
+       switch (ch->u.ofdm.guard_interval) {
+               case GUARD_INTERVAL_1_16: value *= 2; break;
+               case GUARD_INTERVAL_1_8:  value *= 4; break;
+               case GUARD_INTERVAL_1_4:  value *= 8; break;
+               default:
+               case GUARD_INTERVAL_1_32: value *= 1; break;
+       }
+       value <<= 4;
+       value |= dib3000mc_read_word(state, 180) & 0x000f;
+       dib3000mc_write_word(state, 180, value);
 
        // restart demod
-       tmp = dib3000mc_read_word(state, 0);
-       dib3000mc_write_word(state, 0, tmp | (1 << 9));
-       dib3000mc_write_word(state, 0, tmp);
+       value = dib3000mc_read_word(state, 0);
+       dib3000mc_write_word(state, 0, value | (1 << 9));
+       dib3000mc_write_word(state, 0, value);
 
        msleep(30);
 
-       dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft);
+       dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->u.ofdm.transmission_mode);
 }
 
-static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan)
+static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *chan)
 {
        struct dib3000mc_state *state = demod->demodulator_priv;
        u16 reg;
 //     u32 val;
-       struct dibx000_ofdm_channel fchan;
+       struct dvb_frontend_parameters schan;
 
-       INIT_OFDM_CHANNEL(&fchan);
-       fchan = *chan;
+       schan = *chan;
 
+       /* TODO what is that ? */
 
        /* a channel for autosearch */
-       fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2;
-       fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2;
-       fchan.vit_hrch = 0; fchan.vit_select_hp = 1;
+       schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
+       schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
+       schan.u.ofdm.constellation = QAM_64;
+       schan.u.ofdm.code_rate_HP = FEC_2_3;
+       schan.u.ofdm.code_rate_LP = FEC_2_3;
+       schan.u.ofdm.hierarchy_information = 0;
 
-       dib3000mc_set_channel_cfg(state, &fchan, 11);
+       dib3000mc_set_channel_cfg(state, &schan, 11);
 
        reg = dib3000mc_read_word(state, 0);
        dib3000mc_write_word(state, 0, reg | (1 << 8));
@@ -539,7 +585,7 @@ static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
        return 0; // still pending
 }
 
-static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
+static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
 {
        struct dib3000mc_state *state = demod->demodulator_priv;
 
@@ -547,11 +593,17 @@ static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channe
        dib3000mc_set_channel_cfg(state, ch, 0);
 
        // activates isi
-       dib3000mc_write_word(state, 29, 0x1073);
-
-       dib3000mc_set_adp_cfg(state, (u8)ch->nqam);
+       if (state->sfn_workaround_active) {
+               dprintk("SFN workaround is active\n");
+               dib3000mc_write_word(state, 29, 0x1273);
+               dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
+       } else {
+               dib3000mc_write_word(state, 29, 0x1073);
+               dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
+       }
 
-       if (ch->nfft == 1) {
+       dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation);
+       if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) {
                dib3000mc_write_word(state, 26, 38528);
                dib3000mc_write_word(state, 33, 8);
        } else {
@@ -560,7 +612,7 @@ static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channe
        }
 
        if (dib3000mc_read_word(state, 509) & 0x80)
-               dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
+               dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 1);
 
        return 0;
 }
@@ -632,13 +684,12 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
                                struct dvb_frontend_parameters *fep)
 {
        struct dib3000mc_state *state = fe->demodulator_priv;
-       struct dibx000_ofdm_channel ch;
-
-       INIT_OFDM_CHANNEL(&ch);
-       FEP2DIB(fep,&ch);
 
        state->current_bandwidth = fep->u.ofdm.bandwidth;
-       dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth);
+       dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
+
+       /* maybe the parameter has been changed */
+       state->sfn_workaround_active = buggy_sfn_workaround;
 
        if (fe->ops.tuner_ops.set_params) {
                fe->ops.tuner_ops.set_params(fe, fep);
@@ -651,7 +702,7 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
                fep->u.ofdm.code_rate_HP      == FEC_AUTO) {
                int i = 100, found;
 
-               dib3000mc_autosearch_start(fe, &ch);
+               dib3000mc_autosearch_start(fe, fep);
                do {
                        msleep(1);
                        found = dib3000mc_autosearch_is_irq(fe);
@@ -662,13 +713,12 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
                        return 0; // no channel found
 
                dib3000mc_get_frontend(fe, fep);
-               FEP2DIB(fep,&ch);
        }
 
        /* make this a config parameter */
        dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
 
-       return dib3000mc_tune(fe, &ch);
+       return dib3000mc_tune(fe, fep);
 }
 
 static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
index f64546c6aeb5b63af45dffb0b6dd6efc462f602c..fb18441a8c57493eb05e99bdd673c8a74df4a8de 100644 (file)
@@ -2,7 +2,7 @@
  * Linux-DVB Driver for DiBcom's DiB7000M and
  *              first generation DiB7000P-demodulator-family.
  *
- * Copyright (C) 2005-6 DiBcom (http://www.dibcom.fr/)
+ * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
  *
  * This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
@@ -19,7 +19,7 @@ static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
 
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000M:"); printk(args); } } while (0)
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000M: "); printk(args); printk("\n"); } } while (0)
 
 struct dib7000m_state {
        struct dvb_frontend demod;
@@ -39,8 +39,16 @@ struct dib7000m_state {
        fe_bandwidth_t current_bandwidth;
        struct dibx000_agc_config *current_agc;
        u32 timf;
+       u32 timf_default;
+       u32 internal_clk;
+
+       u8 div_force_off : 1;
+       u8 div_state : 1;
+       u16 div_sync_wait;
 
        u16 revision;
+
+       u8 agc_state;
 };
 
 enum dib7000m_power_mode {
@@ -63,7 +71,7 @@ static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
        };
 
        if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
-               dprintk("i2c read error on %d\n",reg);
+               dprintk("i2c read error on %d",reg);
 
        return (rb[0] << 8) | rb[1];
 }
@@ -79,6 +87,25 @@ static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
        };
        return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 }
+static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
+{
+       u16 l = 0, r, *n;
+       n = buf;
+       l = *n++;
+       while (l) {
+               r = *n++;
+
+               if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC
+                       r++;
+
+               do {
+                       dib7000m_write_word(state, r, *n++);
+                       r++;
+               } while (--l);
+               l = *n++;
+       }
+}
+
 static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
 {
        int    ret = 0;
@@ -89,8 +116,7 @@ static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
        fifo_threshold = 1792;
        smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1);
 
-       dprintk("-I-  Setting output mode for demod %p to %d\n",
-                       &state->demod, mode);
+       dprintk( "setting output mode for demod %p to %d", &state->demod, mode);
 
        switch (mode) {
                case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
@@ -117,7 +143,7 @@ static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
                        outreg = 0;
                        break;
                default:
-                       dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
+                       dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
                        break;
        }
 
@@ -129,13 +155,20 @@ static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
        ret |= dib7000m_write_word(state, 1795, outreg);
        ret |= dib7000m_write_word(state, 1805, sram);
 
+       if (state->revision == 0x4003) {
+               u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd;
+               if (mode == OUTMODE_DIVERSITY)
+                       clk_cfg1 |= (1 << 1); // P_O_CLK_en
+               dib7000m_write_word(state, 909, clk_cfg1);
+       }
        return ret;
 }
 
-static int dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
+static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
 {
        /* by default everything is going to be powered off */
        u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906  = 0x3fff;
+       u8  offset = 0;
 
        /* now, depending on the requested mode, we power on */
        switch (mode) {
@@ -170,16 +203,17 @@ static int dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_p
        if (!state->cfg.mobile_mode)
                reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
 
-       /* P_sdio_select_clk = 0 on MC */
+       /* P_sdio_select_clk = 0 on MC and after*/
        if (state->revision != 0x4000)
                reg_906 <<= 1;
 
-       dib7000m_write_word(state,  903,  reg_903);
-       dib7000m_write_word(state,  904,  reg_904);
-       dib7000m_write_word(state,  905,  reg_905);
-       dib7000m_write_word(state,  906,  reg_906);
+       if (state->revision == 0x4003)
+               offset = 1;
 
-       return 0;
+       dib7000m_write_word(state, 903 + offset, reg_903);
+       dib7000m_write_word(state, 904 + offset, reg_904);
+       dib7000m_write_word(state, 905 + offset, reg_905);
+       dib7000m_write_word(state, 906 + offset, reg_906);
 }
 
 static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no)
@@ -230,34 +264,55 @@ static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc
                        break;
        }
 
-//     dprintk("-D-  913: %x, 914: %x\n", reg_913, reg_914);
-
+//     dprintk( "913: %x, 914: %x", reg_913, reg_914);
        ret |= dib7000m_write_word(state, 913, reg_913);
        ret |= dib7000m_write_word(state, 914, reg_914);
 
        return ret;
 }
 
-static int dib7000m_set_bandwidth(struct dvb_frontend *demod, u8 bw_idx)
+static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw)
 {
-       struct dib7000m_state *state = demod->demodulator_priv;
        u32 timf;
 
        // store the current bandwidth for later use
-       state->current_bandwidth = bw_idx;
+       state->current_bandwidth = bw;
 
        if (state->timf == 0) {
-               dprintk("-D-  Using default timf\n");
-               timf = state->cfg.bw->timf;
+               dprintk( "using default timf");
+               timf = state->timf_default;
        } else {
-               dprintk("-D-  Using updated timf\n");
+               dprintk( "using updated timf");
                timf = state->timf;
        }
 
-       timf = timf * (BW_INDEX_TO_KHZ(bw_idx) / 100) / 80;
+       timf = timf * (bw / 50) / 160;
 
-       dib7000m_write_word(state, 23, (timf >> 16) & 0xffff);
-       dib7000m_write_word(state, 24, (timf      ) & 0xffff);
+       dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
+       dib7000m_write_word(state, 24, (u16) ((timf      ) & 0xffff));
+
+       return 0;
+}
+
+static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff)
+{
+       struct dib7000m_state *state = demod->demodulator_priv;
+
+       if (state->div_force_off) {
+               dprintk( "diversity combination deactivated - forced by COFDM parameters");
+               onoff = 0;
+       }
+       state->div_state = (u8)onoff;
+
+       if (onoff) {
+               dib7000m_write_word(state, 263 + state->reg_offs, 6);
+               dib7000m_write_word(state, 264 + state->reg_offs, 6);
+               dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
+       } else {
+               dib7000m_write_word(state, 263 + state->reg_offs, 1);
+               dib7000m_write_word(state, 264 + state->reg_offs, 0);
+               dib7000m_write_word(state, 266 + state->reg_offs, 0);
+       }
 
        return 0;
 }
@@ -266,7 +321,7 @@ static int dib7000m_sad_calib(struct dib7000m_state *state)
 {
 
 /* internal */
-//     dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is written in set_bandwidth
+//     dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
        dib7000m_write_word(state, 929, (0 << 1) | (0 << 0));
        dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096
 
@@ -281,10 +336,10 @@ static int dib7000m_sad_calib(struct dib7000m_state *state)
 
 static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw)
 {
-       dib7000m_write_word(state, 18, ((bw->internal*1000) >> 16) & 0xffff);
-       dib7000m_write_word(state, 19,  (bw->internal*1000)        & 0xffff);
-       dib7000m_write_word(state, 21,  (bw->ifreq          >> 16) & 0xffff);
-       dib7000m_write_word(state, 22,   bw->ifreq                 & 0xffff);
+       dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
+       dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000)        & 0xffff));
+       dib7000m_write_word(state, 21, (u16) ( (bw->ifreq          >> 16) & 0xffff));
+       dib7000m_write_word(state, 22, (u16) (  bw->ifreq                 & 0xffff));
 
        dib7000m_write_word(state, 928, bw->sad_cfg);
 }
@@ -325,15 +380,19 @@ static void dib7000m_reset_pll(struct dib7000m_state *state)
 static void dib7000mc_reset_pll(struct dib7000m_state *state)
 {
        const struct dibx000_bandwidth_config *bw = state->cfg.bw;
+       u16 clk_cfg1;
 
        // clk_cfg0
        dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0));
 
        // clk_cfg1
        //dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) |
-       dib7000m_write_word(state, 908, (0 << 14) | (3 << 12) |(0 << 11) |
+       clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) |
                        (bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) |
-                       (bw->pll_bypass << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0));
+                       (1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0);
+       dib7000m_write_word(state, 908, clk_cfg1);
+       clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3);
+       dib7000m_write_word(state, 908, clk_cfg1);
 
        // smpl_cfg
        dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7));
@@ -344,9 +403,6 @@ static void dib7000mc_reset_pll(struct dib7000m_state *state)
 static int dib7000m_reset_gpio(struct dib7000m_state *st)
 {
        /* reset the GPIOs */
-       dprintk("-D-  gpio dir: %x: gpio val: %x, gpio pwm pos: %x\n",
-               st->cfg.gpio_dir, st->cfg.gpio_val,st->cfg.gpio_pwm_pos);
-
        dib7000m_write_word(st, 773, st->cfg.gpio_dir);
        dib7000m_write_word(st, 774, st->cfg.gpio_val);
 
@@ -358,6 +414,107 @@ static int dib7000m_reset_gpio(struct dib7000m_state *st)
        return 0;
 }
 
+static u16 dib7000m_defaults_common[] =
+
+{
+       // auto search configuration
+       3, 2,
+               0x0004,
+               0x1000,
+               0x0814,
+
+       12, 6,
+               0x001b,
+               0x7740,
+               0x005b,
+               0x8d80,
+               0x01c9,
+               0xc380,
+               0x0000,
+               0x0080,
+               0x0000,
+               0x0090,
+               0x0001,
+               0xd4c0,
+
+       1, 26,
+               0x6680, // P_corm_thres Lock algorithms configuration
+
+       1, 170,
+               0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
+
+       8, 173,
+               0,
+               0,
+               0,
+               0,
+               0,
+               0,
+               0,
+               0,
+
+       1, 182,
+               8192, // P_fft_nb_to_cut
+
+       2, 195,
+               0x0ccd, // P_pha3_thres
+               0,      // P_cti_use_cpe, P_cti_use_prog
+
+       1, 205,
+               0x200f, // P_cspu_regul, P_cspu_win_cut
+
+       5, 214,
+               0x023d, // P_adp_regul_cnt
+               0x00a4, // P_adp_noise_cnt
+               0x00a4, // P_adp_regul_ext
+               0x7ff0, // P_adp_noise_ext
+               0x3ccc, // P_adp_fil
+
+       1, 226,
+               0, // P_2d_byp_ti_num
+
+       1, 255,
+               0x800, // P_equal_thres_wgn
+
+       1, 263,
+               0x0001,
+
+       1, 281,
+               0x0010, // P_fec_*
+
+       1, 294,
+               0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
+
+       0
+};
+
+static u16 dib7000m_defaults[] =
+
+{
+       /* set ADC level to -16 */
+       11, 76,
+               (1 << 13) - 825 - 117,
+               (1 << 13) - 837 - 117,
+               (1 << 13) - 811 - 117,
+               (1 << 13) - 766 - 117,
+               (1 << 13) - 737 - 117,
+               (1 << 13) - 693 - 117,
+               (1 << 13) - 648 - 117,
+               (1 << 13) - 619 - 117,
+               (1 << 13) - 575 - 117,
+               (1 << 13) - 531 - 117,
+               (1 << 13) - 501 - 117,
+
+       // Tuner IO bank: max drive (14mA)
+       1, 912,
+               0x2c8a,
+
+       1, 1817,
+               1,
+
+       0,
+};
+
 static int dib7000m_demod_reset(struct dib7000m_state *state)
 {
        dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
@@ -382,22 +539,47 @@ static int dib7000m_demod_reset(struct dib7000m_state *state)
                dib7000mc_reset_pll(state);
 
        if (dib7000m_reset_gpio(state) != 0)
-               dprintk("-E-  GPIO reset was not successful.\n");
+               dprintk( "GPIO reset was not successful.");
 
        if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
-               dprintk("-E-  OUTPUT_MODE could not be resetted.\n");
+               dprintk( "OUTPUT_MODE could not be reset.");
 
        /* unforce divstr regardless whether i2c enumeration was done or not */
        dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) );
 
-       dib7000m_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
+       dib7000m_set_bandwidth(state, 8000);
 
        dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON);
        dib7000m_sad_calib(state);
        dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
 
+       if (state->cfg.dvbt_mode)
+               dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
+
+       if (state->cfg.mobile_mode)
+               dib7000m_write_word(state, 261 + state->reg_offs, 2);
+       else
+               dib7000m_write_word(state, 224 + state->reg_offs, 1);
+
+       // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
+       if(state->cfg.tuner_is_baseband)
+               dib7000m_write_word(state, 36, 0x0755);
+       else
+               dib7000m_write_word(state, 36, 0x1f55);
+
+       // P_divclksel=3 P_divbitsel=1
+       if (state->revision == 0x4000)
+               dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
+       else
+               dib7000m_write_word(state, 909, (3 << 4) | 1);
+
+       dib7000m_write_tab(state, dib7000m_defaults_common);
+       dib7000m_write_tab(state, dib7000m_defaults);
+
        dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY);
 
+       state->internal_clk = state->cfg.bw->internal;
+
        return 0;
 }
 
@@ -427,7 +609,7 @@ static int dib7000m_agc_soft_split(struct dib7000m_state *state)
                        (agc - state->current_agc->split.min_thres) /
                        (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
 
-       dprintk("AGC split_offset: %d\n",split_offset);
+       dprintk( "AGC split_offset: %d",split_offset);
 
        // P_agc_force_split and P_agc_split_offset
        return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset);
@@ -435,35 +617,26 @@ static int dib7000m_agc_soft_split(struct dib7000m_state *state)
 
 static int dib7000m_update_lna(struct dib7000m_state *state)
 {
-       int i;
        u16 dyn_gain;
 
-       // when there is no LNA to program return immediatly
-       if (state->cfg.update_lna == NULL)
-               return 0;
-
-       msleep(60);
-       for (i = 0; i < 20; i++) {
-               // read dyn_gain here (because it is demod-dependent and not tuner)
+       if (state->cfg.update_lna) {
+               // read dyn_gain here (because it is demod-dependent and not fe)
                dyn_gain = dib7000m_read_word(state, 390);
 
-               dprintk("agc global: %d\n", dyn_gain);
-
                if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
                        dib7000m_restart_agc(state);
-                       msleep(60);
-               } else
-                       break;
+                       return 1;
+               }
        }
        return 0;
 }
 
-static void dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
+static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
 {
        struct dibx000_agc_config *agc = NULL;
        int i;
-       if (state->current_band == band)
-               return;
+       if (state->current_band == band && state->current_agc != NULL)
+               return 0;
        state->current_band = band;
 
        for (i = 0; i < state->cfg.agc_config_count; i++)
@@ -473,8 +646,8 @@ static void dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
                }
 
        if (agc == NULL) {
-               dprintk("-E-  No valid AGC configuration found for band 0x%02x\n",band);
-               return;
+               dprintk( "no valid AGC configuration found for band 0x%02x",band);
+               return -EINVAL;
        }
 
        state->current_agc = agc;
@@ -489,7 +662,7 @@ static void dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
        dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp);
        dib7000m_write_word(state, 99, (agc->beta_mant  << 6) | agc->beta_exp);
 
-       dprintk("-D-  WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
+       dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
                state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
 
        /* AGC continued */
@@ -510,7 +683,7 @@ static void dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
 
        if (state->revision > 0x4000) { // settings for the MC
                dib7000m_write_word(state, 71,   agc->agc1_pt3);
-//             dprintk("-D-  929: %x %d %d\n",
+//             dprintk( "929: %x %d %d",
 //                     (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel);
                dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
        } else {
@@ -519,33 +692,160 @@ static void dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
                for (i = 0; i < 9; i++)
                        dib7000m_write_word(state, 88 + i, b[i]);
        }
+       return 0;
 }
 
-static void dib7000m_update_timf_freq(struct dib7000m_state *state)
+static void dib7000m_update_timf(struct dib7000m_state *state)
 {
        u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437);
-       state->timf = timf * 80 / (BW_INDEX_TO_KHZ(state->current_bandwidth) / 100);
+       state->timf = timf * 160 / (state->current_bandwidth / 50);
        dib7000m_write_word(state, 23, (u16) (timf >> 16));
        dib7000m_write_word(state, 24, (u16) (timf & 0xffff));
-       dprintk("-D-  Updated timf_frequency: %d (default: %d)\n",state->timf, state->cfg.bw->timf);
+       dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->timf_default);
+}
+
+static int dib7000m_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
+{
+       struct dib7000m_state *state = demod->demodulator_priv;
+       u16 cfg_72 = dib7000m_read_word(state, 72);
+       int ret = -1;
+       u8 *agc_state = &state->agc_state;
+       u8 agc_split;
+
+       switch (state->agc_state) {
+               case 0:
+                       // set power-up level: interf+analog+AGC
+                       dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
+                       dib7000m_set_adc_state(state, DIBX000_ADC_ON);
+
+                       if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
+                               return -1;
+
+                       ret = 7; /* ADC power up */
+                       (*agc_state)++;
+                       break;
+
+               case 1:
+                       /* AGC initialization */
+                       if (state->cfg.agc_control)
+                               state->cfg.agc_control(&state->demod, 1);
+
+                       dib7000m_write_word(state, 75, 32768);
+                       if (!state->current_agc->perform_agc_softsplit) {
+                               /* we are using the wbd - so slow AGC startup */
+                               dib7000m_write_word(state, 103, 1 << 8); /* force 0 split on WBD and restart AGC */
+                               (*agc_state)++;
+                               ret = 5;
+                       } else {
+                               /* default AGC startup */
+                               (*agc_state) = 4;
+                               /* wait AGC rough lock time */
+                               ret = 7;
+                       }
+
+                       dib7000m_restart_agc(state);
+                       break;
+
+               case 2: /* fast split search path after 5sec */
+                       dib7000m_write_word(state,  72, cfg_72 | (1 << 4)); /* freeze AGC loop */
+                       dib7000m_write_word(state, 103, 2 << 9);            /* fast split search 0.25kHz */
+                       (*agc_state)++;
+                       ret = 14;
+                       break;
+
+       case 3: /* split search ended */
+                       agc_split = (u8)dib7000m_read_word(state, 392); /* store the split value for the next time */
+                       dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */
+
+                       dib7000m_write_word(state, 72,  cfg_72 & ~(1 << 4));   /* std AGC loop */
+                       dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
+
+                       dib7000m_restart_agc(state);
+
+                       dprintk( "SPLIT %p: %hd", demod, agc_split);
+
+                       (*agc_state)++;
+                       ret = 5;
+                       break;
+
+               case 4: /* LNA startup */
+                       /* wait AGC accurate lock time */
+                       ret = 7;
+
+                       if (dib7000m_update_lna(state))
+                               // wait only AGC rough lock time
+                               ret = 5;
+                       else
+                               (*agc_state)++;
+                       break;
+
+               case 5:
+                       dib7000m_agc_soft_split(state);
+
+                       if (state->cfg.agc_control)
+                               state->cfg.agc_control(&state->demod, 0);
+
+                       (*agc_state)++;
+                       break;
+
+               default:
+                       break;
+       }
+       return ret;
 }
 
-static void dib7000m_set_channel(struct dib7000m_state *state, struct dibx000_ofdm_channel *ch, u8 seq)
+static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_frontend_parameters *ch, u8 seq)
 {
        u16 value, est[4];
 
-       dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->RF_kHz));
+       dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
 
        /* nfft, guard, qam, alpha */
-       dib7000m_write_word(state, 0, (ch->nfft << 7) | (ch->guard << 5) | (ch->nqam << 3) | (ch->vit_alpha));
+       value = 0;
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
+               case /* 4K MODE */ 255: value |= (2 << 7); break;
+               default:
+               case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
+       }
+       switch (ch->u.ofdm.guard_interval) {
+               case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
+               case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
+               case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
+               default:
+               case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
+       }
+       switch (ch->u.ofdm.constellation) {
+               case QPSK:  value |= (0 << 3); break;
+               case QAM_16: value |= (1 << 3); break;
+               default:
+               case QAM_64: value |= (2 << 3); break;
+       }
+       switch (HIERARCHY_1) {
+               case HIERARCHY_2: value |= 2; break;
+               case HIERARCHY_4: value |= 4; break;
+               default:
+               case HIERARCHY_1: value |= 1; break;
+       }
+       dib7000m_write_word(state, 0, value);
        dib7000m_write_word(state, 5, (seq << 4));
 
-       /* P_dintl_native, P_dintlv_inv, P_vit_hrch, P_vit_code_rate, P_vit_select_hp */
-       value = (ch->intlv_native << 6) | (ch->vit_hrch << 4) | (ch->vit_select_hp & 0x1);
-       if (ch->vit_hrch == 0 || ch->vit_select_hp == 1)
-               value |= (ch->vit_code_rate_hp << 1);
-       else
-               value |= (ch->vit_code_rate_lp << 1);
+       /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
+       value = 0;
+       if (1 != 0)
+               value |= (1 << 6);
+       if (ch->u.ofdm.hierarchy_information == 1)
+               value |= (1 << 4);
+       if (1 == 1)
+               value |= 1;
+       switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
+               case FEC_2_3: value |= (2 << 1); break;
+               case FEC_3_4: value |= (3 << 1); break;
+               case FEC_5_6: value |= (5 << 1); break;
+               case FEC_7_8: value |= (7 << 1); break;
+               default:
+               case FEC_1_2: value |= (1 << 1); break;
+       }
        dib7000m_write_word(state, 267 + state->reg_offs, value);
 
        /* offset loop parameters */
@@ -563,32 +863,38 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dibx000_of
        dib7000m_write_word(state, 33, (0 << 4) | 0x5);
 
        /* P_dvsy_sync_wait */
-       switch (ch->nfft) {
-               case 1: value = 256; break;
-               case 2: value = 128; break;
-               case 0:
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_8K: value = 256; break;
+               case /* 4K MODE */ 255: value = 128; break;
+               case TRANSMISSION_MODE_2K:
                default: value = 64; break;
        }
-       value *= ((1 << (ch->guard)) * 3 / 2); // add 50% SFN margin
-       value <<= 4;
+       switch (ch->u.ofdm.guard_interval) {
+               case GUARD_INTERVAL_1_16: value *= 2; break;
+               case GUARD_INTERVAL_1_8:  value *= 4; break;
+               case GUARD_INTERVAL_1_4:  value *= 8; break;
+               default:
+               case GUARD_INTERVAL_1_32: value *= 1; break;
+       }
+       state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
 
        /* deactive the possibility of diversity reception if extended interleave - not for 7000MC */
        /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
-       if (ch->intlv_native || state->revision > 0x4000)
-               value |= (1 << 2) | (2 << 0);
+       if (1 == 1 || state->revision > 0x4000)
+               state->div_force_off = 0;
        else
-               value |= 0;
-       dib7000m_write_word(state, 266 + state->reg_offs, value);
+               state->div_force_off = 1;
+       dib7000m_set_diversity_in(&state->demod, state->div_state);
 
        /* channel estimation fine configuration */
-       switch (ch->nqam) {
-               case 2:
+       switch (ch->u.ofdm.constellation) {
+               case QAM_64:
                        est[0] = 0x0148;       /* P_adp_regul_cnt 0.04 */
                        est[1] = 0xfff0;       /* P_adp_noise_cnt -0.002 */
                        est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
                        est[3] = 0xfff8;       /* P_adp_noise_ext -0.001 */
                        break;
-               case 1:
+               case QAM_16:
                        est[0] = 0x023d;       /* P_adp_regul_cnt 0.07 */
                        est[1] = 0xffdf;       /* P_adp_noise_cnt -0.004 */
                        est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
@@ -604,70 +910,48 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dibx000_of
        for (value = 0; value < 4; value++)
                dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]);
 
-       // set power-up level: interf+analog+AGC
-       dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
-       dib7000m_set_adc_state(state, DIBX000_ADC_ON);
-
-       msleep(7);
-
-       //AGC initialization
-       if (state->cfg.agc_control)
-               state->cfg.agc_control(&state->demod, 1);
-
-       dib7000m_restart_agc(state);
-
-       // wait AGC rough lock time
-       msleep(5);
-
-       dib7000m_update_lna(state);
-       dib7000m_agc_soft_split(state);
-
-       // wait AGC accurate lock time
-       msleep(7);
-
-       if (state->cfg.agc_control)
-               state->cfg.agc_control(&state->demod, 0);
-
        // set power-up level: autosearch
        dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD);
 }
 
-static int dib7000m_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
+static int dib7000m_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
 {
        struct dib7000m_state *state = demod->demodulator_priv;
-       struct dibx000_ofdm_channel auto_ch;
+       struct dvb_frontend_parameters schan;
        int ret = 0;
-       u32 value;
-
-       INIT_OFDM_CHANNEL(&auto_ch);
-       auto_ch.RF_kHz           = ch->RF_kHz;
-       auto_ch.Bw               = ch->Bw;
-       auto_ch.nqam             = 2;
-       auto_ch.guard            = 0;
-       auto_ch.nfft             = 1;
-       auto_ch.vit_alpha        = 1;
-       auto_ch.vit_select_hp    = 1;
-       auto_ch.vit_code_rate_hp = 2;
-       auto_ch.vit_code_rate_lp = 3;
-       auto_ch.vit_hrch         = 0;
-       auto_ch.intlv_native     = 1;
-
-       dib7000m_set_channel(state, &auto_ch, 7);
+       u32 value, factor;
+
+       schan = *ch;
+
+       schan.u.ofdm.constellation = QAM_64;
+       schan.u.ofdm.guard_interval        = GUARD_INTERVAL_1_32;
+       schan.u.ofdm.transmission_mode         = TRANSMISSION_MODE_8K;
+       schan.u.ofdm.code_rate_HP = FEC_2_3;
+       schan.u.ofdm.code_rate_LP = FEC_3_4;
+       schan.u.ofdm.hierarchy_information         = 0;
+
+       dib7000m_set_channel(state, &schan, 7);
+
+       factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
+       if (factor >= 5000)
+               factor = 1;
+       else
+               factor = 6;
 
        // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
-       value = 30 * state->cfg.bw->internal;
+       value = 30 * state->internal_clk * factor;
        ret |= dib7000m_write_word(state, 6,  (u16) ((value >> 16) & 0xffff)); // lock0 wait time
        ret |= dib7000m_write_word(state, 7,  (u16)  (value        & 0xffff)); // lock0 wait time
-       value = 100 * state->cfg.bw->internal;
+       value = 100 * state->internal_clk * factor;
        ret |= dib7000m_write_word(state, 8,  (u16) ((value >> 16) & 0xffff)); // lock1 wait time
        ret |= dib7000m_write_word(state, 9,  (u16)  (value        & 0xffff)); // lock1 wait time
-       value = 500 * state->cfg.bw->internal;
+       value = 500 * state->internal_clk * factor;
        ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
        ret |= dib7000m_write_word(state, 11, (u16)  (value        & 0xffff)); // lock2 wait time
 
        // start search
        value = dib7000m_read_word(state, 0);
-       ret |= dib7000m_write_word(state, 0, value | (1 << 9));
+       ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9)));
 
        /* clear n_irq_pending */
        if (state->revision == 0x4000)
@@ -685,12 +969,12 @@ static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg)
        u16 irq_pending = dib7000m_read_word(state, reg);
 
        if (irq_pending & 0x1) { // failed
-               dprintk("#\n");
+               dprintk( "autosearch failed");
                return 1;
        }
 
        if (irq_pending & 0x2) { // succeeded
-               dprintk("!\n");
+               dprintk( "autosearch succeeded");
                return 2;
        }
        return 0; // still pending
@@ -705,7 +989,7 @@ static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod)
                return dib7000m_autosearch_irq(state, 537);
 }
 
-static int dib7000m_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
+static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
 {
        struct dib7000m_state *state = demod->demodulator_priv;
        int ret = 0;
@@ -722,182 +1006,103 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel
        ret |= dib7000m_write_word(state, 898, 0x0000);
        msleep(45);
 
-       ret |= dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
+       dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
        /* 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 */
        ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
 
-       // never achieved a lock with that bandwidth so far - wait for timfreq to update
+       // never achieved a lock before - wait for timfreq to update
        if (state->timf == 0)
                msleep(200);
 
        //dump_reg(state);
        /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
        value = (6 << 8) | 0x80;
-       switch (ch->nfft) {
-               case 0: value |= (7 << 12); break;
-               case 1: value |= (9 << 12); break;
-               case 2: value |= (8 << 12); break;
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
+               case /* 4K MODE */ 255: value |= (8 << 12); break;
+               default:
+               case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
        }
        ret |= dib7000m_write_word(state, 26, value);
 
        /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
        value = (0 << 4);
-       switch (ch->nfft) {
-               case 0: value |= 0x6; break;
-               case 1: value |= 0x8; break;
-               case 2: value |= 0x7; break;
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_2K: value |= 0x6; break;
+               case /* 4K MODE */ 255: value |= 0x7; break;
+               default:
+               case TRANSMISSION_MODE_8K: value |= 0x8; break;
        }
        ret |= dib7000m_write_word(state, 32, value);
 
        /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
        value = (0 << 4);
-       switch (ch->nfft) {
-               case 0: value |= 0x6; break;
-               case 1: value |= 0x8; break;
-               case 2: value |= 0x7; break;
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_2K: value |= 0x6; break;
+               case /* 4K MODE */ 255: value |= 0x7; break;
+               default:
+               case TRANSMISSION_MODE_8K: value |= 0x8; break;
        }
        ret |= dib7000m_write_word(state, 33,  value);
 
-       // we achieved a lock - it's time to update the osc freq
+       // we achieved a lock - it's time to update the timf freq
        if ((dib7000m_read_word(state, 535) >> 6)  & 0x1)
-               dib7000m_update_timf_freq(state);
+               dib7000m_update_timf(state);
 
+    dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
        return ret;
 }
 
-static int dib7000m_init(struct dvb_frontend *demod)
+static int dib7000m_wakeup(struct dvb_frontend *demod)
 {
        struct dib7000m_state *state = demod->demodulator_priv;
-       int ret = 0;
-       u8 o = state->reg_offs;
 
        dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
 
        if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
-               dprintk("-E-  could not start Slow ADC\n");
-
-       if (state->cfg.dvbt_mode)
-               dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
-
-       if (state->cfg.mobile_mode)
-               ret |= dib7000m_write_word(state, 261 + o, 2);
-       else
-               ret |= dib7000m_write_word(state, 224 + o, 1);
-
-       ret |= dib7000m_write_word(state, 173 + o, 0);
-       ret |= dib7000m_write_word(state, 174 + o, 0);
-       ret |= dib7000m_write_word(state, 175 + o, 0);
-       ret |= dib7000m_write_word(state, 176 + o, 0);
-       ret |= dib7000m_write_word(state, 177 + o, 0);
-       ret |= dib7000m_write_word(state, 178 + o, 0);
-       ret |= dib7000m_write_word(state, 179 + o, 0);
-       ret |= dib7000m_write_word(state, 180 + o, 0);
-
-       // P_corm_thres Lock algorithms configuration
-       ret |= dib7000m_write_word(state, 26, 0x6680);
-
-       // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
-       ret |= dib7000m_write_word(state, 170 + o, 0x0410);
-       // P_fft_nb_to_cut
-       ret |= dib7000m_write_word(state, 182 + o, 8192);
-       // P_pha3_thres
-       ret |= dib7000m_write_word(state, 195 + o, 0x0ccd);
-       // P_cti_use_cpe, P_cti_use_prog
-       ret |= dib7000m_write_word(state, 196 + o,     0);
-       // P_cspu_regul, P_cspu_win_cut
-       ret |= dib7000m_write_word(state, 205 + o, 0x200f);
-       // P_adp_regul_cnt
-       ret |= dib7000m_write_word(state, 214 + o, 0x023d);
-       // P_adp_noise_cnt
-       ret |= dib7000m_write_word(state, 215 + o, 0x00a4);
-       // P_adp_regul_ext
-       ret |= dib7000m_write_word(state, 216 + o, 0x00a4);
-       // P_adp_noise_ext
-       ret |= dib7000m_write_word(state, 217 + o, 0x7ff0);
-       // P_adp_fil
-       ret |= dib7000m_write_word(state, 218 + o, 0x3ccc);
-
-       // P_2d_byp_ti_num
-       ret |= dib7000m_write_word(state, 226 + o, 0);
-
-       // P_fec_*
-       ret |= dib7000m_write_word(state, 281 + o, 0x0010);
-       // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
-       ret |= dib7000m_write_word(state, 294 + o,0x0062);
-
-       // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
-       if(state->cfg.tuner_is_baseband)
-               ret |= dib7000m_write_word(state, 36, 0x0755);
-       else
-               ret |= dib7000m_write_word(state, 36, 0x1f55);
-
-       // auto search configuration
-       ret |= dib7000m_write_word(state, 2,  0x0004);
-       ret |= dib7000m_write_word(state, 3,  0x1000);
-       ret |= dib7000m_write_word(state, 4,  0x0814);
-       ret |= dib7000m_write_word(state, 6,  0x001b);
-       ret |= dib7000m_write_word(state, 7,  0x7740);
-       ret |= dib7000m_write_word(state, 8,  0x005b);
-       ret |= dib7000m_write_word(state, 9,  0x8d80);
-       ret |= dib7000m_write_word(state, 10, 0x01c9);
-       ret |= dib7000m_write_word(state, 11, 0xc380);
-       ret |= dib7000m_write_word(state, 12, 0x0000);
-       ret |= dib7000m_write_word(state, 13, 0x0080);
-       ret |= dib7000m_write_word(state, 14, 0x0000);
-       ret |= dib7000m_write_word(state, 15, 0x0090);
-       ret |= dib7000m_write_word(state, 16, 0x0001);
-       ret |= dib7000m_write_word(state, 17, 0xd4c0);
-       ret |= dib7000m_write_word(state, 263 + o,0x0001);
-
-       // P_divclksel=3 P_divbitsel=1
-       if (state->revision == 0x4000)
-               dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
-       else
-               dib7000m_write_word(state, 909, (3 << 4) | 1);
-
-       // Tuner IO bank: max drive (14mA)
-       ret |= dib7000m_write_word(state, 912 ,0x2c8a);
+               dprintk( "could not start Slow ADC");
 
-       ret |= dib7000m_write_word(state, 1817, 1);
-
-       return ret;
+       return 0;
 }
 
 static int dib7000m_sleep(struct dvb_frontend *demod)
 {
        struct dib7000m_state *st = demod->demodulator_priv;
        dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
-       return dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY) |
-               dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
+       dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
+       return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
                dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
 }
 
 static int dib7000m_identify(struct dib7000m_state *state)
 {
        u16 value;
+
        if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
-               dprintk("-E-  DiB7000M: wrong Vendor ID (read=0x%x)\n",value);
+               dprintk( "wrong Vendor ID (0x%x)",value);
                return -EREMOTEIO;
        }
 
        state->revision = dib7000m_read_word(state, 897);
        if (state->revision != 0x4000 &&
                state->revision != 0x4001 &&
-               state->revision != 0x4002) {
-               dprintk("-E-  DiB7000M: wrong Device ID (%x)\n",value);
+               state->revision != 0x4002 &&
+               state->revision != 0x4003) {
+               dprintk( "wrong Device ID (0x%x)",value);
                return -EREMOTEIO;
        }
 
        /* protect this driver to be used with 7000PC */
        if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
-               dprintk("-E-  DiB7000M: this driver does not work with DiB7000PC\n");
+               dprintk( "this driver does not work with DiB7000PC");
                return -EREMOTEIO;
        }
 
        switch (state->revision) {
-               case 0x4000: dprintk("-I-  found DiB7000MA/PA/MB/PB\n"); break;
-               case 0x4001: state->reg_offs = 1; dprintk("-I-  found DiB7000HC\n"); break;
-               case 0x4002: state->reg_offs = 1; dprintk("-I-  found DiB7000MC\n"); break;
+               case 0x4000: dprintk( "found DiB7000MA/PA/MB/PB"); break;
+               case 0x4001: state->reg_offs = 1; dprintk( "found DiB7000HC"); break;
+               case 0x4002: state->reg_offs = 1; dprintk( "found DiB7000MC"); break;
+               case 0x4003: state->reg_offs = 1; dprintk( "found DiB9000"); break;
        }
 
        return 0;
@@ -966,41 +1171,45 @@ static int dib7000m_set_frontend(struct dvb_frontend* fe,
                                struct dvb_frontend_parameters *fep)
 {
        struct dib7000m_state *state = fe->demodulator_priv;
-       struct dibx000_ofdm_channel ch;
-
-       INIT_OFDM_CHANNEL(&ch);
-       FEP2DIB(fep,&ch);
+       int time;
 
        state->current_bandwidth = fep->u.ofdm.bandwidth;
-       dib7000m_set_bandwidth(fe, fep->u.ofdm.bandwidth);
+       dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
 
        if (fe->ops.tuner_ops.set_params)
                fe->ops.tuner_ops.set_params(fe, fep);
 
+       /* start up the AGC */
+       state->agc_state = 0;
+       do {
+               time = dib7000m_agc_startup(fe, fep);
+               if (time != -1)
+                       msleep(time);
+       } while (time != -1);
+
        if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
                fep->u.ofdm.guard_interval    == GUARD_INTERVAL_AUTO ||
                fep->u.ofdm.constellation     == QAM_AUTO ||
                fep->u.ofdm.code_rate_HP      == FEC_AUTO) {
                int i = 800, found;
 
-               dib7000m_autosearch_start(fe, &ch);
+               dib7000m_autosearch_start(fe, fep);
                do {
                        msleep(1);
                        found = dib7000m_autosearch_is_irq(fe);
                } while (found == 0 && i--);
 
-               dprintk("autosearch returns: %d\n",found);
+               dprintk("autosearch returns: %d",found);
                if (found == 0 || found == 1)
                        return 0; // no channel found
 
                dib7000m_get_frontend(fe, fep);
-               FEP2DIB(fep, &ch);
        }
 
        /* make this a config parameter */
        dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
 
-       return dib7000m_tune(fe, &ch);
+       return dib7000m_tune(fe, fep);
 }
 
 static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat)
@@ -1087,7 +1296,7 @@ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
                if (dib7000m_identify(&st) != 0) {
                        st.i2c_addr = default_addr;
                        if (dib7000m_identify(&st) != 0) {
-                               dprintk("DiB7000M #%d: not identified\n", k);
+                               dprintk("DiB7000M #%d: not identified", k);
                                return -EIO;
                        }
                }
@@ -1100,7 +1309,7 @@ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
                /* set new i2c address and force divstart */
                dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
 
-               dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);
+               dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
        }
 
        for (k = 0; k < no_of_demods; k++) {
@@ -1135,6 +1344,8 @@ struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
        demod->demodulator_priv = st;
        memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
 
+       st->timf_default = cfg->bw->timf;
+
        if (dib7000m_identify(st) != 0)
                goto error;
 
@@ -1172,7 +1383,7 @@ static struct dvb_frontend_ops dib7000m_ops = {
 
        .release              = dib7000m_release,
 
-       .init                 = dib7000m_init,
+       .init                 = dib7000m_wakeup,
        .sleep                = dib7000m_sleep,
 
        .set_frontend         = dib7000m_set_frontend,
index aece458cfe12eb50441dca12258bd23eb3be64f8..f45bcfc51cf8ba13ead921436b83b50f8b61e74f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
  *
- * Copyright (C) 2005-6 DiBcom (http://www.dibcom.fr/)
+ * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
  *
  * This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
@@ -18,7 +18,11 @@ static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
 
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P:"); printk(args); } } while (0)
+static int buggy_sfn_workaround;
+module_param(buggy_sfn_workaround, int, 0644);
+MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
 
 struct dib7000p_state {
        struct dvb_frontend demod;
@@ -36,12 +40,21 @@ struct dib7000p_state {
        struct dibx000_agc_config *current_agc;
        u32 timf;
 
+       u8 div_force_off : 1;
+       u8 div_state : 1;
+       u16 div_sync_wait;
+
+       u8 agc_state;
+
        u16 gpio_dir;
        u16 gpio_val;
+
+       u8 sfn_workaround_active :1;
 };
 
 enum dib7000p_power_mode {
        DIB7000P_POWER_ALL = 0,
+       DIB7000P_POWER_ANALOG_ADC,
        DIB7000P_POWER_INTERFACE_ONLY,
 };
 
@@ -55,7 +68,7 @@ static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
        };
 
        if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
-               dprintk("i2c read error on %d\n",reg);
+               dprintk("i2c read error on %d",reg);
 
        return (rb[0] << 8) | rb[1];
 }
@@ -71,6 +84,22 @@ static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
        };
        return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 }
+static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf)
+{
+       u16 l = 0, r, *n;
+       n = buf;
+       l = *n++;
+       while (l) {
+               r = *n++;
+
+               do {
+                       dib7000p_write_word(state, r, *n++);
+                       r++;
+               } while (--l);
+               l = *n++;
+       }
+}
+
 static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
 {
        int    ret = 0;
@@ -80,7 +109,7 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
        fifo_threshold = 1792;
        smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1);
 
-       dprintk("-I-  Setting output mode for demod %p to %d\n",
+       dprintk( "setting output mode for demod %p to %d",
                        &state->demod, mode);
 
        switch (mode) {
@@ -104,11 +133,14 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
                        fifo_threshold = 512;
                        outreg = (1 << 10) | (5 << 6);
                        break;
+               case OUTMODE_ANALOG_ADC:
+                       outreg = (1 << 10) | (3 << 6);
+                       break;
                case OUTMODE_HIGH_Z:  // disable
                        outreg = 0;
                        break;
                default:
-                       dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
+                       dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
                        break;
        }
 
@@ -122,6 +154,30 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
        return ret;
 }
 
+static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
+{
+       struct dib7000p_state *state = demod->demodulator_priv;
+
+       if (state->div_force_off) {
+               dprintk( "diversity combination deactivated - forced by COFDM parameters");
+               onoff = 0;
+       }
+       state->div_state = (u8)onoff;
+
+       if (onoff) {
+               dib7000p_write_word(state, 204, 6);
+               dib7000p_write_word(state, 205, 16);
+               /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
+               dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
+       } else {
+               dib7000p_write_word(state, 204, 1);
+               dib7000p_write_word(state, 205, 0);
+               dib7000p_write_word(state, 207, 0);
+       }
+
+       return 0;
+}
+
 static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
 {
        /* by default everything is powered off */
@@ -134,10 +190,21 @@ static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_p
                case DIB7000P_POWER_ALL:
                        reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff;
                        break;
+
+               case DIB7000P_POWER_ANALOG_ADC:
+                       /* dem, cfg, iqc, sad, agc */
+                       reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
+                       /* nud */
+                       reg_776 &= ~((1 << 0));
+                       /* Dout */
+                       reg_1280 &= ~((1 << 11));
+                       /* fall through wanted to enable the interfaces */
+
                /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
                case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
                        reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
                        break;
+
 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
        }
 
@@ -188,34 +255,31 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad
                        break;
        }
 
-//     dprintk("908: %x, 909: %x\n", reg_908, reg_909);
+//     dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
 
        dib7000p_write_word(state, 908, reg_908);
        dib7000p_write_word(state, 909, reg_909);
 }
 
-static int dib7000p_set_bandwidth(struct dvb_frontend *demod, u8 BW_Idx)
+static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
 {
-       struct dib7000p_state *state = demod->demodulator_priv;
        u32 timf;
 
        // store the current bandwidth for later use
-       state->current_bandwidth = BW_Idx;
+       state->current_bandwidth = bw;
 
        if (state->timf == 0) {
-               dprintk("-D-  Using default timf\n");
+               dprintk( "using default timf");
                timf = state->cfg.bw->timf;
        } else {
-               dprintk("-D-  Using updated timf\n");
+               dprintk( "using updated timf");
                timf = state->timf;
        }
 
-       timf = timf * (BW_INDEX_TO_KHZ(BW_Idx) / 100) / 80;
-
-       dprintk("timf: %d\n",timf);
+       timf = timf * (bw / 50) / 160;
 
-       dib7000p_write_word(state, 23, (timf >> 16) & 0xffff);
-       dib7000p_write_word(state, 24, (timf      ) & 0xffff);
+       dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
+       dib7000p_write_word(state, 24, (u16) ((timf      ) & 0xffff));
 
        return 0;
 }
@@ -223,7 +287,7 @@ static int dib7000p_set_bandwidth(struct dvb_frontend *demod, u8 BW_Idx)
 static int dib7000p_sad_calib(struct dib7000p_state *state)
 {
 /* internal */
-//     dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is written in set_bandwidth
+//     dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
        dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
        dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096
 
@@ -236,18 +300,37 @@ static int dib7000p_sad_calib(struct dib7000p_state *state)
        return 0;
 }
 
+int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
+{
+       struct dib7000p_state *state = demod->demodulator_priv;
+       if (value > 4095)
+               value = 4095;
+       state->wbd_ref = value;
+       return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
+}
+
+EXPORT_SYMBOL(dib7000p_set_wbd_ref);
 static void dib7000p_reset_pll(struct dib7000p_state *state)
 {
        struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
+       u16 clk_cfg0;
+
+       /* force PLL bypass */
+       clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
+               (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) |
+               (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
 
+       dib7000p_write_word(state, 900, clk_cfg0);
+
+       /* P_pll_cfg */
        dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
-       dib7000p_write_word(state, 900, ((bw->pll_ratio & 0x3f) << 9) | (bw->pll_bypass << 15) | (bw->modulo << 7) | (bw->ADClkSrc << 6) |
-               (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0));
+       clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
+       dib7000p_write_word(state, 900, clk_cfg0);
 
-       dib7000p_write_word(state, 18, ((bw->internal*1000) >> 16) & 0xffff);
-       dib7000p_write_word(state, 19,  (bw->internal*1000       ) & 0xffff);
-       dib7000p_write_word(state, 21,  (bw->ifreq          >> 16) & 0xffff);
-       dib7000p_write_word(state, 22,  (bw->ifreq               ) & 0xffff);
+       dib7000p_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
+       dib7000p_write_word(state, 19, (u16) ( (bw->internal*1000       ) & 0xffff));
+       dib7000p_write_word(state, 21, (u16) ( (bw->ifreq          >> 16) & 0xffff));
+       dib7000p_write_word(state, 22, (u16) ( (bw->ifreq               ) & 0xffff));
 
        dib7000p_write_word(state, 72, bw->sad_cfg);
 }
@@ -255,7 +338,7 @@ static void dib7000p_reset_pll(struct dib7000p_state *state)
 static int dib7000p_reset_gpio(struct dib7000p_state *st)
 {
        /* reset the GPIOs */
-       dprintk("-D-  gpio dir: %x: gpio val: %x, gpio pwm pos: %x\n",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos);
+       dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos);
 
        dib7000p_write_word(st, 1029, st->gpio_dir);
        dib7000p_write_word(st, 1030, st->gpio_val);
@@ -268,6 +351,120 @@ static int dib7000p_reset_gpio(struct dib7000p_state *st)
        return 0;
 }
 
+static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
+{
+       st->gpio_dir = dib7000p_read_word(st, 1029);
+       st->gpio_dir &= ~(1 << num);         /* reset the direction bit */
+       st->gpio_dir |=  (dir & 0x1) << num; /* set the new direction */
+       dib7000p_write_word(st, 1029, st->gpio_dir);
+
+       st->gpio_val = dib7000p_read_word(st, 1030);
+       st->gpio_val &= ~(1 << num);          /* reset the direction bit */
+       st->gpio_val |=  (val & 0x01) << num; /* set the new value */
+       dib7000p_write_word(st, 1030, st->gpio_val);
+
+       return 0;
+}
+
+int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
+{
+       struct dib7000p_state *state = demod->demodulator_priv;
+       return dib7000p_cfg_gpio(state, num, dir, val);
+}
+
+EXPORT_SYMBOL(dib7000p_set_gpio);
+static u16 dib7000p_defaults[] =
+
+{
+       // auto search configuration
+       3, 2,
+               0x0004,
+               0x1000,
+               0x0814, /* Equal Lock */
+
+       12, 6,
+               0x001b,
+               0x7740,
+               0x005b,
+               0x8d80,
+               0x01c9,
+               0xc380,
+               0x0000,
+               0x0080,
+               0x0000,
+               0x0090,
+               0x0001,
+               0xd4c0,
+
+       1, 26,
+               0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
+
+       /* set ADC level to -16 */
+       11, 79,
+               (1 << 13) - 825 - 117,
+               (1 << 13) - 837 - 117,
+               (1 << 13) - 811 - 117,
+               (1 << 13) - 766 - 117,
+               (1 << 13) - 737 - 117,
+               (1 << 13) - 693 - 117,
+               (1 << 13) - 648 - 117,
+               (1 << 13) - 619 - 117,
+               (1 << 13) - 575 - 117,
+               (1 << 13) - 531 - 117,
+               (1 << 13) - 501 - 117,
+
+       1, 142,
+               0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
+
+       /* disable power smoothing */
+       8, 145,
+               0,
+               0,
+               0,
+               0,
+               0,
+               0,
+               0,
+               0,
+
+       1, 154,
+               1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
+
+       1, 168,
+               0x0ccd, // P_pha3_thres, default 0x3000
+
+//     1, 169,
+//             0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
+
+       1, 183,
+               0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
+
+       5, 187,
+               0x023d, // P_adp_regul_cnt=573, default: 410
+               0x00a4, // P_adp_noise_cnt=
+               0x00a4, // P_adp_regul_ext
+               0x7ff0, // P_adp_noise_ext
+               0x3ccc, // P_adp_fil
+
+       1, 198,
+               0x800, // P_equal_thres_wgn
+
+       1, 222,
+               0x0010, // P_fec_ber_rs_len=2
+
+       1, 235,
+               0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
+
+       2, 901,
+               0x0006, // P_clk_cfg1
+               (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
+
+       1, 905,
+               0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
+
+       0,
+};
+
 static int dib7000p_demod_reset(struct dib7000p_state *state)
 {
        dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
@@ -292,111 +489,307 @@ static int dib7000p_demod_reset(struct dib7000p_state *state)
        dib7000p_reset_pll(state);
 
        if (dib7000p_reset_gpio(state) != 0)
-               dprintk("-E-  GPIO reset was not successful.\n");
+               dprintk( "GPIO reset was not successful.");
 
        if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
-               dprintk("-E-  OUTPUT_MODE could not be resetted.\n");
+               dprintk( "OUTPUT_MODE could not be reset.");
 
        /* unforce divstr regardless whether i2c enumeration was done or not */
        dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) );
 
+       dib7000p_set_bandwidth(state, 8000);
+
+       dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
+       dib7000p_sad_calib(state);
+       dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
+
+       // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
+       if(state->cfg.tuner_is_baseband)
+               dib7000p_write_word(state, 36,0x0755);
+       else
+               dib7000p_write_word(state, 36,0x1f55);
+
+       dib7000p_write_tab(state, dib7000p_defaults);
+
        dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
 
+
        return 0;
 }
 
+static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
+{
+       u16 tmp = 0;
+       tmp = dib7000p_read_word(state, 903);
+       dib7000p_write_word(state, 903, (tmp | 0x1));   //pwr-up pll
+       tmp = dib7000p_read_word(state, 900);
+       dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));     //use High freq clock
+}
+
 static void dib7000p_restart_agc(struct dib7000p_state *state)
 {
        // P_restart_iqc & P_restart_agc
-       dib7000p_write_word(state, 770, 0x0c00);
+       dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
        dib7000p_write_word(state, 770, 0x0000);
 }
 
-static void dib7000p_update_lna(struct dib7000p_state *state)
+static int dib7000p_update_lna(struct dib7000p_state *state)
 {
-       int i;
        u16 dyn_gain;
 
        // when there is no LNA to program return immediatly
-       if (state->cfg.update_lna == NULL)
-               return;
-
-       for (i = 0; i < 5; i++) {
-               // read dyn_gain here (because it is demod-dependent and not tuner)
+       if (state->cfg.update_lna) {
+               // read dyn_gain here (because it is demod-dependent and not fe)
                dyn_gain = dib7000p_read_word(state, 394);
-
                if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
                        dib7000p_restart_agc(state);
-                       msleep(5);
-               } else
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
+{
+       struct dibx000_agc_config *agc = NULL;
+       int i;
+       if (state->current_band == band && state->current_agc != NULL)
+               return 0;
+       state->current_band = band;
+
+       for (i = 0; i < state->cfg.agc_config_count; i++)
+               if (state->cfg.agc[i].band_caps & band) {
+                       agc = &state->cfg.agc[i];
                        break;
+               }
+
+       if (agc == NULL) {
+               dprintk( "no valid AGC configuration found for band 0x%02x",band);
+               return -EINVAL;
        }
+
+       state->current_agc = agc;
+
+       /* AGC */
+       dib7000p_write_word(state, 75 ,  agc->setup );
+       dib7000p_write_word(state, 76 ,  agc->inv_gain );
+       dib7000p_write_word(state, 77 ,  agc->time_stabiliz );
+       dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
+
+       // Demod AGC loop configuration
+       dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
+       dib7000p_write_word(state, 102, (agc->beta_mant << 6)  | agc->beta_exp);
+
+       /* AGC continued */
+       dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
+               state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
+
+       if (state->wbd_ref != 0)
+               dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
+       else
+               dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
+
+       dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
+
+       dib7000p_write_word(state, 107,  agc->agc1_max);
+       dib7000p_write_word(state, 108,  agc->agc1_min);
+       dib7000p_write_word(state, 109,  agc->agc2_max);
+       dib7000p_write_word(state, 110,  agc->agc2_min);
+       dib7000p_write_word(state, 111, (agc->agc1_pt1    << 8) | agc->agc1_pt2);
+       dib7000p_write_word(state, 112,  agc->agc1_pt3);
+       dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
+       dib7000p_write_word(state, 114, (agc->agc2_pt1    << 8) | agc->agc2_pt2);
+       dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
+       return 0;
 }
 
-static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
+static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
 {
-       u16 tmp = 0;
-       tmp = dib7000p_read_word(state, 903);
-       dib7000p_write_word(state, 903, (tmp | 0x1));   //pwr-up pll
-       tmp = dib7000p_read_word(state, 900);
-       dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));     //use High freq clock
+       struct dib7000p_state *state = demod->demodulator_priv;
+       int ret = -1;
+       u8 *agc_state = &state->agc_state;
+       u8 agc_split;
+
+       switch (state->agc_state) {
+               case 0:
+                       // set power-up level: interf+analog+AGC
+                       dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
+                       dib7000p_set_adc_state(state, DIBX000_ADC_ON);
+                       dib7000p_pll_clk_cfg(state);
+
+                       if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
+                               return -1;
+
+                       ret = 7;
+                       (*agc_state)++;
+                       break;
+
+               case 1:
+                       // AGC initialization
+                       if (state->cfg.agc_control)
+                               state->cfg.agc_control(&state->demod, 1);
+
+                       dib7000p_write_word(state, 78, 32768);
+                       if (!state->current_agc->perform_agc_softsplit) {
+                               /* we are using the wbd - so slow AGC startup */
+                               /* force 0 split on WBD and restart AGC */
+                               dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
+                               (*agc_state)++;
+                               ret = 5;
+                       } else {
+                               /* default AGC startup */
+                               (*agc_state) = 4;
+                               /* wait AGC rough lock time */
+                               ret = 7;
+                       }
+
+                       dib7000p_restart_agc(state);
+                       break;
+
+               case 2: /* fast split search path after 5sec */
+                       dib7000p_write_word(state,  75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
+                       dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
+                       (*agc_state)++;
+                       ret = 14;
+                       break;
+
+       case 3: /* split search ended */
+                       agc_split = (u8)dib7000p_read_word(state, 396); /* store the split value for the next time */
+                       dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
+
+                       dib7000p_write_word(state, 75,  state->current_agc->setup);   /* std AGC loop */
+                       dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
+
+                       dib7000p_restart_agc(state);
+
+                       dprintk( "SPLIT %p: %hd", demod, agc_split);
+
+                       (*agc_state)++;
+                       ret = 5;
+                       break;
+
+               case 4: /* LNA startup */
+                       // wait AGC accurate lock time
+                       ret = 7;
+
+                       if (dib7000p_update_lna(state))
+                               // wait only AGC rough lock time
+                               ret = 5;
+                       else // nothing was done, go to the next state
+                               (*agc_state)++;
+                       break;
+
+               case 5:
+                       if (state->cfg.agc_control)
+                               state->cfg.agc_control(&state->demod, 0);
+                       (*agc_state)++;
+                       break;
+               default:
+                       break;
+       }
+       return ret;
 }
 
-static void dib7000p_update_timf_freq(struct dib7000p_state *state)
+static void dib7000p_update_timf(struct dib7000p_state *state)
 {
        u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
-       state->timf = timf * 80 / (BW_INDEX_TO_KHZ(state->current_bandwidth) / 100);
+       state->timf = timf * 160 / (state->current_bandwidth / 50);
        dib7000p_write_word(state, 23, (u16) (timf >> 16));
        dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
-       dprintk("-D-  Updated timf_frequency: %d (default: %d)\n",state->timf, state->cfg.bw->timf);
+       dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->cfg.bw->timf);
+
 }
 
-static void dib7000p_set_channel(struct dib7000p_state *state, struct dibx000_ofdm_channel *ch, u8 seq)
+static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
 {
-       u16 tmp, est[4]; // reg_26, reg_32, reg_33, reg_187, reg_188, reg_189, reg_190, reg_207, reg_208;
+       u16 value, est[4];
+
+    dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
 
        /* nfft, guard, qam, alpha */
-       dib7000p_write_word(state, 0, (ch->nfft << 7) | (ch->guard << 5) | (ch->nqam << 3) | (ch->vit_alpha));
+       value = 0;
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
+               case /* 4K MODE */ 255: value |= (2 << 7); break;
+               default:
+               case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
+       }
+       switch (ch->u.ofdm.guard_interval) {
+               case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
+               case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
+               case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
+               default:
+               case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
+       }
+       switch (ch->u.ofdm.constellation) {
+               case QPSK:  value |= (0 << 3); break;
+               case QAM_16: value |= (1 << 3); break;
+               default:
+               case QAM_64: value |= (2 << 3); break;
+       }
+       switch (HIERARCHY_1) {
+               case HIERARCHY_2: value |= 2; break;
+               case HIERARCHY_4: value |= 4; break;
+               default:
+               case HIERARCHY_1: value |= 1; break;
+       }
+       dib7000p_write_word(state, 0, value);
        dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
 
-       /* P_dintl_native, P_dintlv_inv, P_vit_hrch, P_vit_code_rate, P_vit_select_hp */
-       tmp = (ch->intlv_native << 6) | (ch->vit_hrch << 4) | (ch->vit_select_hp & 0x1);
-       if (ch->vit_hrch == 0 || ch->vit_select_hp == 1)
-               tmp |= (ch->vit_code_rate_hp << 1);
-       else
-               tmp |= (ch->vit_code_rate_lp << 1);
-       dib7000p_write_word(state, 208, tmp);
+       /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
+       value = 0;
+       if (1 != 0)
+               value |= (1 << 6);
+       if (ch->u.ofdm.hierarchy_information == 1)
+               value |= (1 << 4);
+       if (1 == 1)
+               value |= 1;
+       switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
+               case FEC_2_3: value |= (2 << 1); break;
+               case FEC_3_4: value |= (3 << 1); break;
+               case FEC_5_6: value |= (5 << 1); break;
+               case FEC_7_8: value |= (7 << 1); break;
+               default:
+               case FEC_1_2: value |= (1 << 1); break;
+       }
+       dib7000p_write_word(state, 208, value);
+
+       /* offset loop parameters */
+       dib7000p_write_word(state, 26, 0x6680); // timf(6xxx)
+       dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3)
+       dib7000p_write_word(state, 29, 0x1273); // isi
+       dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5)
 
        /* P_dvsy_sync_wait */
-       switch (ch->nfft) {
-               case 1: tmp = 256; break;
-               case 2: tmp = 128; break;
-               case 0:
-               default: tmp = 64; break;
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_8K: value = 256; break;
+               case /* 4K MODE */ 255: value = 128; break;
+               case TRANSMISSION_MODE_2K:
+               default: value = 64; break;
        }
-       tmp *= ((1 << (ch->guard)) * 3 / 2); // add 50% SFN margin
-       tmp <<= 4;
-
-       /* deactive the possibility of diversity reception if extended interleave */
-       /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
-       if (ch->intlv_native || ch->nfft == 1)
-               tmp |= (1 << 2) | (2 << 0);
-       dib7000p_write_word(state, 207, tmp);
+       switch (ch->u.ofdm.guard_interval) {
+               case GUARD_INTERVAL_1_16: value *= 2; break;
+               case GUARD_INTERVAL_1_8:  value *= 4; break;
+               case GUARD_INTERVAL_1_4:  value *= 8; break;
+               default:
+               case GUARD_INTERVAL_1_32: value *= 1; break;
+       }
+       state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
 
-       dib7000p_write_word(state, 26, 0x6680);   // timf(6xxx)
-       dib7000p_write_word(state, 29, 0x1273);   // isi inh1273 on1073
-       dib7000p_write_word(state, 32, 0x0003);   // pha_off_max(xxx3)
-       dib7000p_write_word(state, 33, 0x0005);   // sfreq(xxx5)
+       /* deactive the possibility of diversity reception if extended interleaver */
+       state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
+       dib7000p_set_diversity_in(&state->demod, state->div_state);
 
        /* channel estimation fine configuration */
-       switch (ch->nqam) {
-               case 2:
+       switch (ch->u.ofdm.constellation) {
+               case QAM_64:
                        est[0] = 0x0148;       /* P_adp_regul_cnt 0.04 */
                        est[1] = 0xfff0;       /* P_adp_noise_cnt -0.002 */
                        est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
                        est[3] = 0xfff8;       /* P_adp_noise_ext -0.001 */
                        break;
-               case 1:
+               case QAM_16:
                        est[0] = 0x023d;       /* P_adp_regul_cnt 0.07 */
                        est[1] = 0xffdf;       /* P_adp_noise_cnt -0.004 */
                        est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
@@ -409,66 +802,45 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dibx000_of
                        est[3] = 0xfff8;       /* P_adp_noise_ext -0.002 */
                        break;
        }
-       for (tmp = 0; tmp < 4; tmp++)
-               dib7000p_write_word(state, 187 + tmp, est[tmp]);
-
-       // set power-up level: interf+analog+AGC
-       dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
-       dib7000p_set_adc_state(state, DIBX000_ADC_ON);
-       dib7000p_pll_clk_cfg(state);
-       msleep(7);
-
-       // AGC initialization
-       if (state->cfg.agc_control)
-               state->cfg.agc_control(&state->demod, 1);
-
-       dib7000p_restart_agc(state);
-
-       // wait AGC rough lock time
-       msleep(5);
-
-       dib7000p_update_lna(state);
-
-       // wait AGC accurate lock time
-       msleep(7);
-       if (state->cfg.agc_control)
-               state->cfg.agc_control(&state->demod, 0);
+       for (value = 0; value < 4; value++)
+               dib7000p_write_word(state, 187 + value, est[value]);
 }
 
-static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
+static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
 {
        struct dib7000p_state *state = demod->demodulator_priv;
-       struct dibx000_ofdm_channel auto_ch;
-       u32 value;
-
-       INIT_OFDM_CHANNEL(&auto_ch);
-       auto_ch.RF_kHz           = ch->RF_kHz;
-       auto_ch.Bw               = ch->Bw;
-       auto_ch.nqam             = 2;
-       auto_ch.guard            = 0;
-       auto_ch.nfft             = 1;
-       auto_ch.vit_alpha        = 1;
-       auto_ch.vit_select_hp    = 1;
-       auto_ch.vit_code_rate_hp = 2;
-       auto_ch.vit_code_rate_lp = 3;
-       auto_ch.vit_hrch         = 0;
-       auto_ch.intlv_native     = 1;
-
-       dib7000p_set_channel(state, &auto_ch, 7);
+       struct dvb_frontend_parameters schan;
+       u32 value, factor;
+
+       schan = *ch;
+       schan.u.ofdm.constellation = QAM_64;
+       schan.u.ofdm.guard_interval         = GUARD_INTERVAL_1_32;
+       schan.u.ofdm.transmission_mode          = TRANSMISSION_MODE_8K;
+       schan.u.ofdm.code_rate_HP  = FEC_2_3;
+       schan.u.ofdm.code_rate_LP  = FEC_3_4;
+       schan.u.ofdm.hierarchy_information          = 0;
+
+       dib7000p_set_channel(state, &schan, 7);
+
+       factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
+       if (factor >= 5000)
+               factor = 1;
+       else
+               factor = 6;
 
        // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
-       value = 30 * state->cfg.bw->internal;
+       value = 30 * state->cfg.bw->internal * factor;
        dib7000p_write_word(state, 6,  (u16) ((value >> 16) & 0xffff)); // lock0 wait time
        dib7000p_write_word(state, 7,  (u16)  (value        & 0xffff)); // lock0 wait time
-       value = 100 * state->cfg.bw->internal;
+       value = 100 * state->cfg.bw->internal * factor;
        dib7000p_write_word(state, 8,  (u16) ((value >> 16) & 0xffff)); // lock1 wait time
        dib7000p_write_word(state, 9,  (u16)  (value        & 0xffff)); // lock1 wait time
-       value = 500 * state->cfg.bw->internal;
+       value = 500 * state->cfg.bw->internal * factor;
        dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
        dib7000p_write_word(state, 11, (u16)  (value        & 0xffff)); // lock2 wait time
 
        value = dib7000p_read_word(state, 0);
-       dib7000p_write_word(state, 0, (1 << 9) | value);
+       dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
        dib7000p_read_word(state, 1284);
        dib7000p_write_word(state, 0, (u16) value);
 
@@ -489,7 +861,95 @@ static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
        return 0; // still pending
 }
 
-static int dib7000p_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
+static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
+{
+       static s16 notch[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392};
+       static u8 sine [] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
+       24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
+       53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
+       82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
+       107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
+       128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
+       147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
+       166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
+       183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
+       199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
+       213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
+       225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
+       235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
+       244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
+       250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
+       254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+       255, 255, 255, 255, 255, 255};
+
+       u32 xtal = state->cfg.bw->xtal_hz / 1000;
+       int f_rel = ( (rf_khz + xtal/2) / xtal) * xtal - rf_khz;
+       int k;
+       int coef_re[8],coef_im[8];
+       int bw_khz = bw;
+       u32 pha;
+
+       dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
+
+
+       if (f_rel < -bw_khz/2 || f_rel > bw_khz/2)
+               return;
+
+       bw_khz /= 100;
+
+       dib7000p_write_word(state, 142 ,0x0610);
+
+       for (k = 0; k < 8; k++) {
+               pha = ((f_rel * (k+1) * 112 * 80/bw_khz) /1000) & 0x3ff;
+
+               if (pha==0) {
+                       coef_re[k] = 256;
+                       coef_im[k] = 0;
+               } else if(pha < 256) {
+                       coef_re[k] = sine[256-(pha&0xff)];
+                       coef_im[k] = sine[pha&0xff];
+               } else if (pha == 256) {
+                       coef_re[k] = 0;
+                       coef_im[k] = 256;
+               } else if (pha < 512) {
+                       coef_re[k] = -sine[pha&0xff];
+                       coef_im[k] = sine[256 - (pha&0xff)];
+               } else if (pha == 512) {
+                       coef_re[k] = -256;
+                       coef_im[k] = 0;
+               } else if (pha < 768) {
+                       coef_re[k] = -sine[256-(pha&0xff)];
+                       coef_im[k] = -sine[pha&0xff];
+               } else if (pha == 768) {
+                       coef_re[k] = 0;
+                       coef_im[k] = -256;
+               } else {
+                       coef_re[k] = sine[pha&0xff];
+                       coef_im[k] = -sine[256 - (pha&0xff)];
+               }
+
+               coef_re[k] *= notch[k];
+               coef_re[k] += (1<<14);
+               if (coef_re[k] >= (1<<24))
+                       coef_re[k]  = (1<<24) - 1;
+               coef_re[k] /= (1<<15);
+
+               coef_im[k] *= notch[k];
+               coef_im[k] += (1<<14);
+               if (coef_im[k] >= (1<<24))
+                       coef_im[k]  = (1<<24)-1;
+               coef_im[k] /= (1<<15);
+
+               dprintk( "PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
+
+               dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
+               dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
+               dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
+       }
+       dib7000p_write_word(state,143 ,0);
+}
+
+static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
 {
        struct dib7000p_state *state = demod->demodulator_priv;
        u16 tmp = 0;
@@ -505,7 +965,15 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel
        msleep(45);
 
        /* 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 */
-       dib7000p_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
+       tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
+       if (state->sfn_workaround_active) {
+               dprintk( "SFN workaround is active");
+               tmp |= (1 << 9);
+               dib7000p_write_word(state, 166, 0x4000); // P_pha3_force_pha_shift
+       } else {
+               dib7000p_write_word(state, 166, 0x0000); // P_pha3_force_pha_shift
+       }
+       dib7000p_write_word(state, 29, tmp);
 
        // never achieved a lock with that bandwidth so far - wait for osc-freq to update
        if (state->timf == 0)
@@ -515,28 +983,31 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel
 
        /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
        tmp = (6 << 8) | 0x80;
-       switch (ch->nfft) {
-               case 0: tmp |= (7 << 12); break;
-               case 1: tmp |= (9 << 12); break;
-               case 2: tmp |= (8 << 12); break;
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break;
+               case /* 4K MODE */ 255: tmp |= (8 << 12); break;
+               default:
+               case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break;
        }
        dib7000p_write_word(state, 26, tmp);  /* timf_a(6xxx) */
 
        /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
        tmp = (0 << 4);
-       switch (ch->nfft) {
-               case 0: tmp |= 0x6; break;
-               case 1: tmp |= 0x8; break;
-               case 2: tmp |= 0x7; break;
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
+               case /* 4K MODE */ 255: tmp |= 0x7; break;
+               default:
+               case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
        }
        dib7000p_write_word(state, 32,  tmp);
 
        /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
        tmp = (0 << 4);
-       switch (ch->nfft) {
-               case 0: tmp |= 0x6; break;
-               case 1: tmp |= 0x8; break;
-               case 2: tmp |= 0x7; break;
+       switch (ch->u.ofdm.transmission_mode) {
+               case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
+               case /* 4K MODE */ 255: tmp |= 0x7; break;
+               default:
+               case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
        }
        dib7000p_write_word(state, 33,  tmp);
 
@@ -552,131 +1023,21 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel
 
        // we achieved a lock - it's time to update the osc freq
        if ((tmp >> 6) & 0x1)
-               dib7000p_update_timf_freq(state);
+               dib7000p_update_timf(state);
 
+       if (state->cfg.spur_protect)
+               dib7000p_spur_protect(state, ch->frequency/1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
+
+    dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
        return 0;
 }
 
-static int dib7000p_init(struct dvb_frontend *demod)
+static int dib7000p_wakeup(struct dvb_frontend *demod)
 {
-       struct dibx000_agc_config *agc;
        struct dib7000p_state *state = demod->demodulator_priv;
-       int ret = 0;
-
-       // Demodulator default configuration
-       agc = state->cfg.agc;
-
        dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
        dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
-
-       /* AGC */
-       ret |= dib7000p_write_word(state, 75 ,  agc->setup );
-       ret |= dib7000p_write_word(state, 76 ,  agc->inv_gain );
-       ret |= dib7000p_write_word(state, 77 ,  agc->time_stabiliz );
-       ret |= dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
-
-       // Demod AGC loop configuration
-       ret |= dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
-       ret |= dib7000p_write_word(state, 102, (agc->beta_mant << 6)  | agc->beta_exp);
-
-       /* AGC continued */
-       dprintk("-D-  WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
-               state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
-
-       if (state->wbd_ref != 0)
-               ret |= dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
-       else
-               ret |= dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
-
-       ret |= dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
-
-       ret |= dib7000p_write_word(state, 107,  agc->agc1_max);
-       ret |= dib7000p_write_word(state, 108,  agc->agc1_min);
-       ret |= dib7000p_write_word(state, 109,  agc->agc2_max);
-       ret |= dib7000p_write_word(state, 110,  agc->agc2_min);
-       ret |= dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2 );
-       ret |= dib7000p_write_word(state, 112,  agc->agc1_pt3);
-       ret |= dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
-       ret |= dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
-       ret |= dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
-
-       /* disable power smoothing */
-       ret |= dib7000p_write_word(state, 145, 0);
-       ret |= dib7000p_write_word(state, 146, 0);
-       ret |= dib7000p_write_word(state, 147, 0);
-       ret |= dib7000p_write_word(state, 148, 0);
-       ret |= dib7000p_write_word(state, 149, 0);
-       ret |= dib7000p_write_word(state, 150, 0);
-       ret |= dib7000p_write_word(state, 151, 0);
-       ret |= dib7000p_write_word(state, 152, 0);
-
-       // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
-       ret |= dib7000p_write_word(state, 26 ,0x6680);
-
-       // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
-       ret |= dib7000p_write_word(state, 142,0x0410);
-       // P_fft_freq_dir=1, P_fft_nb_to_cut=0
-       ret |= dib7000p_write_word(state, 154,1 << 13);
-       // P_pha3_thres, default 0x3000
-       ret |= dib7000p_write_word(state, 168,0x0ccd);
-       // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
-       //ret |= dib7000p_write_word(state, 169,0x0010);
-       // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
-       ret |= dib7000p_write_word(state, 183,0x200f);
-       // P_adp_regul_cnt=573, default: 410
-       ret |= dib7000p_write_word(state, 187,0x023d);
-       // P_adp_noise_cnt=
-       ret |= dib7000p_write_word(state, 188,0x00a4);
-       // P_adp_regul_ext
-       ret |= dib7000p_write_word(state, 189,0x00a4);
-       // P_adp_noise_ext
-       ret |= dib7000p_write_word(state, 190,0x7ff0);
-       // P_adp_fil
-       ret |= dib7000p_write_word(state, 191,0x3ccc);
-
-       ret |= dib7000p_write_word(state, 222,0x0010);
-       // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
-       ret |= dib7000p_write_word(state, 235,0x0062);
-
-       // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
-       if(state->cfg.tuner_is_baseband)
-               ret |= dib7000p_write_word(state, 36,0x0755);
-       else
-               ret |= dib7000p_write_word(state, 36,0x1f55);
-
-       // auto search configuration
-       ret |= dib7000p_write_word(state, 2  ,0x0004);
-       ret |= dib7000p_write_word(state, 3  ,0x1000);
-
-       /* Equal Lock */
-       ret |= dib7000p_write_word(state, 4   ,0x0814);
-
-       ret |= dib7000p_write_word(state, 6  ,0x001b);
-       ret |= dib7000p_write_word(state, 7  ,0x7740);
-       ret |= dib7000p_write_word(state, 8  ,0x005b);
-       ret |= dib7000p_write_word(state, 9  ,0x8d80);
-       ret |= dib7000p_write_word(state, 10 ,0x01c9);
-       ret |= dib7000p_write_word(state, 11 ,0xc380);
-       ret |= dib7000p_write_word(state, 12 ,0x0000);
-       ret |= dib7000p_write_word(state, 13 ,0x0080);
-       ret |= dib7000p_write_word(state, 14 ,0x0000);
-       ret |= dib7000p_write_word(state, 15 ,0x0090);
-       ret |= dib7000p_write_word(state, 16 ,0x0001);
-       ret |= dib7000p_write_word(state, 17 ,0xd4c0);
-
-       // P_clk_cfg1
-       ret |= dib7000p_write_word(state, 901, 0x0006);
-
-       // P_divclksel=3 P_divbitsel=1
-       ret |= dib7000p_write_word(state, 902, (3 << 10) | (1 << 6));
-
-       // Tuner IO bank: max drive (14mA) + divout pads max drive
-       ret |= dib7000p_write_word(state, 905, 0x2c8e);
-
-       ret |= dib7000p_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
-       dib7000p_sad_calib(state);
-
-       return ret;
+       return 0;
 }
 
 static int dib7000p_sleep(struct dvb_frontend *demod)
@@ -688,16 +1049,16 @@ static int dib7000p_sleep(struct dvb_frontend *demod)
 static int dib7000p_identify(struct dib7000p_state *st)
 {
        u16 value;
-       dprintk("-I-  DiB7000PC: checking demod on I2C address: %d (%x)\n",
+       dprintk( "checking demod on I2C address: %d (%x)",
                st->i2c_addr, st->i2c_addr);
 
        if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
-               dprintk("-E-  DiB7000PC: wrong Vendor ID (read=0x%x)\n",value);
+               dprintk( "wrong Vendor ID (read=0x%x)",value);
                return -EREMOTEIO;
        }
 
        if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
-               dprintk("-E-  DiB7000PC: wrong Device ID (%x)\n",value);
+               dprintk( "wrong Device ID (%x)",value);
                return -EREMOTEIO;
        }
 
@@ -767,41 +1128,48 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
                                struct dvb_frontend_parameters *fep)
 {
        struct dib7000p_state *state = fe->demodulator_priv;
-       struct dibx000_ofdm_channel ch;
-
-       INIT_OFDM_CHANNEL(&ch);
-       FEP2DIB(fep,&ch);
+       int time;
 
        state->current_bandwidth = fep->u.ofdm.bandwidth;
-       dib7000p_set_bandwidth(fe, fep->u.ofdm.bandwidth);
+       dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
+
+       /* maybe the parameter has been changed */
+       state->sfn_workaround_active = buggy_sfn_workaround;
 
        if (fe->ops.tuner_ops.set_params)
                fe->ops.tuner_ops.set_params(fe, fep);
 
+       /* start up the AGC */
+       state->agc_state = 0;
+       do {
+               time = dib7000p_agc_startup(fe, fep);
+               if (time != -1)
+                       msleep(time);
+       } while (time != -1);
+
        if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
                fep->u.ofdm.guard_interval    == GUARD_INTERVAL_AUTO ||
                fep->u.ofdm.constellation     == QAM_AUTO ||
                fep->u.ofdm.code_rate_HP      == FEC_AUTO) {
                int i = 800, found;
 
-               dib7000p_autosearch_start(fe, &ch);
+               dib7000p_autosearch_start(fe, fep);
                do {
                        msleep(1);
                        found = dib7000p_autosearch_is_irq(fe);
                } while (found == 0 && i--);
 
-               dprintk("autosearch returns: %d\n",found);
+               dprintk("autosearch returns: %d",found);
                if (found == 0 || found == 1)
                        return 0; // no channel found
 
                dib7000p_get_frontend(fe, fep);
-               FEP2DIB(fep, &ch);
        }
 
        /* make this a config parameter */
        dib7000p_set_output_mode(state, OUTMODE_MPEG2_FIFO);
 
-       return dib7000p_tune(fe, &ch);
+       return dib7000p_tune(fe, fep);
 }
 
 static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat)
@@ -879,7 +1247,7 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
 
        if (i2c_transfer(i2c_adap, msg, 2) == 2)
                if (rx[0] == 0x01 && rx[1] == 0xb3) {
-                       dprintk("-D-  DiB7000PC detected\n");
+                       dprintk("-D-  DiB7000PC detected");
                        return 1;
                }
 
@@ -887,11 +1255,11 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
 
        if (i2c_transfer(i2c_adap, msg, 2) == 2)
                if (rx[0] == 0x01 && rx[1] == 0xb3) {
-                       dprintk("-D-  DiB7000PC detected\n");
+                       dprintk("-D-  DiB7000PC detected");
                        return 1;
                }
 
-       dprintk("-D-  DiB7000PC not detected\n");
+       dprintk("-D-  DiB7000PC not detected");
        return 0;
 }
 EXPORT_SYMBOL(dib7000pc_detection);
@@ -929,7 +1297,7 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
                /* set new i2c address and force divstart */
                dib7000p_write_word(&st, 1285, (new_addr << 2) | 0x2);
 
-               dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);
+               dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
        }
 
        for (k = 0; k < no_of_demods; k++) {
@@ -1000,7 +1368,7 @@ static struct dvb_frontend_ops dib7000p_ops = {
 
        .release              = dib7000p_release,
 
-       .init                 = dib7000p_init,
+       .init                 = dib7000p_wakeup,
        .sleep                = dib7000p_sleep,
 
        .set_frontend         = dib7000p_set_frontend,
index 79465cf1aced24c285dc5d1f2aad065b5af5752a..eefcac8b5244197d0cf9390960a77d8cd954afe5 100644 (file)
@@ -9,6 +9,7 @@ struct dib7000p_config {
        u8 tuner_is_baseband;
        int (*update_lna) (struct dvb_frontend *, u16 agc_global);
 
+       u8 agc_config_count;
        struct dibx000_agc_config *agc;
        struct dibx000_bandwidth_config *bw;
 
@@ -27,20 +28,19 @@ struct dib7000p_config {
 
        u8 quartz_direct;
 
+       u8 spur_protect;
+
        int (*agc_control) (struct dvb_frontend *, u8 before);
 };
 
 #define DEFAULT_DIB7000P_I2C_ADDRESS 18
 
 extern struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
+extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
+
 extern struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
 extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
-
-/* TODO
-extern INT dib7000p_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val);
-extern INT dib7000p_enable_vbg_voltage(struct dibDemod *demod);
-extern void dib7000p_set_hostbus_diversity(struct dibDemod *demod, UCHAR onoff);
-extern USHORT dib7000p_get_current_agc_global(struct dibDemod *demod);
-*/
+extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
+extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
 
 #endif
index a1df604366c37251200771362ffe7c331fdb8196..5e17275afd256c732716c853164a2dcc29dd3c0c 100644 (file)
@@ -111,6 +111,8 @@ struct dibx000_bandwidth_config {
 
        u32 ifreq;
        u32 timf;
+
+       u32 xtal_hz;
 };
 
 enum dibx000_adc_states {
@@ -122,56 +124,17 @@ enum dibx000_adc_states {
        DIBX000_VBG_DISABLE,
 };
 
-#define BW_INDEX_TO_KHZ(v) ( (v) == BANDWIDTH_8_MHZ  ? 8000 : \
+#define BANDWIDTH_TO_KHZ(v) ( (v) == BANDWIDTH_8_MHZ  ? 8000 : \
                             (v) == BANDWIDTH_7_MHZ  ? 7000 : \
                             (v) == BANDWIDTH_6_MHZ  ? 6000 : 8000 )
 
 /* Chip output mode. */
-#define OUTMODE_HIGH_Z                      0
-#define OUTMODE_MPEG2_PAR_GATED_CLK         1
-#define OUTMODE_MPEG2_PAR_CONT_CLK          2
-#define OUTMODE_MPEG2_SERIAL                7
-#define OUTMODE_DIVERSITY                   4
-#define OUTMODE_MPEG2_FIFO                  5
-
-/* I hope I can get rid of the following kludge in the near future */
-struct dibx000_ofdm_channel {
-       u32 RF_kHz;
-       u8  Bw;
-       s16 nfft;
-       s16 guard;
-       s16 nqam;
-       s16 vit_hrch;
-       s16 vit_select_hp;
-       s16 vit_alpha;
-       s16 vit_code_rate_hp;
-       s16 vit_code_rate_lp;
-       u8  intlv_native;
-};
-
-#define FEP2DIB(fep,ch) \
-       (ch)->RF_kHz           = (fep)->frequency / 1000; \
-       (ch)->Bw               = (fep)->u.ofdm.bandwidth; \
-       (ch)->nfft             = (fep)->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ? -1 : (fep)->u.ofdm.transmission_mode; \
-       (ch)->guard            = (fep)->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ? -1 : (fep)->u.ofdm.guard_interval; \
-       (ch)->nqam             = (fep)->u.ofdm.constellation == QAM_AUTO ? -1 : (fep)->u.ofdm.constellation == QAM_64 ? 2 : (fep)->u.ofdm.constellation; \
-       (ch)->vit_hrch         = 0; /* linux-dvb is not prepared for HIERARCHICAL TRANSMISSION */ \
-       (ch)->vit_select_hp    = 1; \
-       (ch)->vit_alpha        = 1; \
-       (ch)->vit_code_rate_hp = (fep)->u.ofdm.code_rate_HP == FEC_AUTO ? -1 : (fep)->u.ofdm.code_rate_HP; \
-       (ch)->vit_code_rate_lp = (fep)->u.ofdm.code_rate_LP == FEC_AUTO ? -1 : (fep)->u.ofdm.code_rate_LP; \
-       (ch)->intlv_native     = 1;
-
-#define INIT_OFDM_CHANNEL(ch) do {\
-       (ch)->Bw               = 0;  \
-       (ch)->nfft             = -1; \
-       (ch)->guard            = -1; \
-       (ch)->nqam             = -1; \
-       (ch)->vit_hrch         = -1; \
-       (ch)->vit_select_hp    = -1; \
-       (ch)->vit_alpha        = -1; \
-       (ch)->vit_code_rate_hp = -1; \
-       (ch)->vit_code_rate_lp = -1; \
-} while (0)
+#define OUTMODE_HIGH_Z              0
+#define OUTMODE_MPEG2_PAR_GATED_CLK 1
+#define OUTMODE_MPEG2_PAR_CONT_CLK  2
+#define OUTMODE_MPEG2_SERIAL        7
+#define OUTMODE_DIVERSITY           4
+#define OUTMODE_MPEG2_FIFO          5
+#define OUTMODE_ANALOG_ADC          6
 
 #endif
index 11f7d5939bd924269aa318f55d9b6904671a8110..8c8d7342d0b37254475d22a804e4680455d5be3a 100644 (file)
 
 #include "dvb-pll.h"
 
+struct dvb_pll_priv {
+       /* pll number */
+       int nr;
+
+       /* i2c details */
+       int pll_i2c_address;
+       struct i2c_adapter *i2c;
+
+       /* the PLL descriptor */
+       struct dvb_pll_desc *pll_desc;
+
+       /* cached frequency/bandwidth */
+       u32 frequency;
+       u32 bandwidth;
+};
+
+#define DVB_PLL_MAX 64
+
+static unsigned int dvb_pll_devcount;
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+static unsigned int input[DVB_PLL_MAX] = { [ 0 ... (DVB_PLL_MAX-1) ] = 0 };
+module_param_array(input, int, NULL, 0644);
+MODULE_PARM_DESC(input,"specify rf input choice, 0 for autoselect (default)");
+
+static unsigned int id[DVB_PLL_MAX] =
+       { [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED };
+module_param_array(id, int, NULL, 0644);
+MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)");
+
+/* ----------------------------------------------------------- */
+
 struct dvb_pll_desc {
        char *name;
        u32  min;
        u32  max;
        u32  iffreq;
-       void (*set)(u8 *buf, const struct dvb_frontend_parameters *params);
+       void (*set)(struct dvb_frontend *fe, u8 *buf,
+                   const struct dvb_frontend_parameters *params);
        u8   *initdata;
        u8   *sleepdata;
        int  count;
@@ -89,7 +125,7 @@ static struct dvb_pll_desc dvb_pll_thomson_dtt7610 = {
        },
 };
 
-static void thomson_dtt759x_bw(u8 *buf,
+static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf,
                               const struct dvb_frontend_parameters *params)
 {
        if (BANDWIDTH_7_MHZ == params->u.ofdm.bandwidth)
@@ -210,7 +246,8 @@ static struct dvb_pll_desc dvb_pll_env57h1xd5 = {
 /* Philips TDA6650/TDA6651
  * used in Panasonic ENV77H11D5
  */
-static void tda665x_bw(u8 *buf, const struct dvb_frontend_parameters *params)
+static void tda665x_bw(struct dvb_frontend *fe, u8 *buf,
+                      const struct dvb_frontend_parameters *params)
 {
        if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
                buf[3] |= 0x08;
@@ -243,7 +280,8 @@ static struct dvb_pll_desc dvb_pll_tda665x = {
 /* Infineon TUA6034
  * used in LG TDTP E102P
  */
-static void tua6034_bw(u8 *buf, const struct dvb_frontend_parameters *params)
+static void tua6034_bw(struct dvb_frontend *fe, u8 *buf,
+                      const struct dvb_frontend_parameters *params)
 {
        if (BANDWIDTH_7_MHZ != params->u.ofdm.bandwidth)
                buf[3] |= 0x08;
@@ -283,7 +321,8 @@ static struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = {
 /* Philips FMD1216ME
  * used in Medion Hybrid PCMCIA card and USB Box
  */
-static void fmd1216me_bw(u8 *buf, const struct dvb_frontend_parameters *params)
+static void fmd1216me_bw(struct dvb_frontend *fe, u8 *buf,
+                        const struct dvb_frontend_parameters *params)
 {
        if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ &&
            params->frequency >= 158870000)
@@ -313,7 +352,8 @@ static struct dvb_pll_desc dvb_pll_fmd1216me = {
 /* ALPS TDED4
  * used in Nebula-Cards and USB boxes
  */
-static void tded4_bw(u8 *buf, const struct dvb_frontend_parameters *params)
+static void tded4_bw(struct dvb_frontend *fe, u8 *buf,
+                    const struct dvb_frontend_parameters *params)
 {
        if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
                buf[3] |= 0x04;
@@ -354,16 +394,35 @@ static struct dvb_pll_desc dvb_pll_tdhu2 = {
 /* Philips TUV1236D
  * used in ATI HDTV Wonder
  */
-static void tuv1236d_rf(u8 *buf, const struct dvb_frontend_parameters *params)
+static void tuv1236d_rf(struct dvb_frontend *fe, u8 *buf,
+                       const struct dvb_frontend_parameters *params)
 {
-       switch (params->u.vsb.modulation) {
-               case QAM_64:
-               case QAM_256:
+       struct dvb_pll_priv *priv = fe->tuner_priv;
+       unsigned int new_rf = input[priv->nr];
+
+       if ((new_rf == 0) || (new_rf > 2)) {
+               switch (params->u.vsb.modulation) {
+                       case QAM_64:
+                       case QAM_256:
+                               new_rf = 1;
+                               break;
+                       case VSB_8:
+                       default:
+                               new_rf = 2;
+               }
+       }
+
+       switch (new_rf) {
+               case 1:
                        buf[3] |= 0x08;
                        break;
-               case VSB_8:
-               default:
+               case 2:
                        buf[3] &= ~0x08;
+                       break;
+               default:
+                       printk(KERN_WARNING
+                              "%s: unhandled rf input selection: %d",
+                              __FUNCTION__, new_rf);
        }
 }
 
@@ -420,7 +479,8 @@ static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
 /*
  * Philips TD1316 Tuner.
  */
-static void td1316_bw(u8 *buf, const struct dvb_frontend_parameters *params)
+static void td1316_bw(struct dvb_frontend *fe, u8 *buf,
+                     const struct dvb_frontend_parameters *params)
 {
        u8 band;
 
@@ -474,7 +534,8 @@ static struct dvb_pll_desc dvb_pll_thomson_fe6600 = {
        }
 };
 
-static void opera1_bw(u8 *buf, const struct dvb_frontend_parameters *params)
+static void opera1_bw(struct dvb_frontend *fe, u8 *buf,
+                     const struct dvb_frontend_parameters *params)
 {
        if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
                buf[2] |= 0x08;
@@ -545,31 +606,14 @@ static struct dvb_pll_desc *pll_list[] = {
        [DVB_PLL_FCV1236D]               = &dvb_pll_fcv1236d,
 };
 
-/* ----------------------------------------------------------- */
-
-struct dvb_pll_priv {
-       /* i2c details */
-       int pll_i2c_address;
-       struct i2c_adapter *i2c;
-
-       /* the PLL descriptor */
-       struct dvb_pll_desc *pll_desc;
-
-       /* cached frequency/bandwidth */
-       u32 frequency;
-       u32 bandwidth;
-};
-
 /* ----------------------------------------------------------- */
 /* code                                                        */
 
-static int debug = 0;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable verbose debug messages");
-
-static int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
+static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf,
                             const struct dvb_frontend_parameters *params)
 {
+       struct dvb_pll_priv *priv = fe->tuner_priv;
+       struct dvb_pll_desc *desc = priv->pll_desc;
        u32 div;
        int i;
 
@@ -597,7 +641,7 @@ static int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
        buf[3] = desc->entries[i].cb;
 
        if (desc->set)
-               desc->set(buf, params);
+               desc->set(fe, buf, params);
 
        if (debug)
                printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
@@ -654,7 +698,7 @@ static int dvb_pll_set_params(struct dvb_frontend *fe,
        if (priv->i2c == NULL)
                return -EINVAL;
 
-       if ((result = dvb_pll_configure(priv->pll_desc, buf, params)) < 0)
+       if ((result = dvb_pll_configure(fe, buf, params)) < 0)
                return result;
        else
                frequency = result;
@@ -682,7 +726,7 @@ static int dvb_pll_calc_regs(struct dvb_frontend *fe,
        if (buf_len < 5)
                return -EINVAL;
 
-       if ((result = dvb_pll_configure(priv->pll_desc, buf+1, params)) < 0)
+       if ((result = dvb_pll_configure(fe, buf+1, params)) < 0)
                return result;
        else
                frequency = result;
@@ -755,6 +799,10 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
        int ret;
        struct dvb_pll_desc *desc;
 
+       if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) &&
+           (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list)))
+               pll_desc_id = id[dvb_pll_devcount];
+
        BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list));
 
        desc = pll_list[pll_desc_id];
@@ -777,6 +825,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
        priv->pll_i2c_address = pll_addr;
        priv->i2c = i2c;
        priv->pll_desc = desc;
+       priv->nr = dvb_pll_devcount++;
 
        memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops,
               sizeof(struct dvb_tuner_ops));
@@ -791,6 +840,30 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
                fe->ops.tuner_ops.sleep = NULL;
 
        fe->tuner_priv = priv;
+
+       if ((debug) || (id[priv->nr] == pll_desc_id)) {
+               printk("dvb-pll[%d]", priv->nr);
+               if (i2c != NULL)
+                       printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr);
+               printk(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name,
+                      id[priv->nr] == pll_desc_id ?
+                               "insmod option" : "autodetected");
+       }
+       if ((debug) || (input[priv->nr] > 0)) {
+               printk("dvb-pll[%d]", priv->nr);
+               if (i2c != NULL)
+                       printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr);
+               printk(": tuner rf input will be ");
+               switch (input[priv->nr]) {
+               case 0:
+                       printk("autoselected\n");
+                       break;
+               default:
+                       printk("set to input %d (insmod option)\n",
+                              input[priv->nr]);
+               }
+       }
+
        return fe;
 }
 EXPORT_SYMBOL(dvb_pll_attach);
index 6271b1e7f6ab94c8abdc55a35f64d9ee692223ab..fed09dfb2b7c64eb2c90b5ebd9ec64a913512b47 100644 (file)
@@ -20,7 +20,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/slab.h>
index c967148a5945c6fd53a2da491b11c0b84cbfb3b2..684c8ec166cbc7bfbdaed883a18c664ec59dd428 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 
index 1aeacb1c4af7b034ba17c2bd46f43af9fac47bc6..443d9045d4c9b8d93ec8fa2f53a18f9351166d6c 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include "dvb_frontend.h"
index e25286e2d4315b53d8e5aa295383d239ea20326f..bdc9fa88b86afc93128f43de48adabfb1818bca2 100644 (file)
@@ -35,7 +35,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/string.h>
index 2d2f58c26226527dd7ddadd5fd4e9ba634d388a4..76f935d9755a4764ed775f0b26c72bc9d05102e8 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 
index 450fad8d9b65099ced8ca7f99a789fce9e3636ad..1305b0e63ce5a6b268c5203eb035393d746407a3 100644 (file)
@@ -22,7 +22,6 @@
 /* In that file, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/delay.h>
 #include <linux/dvb/frontend.h>
 #include <linux/i2c.h>
diff --git a/drivers/media/dvb/frontends/mt2131.c b/drivers/media/dvb/frontends/mt2131.c
new file mode 100644 (file)
index 0000000..4b93931
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+ *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "mt2131.h"
+#include "mt2131_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(level,fmt, arg...) if (debug >= level) \
+       printk(KERN_INFO "%s: " fmt, "mt2131", ## arg)
+
+static u8 mt2131_config1[] = {
+       0x01,
+       0x50, 0x00, 0x50, 0x80, 0x00, 0x49, 0xfa, 0x88,
+       0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
+       0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80,
+       0xff, 0x68, 0xa0, 0xff, 0xdd, 0x00, 0x00
+};
+
+static u8 mt2131_config2[] = {
+       0x10,
+       0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
+};
+
+static int mt2131_readreg(struct mt2131_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->cfg->i2c_address, .flags = 0,
+                 .buf = &reg, .len = 1 },
+               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
+                 .buf = val,  .len = 1 },
+       };
+
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "mt2131 I2C read failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mt2131_writereg(struct mt2131_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0,
+                              .buf = buf, .len = 2 };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "mt2131 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mt2131_writeregs(struct mt2131_priv *priv,u8 *buf, u8 len)
+{
+       struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
+                              .flags = 0, .buf = buf, .len = len };
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "mt2131 I2C write failed (len=%i)\n",
+                      (int)len);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+static int mt2131_set_params(struct dvb_frontend *fe,
+                            struct dvb_frontend_parameters *params)
+{
+       struct mt2131_priv *priv;
+       int ret=0, i;
+       u32 freq;
+       u8  if_band_center;
+       u32 f_lo1, f_lo2;
+       u32 div1, num1, div2, num2;
+       u8  b[8];
+       u8 lockval = 0;
+
+       priv = fe->tuner_priv;
+       if (fe->ops.info.type == FE_OFDM)
+               priv->bandwidth = params->u.ofdm.bandwidth;
+       else
+               priv->bandwidth = 0;
+
+       freq = params->frequency / 1000;  // Hz -> kHz
+       dprintk(1, "%s() freq=%d\n", __FUNCTION__, freq);
+
+       f_lo1 = freq + MT2131_IF1 * 1000;
+       f_lo1 = (f_lo1 / 250) * 250;
+       f_lo2 = f_lo1 - freq - MT2131_IF2;
+
+       priv->frequency =  (f_lo1 - f_lo2 - MT2131_IF2) * 1000,
+
+       /* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
+       num1 = f_lo1 * 64 / (MT2131_FREF / 128);
+       div1 = num1 / 8192;
+       num1 &= 0x1fff;
+
+       /* Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 ) */
+       num2 = f_lo2 * 64 / (MT2131_FREF / 128);
+       div2 = num2 / 8192;
+       num2 &= 0x1fff;
+
+       if (freq <=   82500) if_band_center = 0x00; else
+       if (freq <=  137500) if_band_center = 0x01; else
+       if (freq <=  192500) if_band_center = 0x02; else
+       if (freq <=  247500) if_band_center = 0x03; else
+       if (freq <=  302500) if_band_center = 0x04; else
+       if (freq <=  357500) if_band_center = 0x05; else
+       if (freq <=  412500) if_band_center = 0x06; else
+       if (freq <=  467500) if_band_center = 0x07; else
+       if (freq <=  522500) if_band_center = 0x08; else
+       if (freq <=  577500) if_band_center = 0x09; else
+       if (freq <=  632500) if_band_center = 0x0A; else
+       if (freq <=  687500) if_band_center = 0x0B; else
+       if (freq <=  742500) if_band_center = 0x0C; else
+       if (freq <=  797500) if_band_center = 0x0D; else
+       if (freq <=  852500) if_band_center = 0x0E; else
+       if (freq <=  907500) if_band_center = 0x0F; else
+       if (freq <=  962500) if_band_center = 0x10; else
+       if (freq <= 1017500) if_band_center = 0x11; else
+       if (freq <= 1072500) if_band_center = 0x12; else if_band_center = 0x13;
+
+       b[0] = 1;
+       b[1] = (num1 >> 5) & 0xFF;
+       b[2] = (num1 & 0x1F);
+       b[3] = div1;
+       b[4] = (num2 >> 5) & 0xFF;
+       b[5] = num2 & 0x1F;
+       b[6] = div2;
+
+       dprintk(1, "IF1: %dMHz IF2: %dMHz\n", MT2131_IF1, MT2131_IF2);
+       dprintk(1, "PLL freq=%dkHz  band=%d\n", (int)freq, (int)if_band_center);
+       dprintk(1, "PLL f_lo1=%dkHz  f_lo2=%dkHz\n", (int)f_lo1, (int)f_lo2);
+       dprintk(1, "PLL div1=%d  num1=%d  div2=%d  num2=%d\n",
+               (int)div1, (int)num1, (int)div2, (int)num2);
+       dprintk(1, "PLL [1..6]: %2x %2x %2x %2x %2x %2x\n",
+               (int)b[1], (int)b[2], (int)b[3], (int)b[4], (int)b[5],
+               (int)b[6]);
+
+       ret = mt2131_writeregs(priv,b,7);
+       if (ret < 0)
+               return ret;
+
+       mt2131_writereg(priv, 0x0b, if_band_center);
+
+       /* Wait for lock */
+       i = 0;
+       do {
+               mt2131_readreg(priv, 0x08, &lockval);
+               if ((lockval & 0x88) == 0x88)
+                       break;
+               msleep(4);
+               i++;
+       } while (i < 10);
+
+       return ret;
+}
+
+static int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mt2131_priv *priv = fe->tuner_priv;
+       dprintk(1, "%s()\n", __FUNCTION__);
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int mt2131_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct mt2131_priv *priv = fe->tuner_priv;
+       dprintk(1, "%s()\n", __FUNCTION__);
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+static int mt2131_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct mt2131_priv *priv = fe->tuner_priv;
+       u8 lock_status = 0;
+       u8 afc_status = 0;
+
+       *status = 0;
+
+       mt2131_readreg(priv, 0x08, &lock_status);
+       if ((lock_status & 0x88) == 0x88)
+               *status = TUNER_STATUS_LOCKED;
+
+       mt2131_readreg(priv, 0x09, &afc_status);
+       dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n",
+               __FUNCTION__, lock_status, afc_status);
+
+       return 0;
+}
+
+static int mt2131_init(struct dvb_frontend *fe)
+{
+       struct mt2131_priv *priv = fe->tuner_priv;
+       int ret;
+       dprintk(1, "%s()\n", __FUNCTION__);
+
+       if ((ret = mt2131_writeregs(priv, mt2131_config1,
+                                   sizeof(mt2131_config1))) < 0)
+               return ret;
+
+       mt2131_writereg(priv, 0x0b, 0x09);
+       mt2131_writereg(priv, 0x15, 0x47);
+       mt2131_writereg(priv, 0x07, 0xf2);
+       mt2131_writereg(priv, 0x0b, 0x01);
+
+       if ((ret = mt2131_writeregs(priv, mt2131_config2,
+                                   sizeof(mt2131_config2))) < 0)
+               return ret;
+
+       return ret;
+}
+
+static int mt2131_release(struct dvb_frontend *fe)
+{
+       dprintk(1, "%s()\n", __FUNCTION__);
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static const struct dvb_tuner_ops mt2131_tuner_ops = {
+       .info = {
+               .name           = "Microtune MT2131",
+               .frequency_min  =  48000000,
+               .frequency_max  = 860000000,
+               .frequency_step =     50000,
+       },
+
+       .release       = mt2131_release,
+       .init          = mt2131_init,
+
+       .set_params    = mt2131_set_params,
+       .get_frequency = mt2131_get_frequency,
+       .get_bandwidth = mt2131_get_bandwidth,
+       .get_status    = mt2131_get_status
+};
+
+struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter *i2c,
+                                   struct mt2131_config *cfg, u16 if1)
+{
+       struct mt2131_priv *priv = NULL;
+       u8 id = 0;
+
+       dprintk(1, "%s()\n", __FUNCTION__);
+
+       priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg = cfg;
+       priv->bandwidth = 6000000; /* 6MHz */
+       priv->i2c = i2c;
+
+       if (mt2131_readreg(priv, 0, &id) != 0) {
+               kfree(priv);
+               return NULL;
+       }
+       if ( (id != 0x3E) && (id != 0x3F) ) {
+               printk(KERN_ERR "MT2131: Device not found at addr 0x%02x\n",
+                      cfg->i2c_address);
+               kfree(priv);
+               return NULL;
+       }
+
+       printk(KERN_INFO "MT2131: successfully identified at address 0x%02x\n",
+              cfg->i2c_address);
+       memcpy(&fe->ops.tuner_ops, &mt2131_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+       return fe;
+}
+EXPORT_SYMBOL(mt2131_attach);
+
+MODULE_AUTHOR("Steven Toth");
+MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/dvb/frontends/mt2131.h b/drivers/media/dvb/frontends/mt2131.h
new file mode 100644 (file)
index 0000000..1e4ffe7
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MT2131_H__
+#define __MT2131_H__
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mt2131_config {
+       u8 i2c_address;
+       u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
+};
+
+#if defined(CONFIG_DVB_TUNER_MT2131) || (defined(CONFIG_DVB_TUNER_MT2131_MODULE) && defined(MODULE))
+extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
+                                         struct i2c_adapter *i2c,
+                                         struct mt2131_config *cfg,
+                                         u16 if1);
+#else
+static inline struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
+                                                struct i2c_adapter *i2c,
+                                                struct mt2131_config *cfg,
+                                                u16 if1)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_TUNER_MT2131 */
+
+#endif /* __MT2131_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/dvb/frontends/mt2131_priv.h b/drivers/media/dvb/frontends/mt2131_priv.h
new file mode 100644 (file)
index 0000000..e930759
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MT2131_PRIV_H__
+#define __MT2131_PRIV_H__
+
+/* Regs */
+#define MT2131_PWR              0x07
+#define MT2131_UPC_1            0x0b
+#define MT2131_AGC_RL           0x10
+#define MT2131_MISC_2           0x15
+
+/* frequency values in KHz */
+#define MT2131_IF1              1220
+#define MT2131_IF2              44000
+#define MT2131_FREF             16000
+
+struct mt2131_priv {
+       struct mt2131_config *cfg;
+       struct i2c_adapter   *i2c;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+#endif /* __MT2131_PRIV_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/dvb/frontends/mt2266.c b/drivers/media/dvb/frontends/mt2266.c
new file mode 100644 (file)
index 0000000..03fe826
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ *  Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
+ *
+ *  Copyright (c) 2007 Olivier DANET <odanet@caramail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+#include "mt2266.h"
+
+#define I2C_ADDRESS 0x60
+
+#define REG_PART_REV   0
+#define REG_TUNE       1
+#define REG_BAND       6
+#define REG_BANDWIDTH  8
+#define REG_LOCK       0x12
+
+#define PART_REV 0x85
+
+struct mt2266_priv {
+       struct mt2266_config *cfg;
+       struct i2c_adapter   *i2c;
+
+       u32 frequency;
+       u32 bandwidth;
+};
+
+/* Here, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2266: " args); printk("\n"); }} while (0)
+
+// Reads a single register
+static int mt2266_readreg(struct mt2266_priv *priv, u8 reg, u8 *val)
+{
+       struct i2c_msg msg[2] = {
+               { .addr = priv->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
+               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val,  .len = 1 },
+       };
+       if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+               printk(KERN_WARNING "MT2266 I2C read failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Writes a single register
+static int mt2266_writereg(struct mt2266_priv *priv, u8 reg, u8 val)
+{
+       u8 buf[2] = { reg, val };
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
+       };
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "MT2266 I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Writes a set of consecutive registers
+static int mt2266_writeregs(struct mt2266_priv *priv,u8 *buf, u8 len)
+{
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
+       };
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               printk(KERN_WARNING "MT2266 I2C write failed (len=%i)\n",(int)len);
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+// Initialisation sequences
+static u8 mt2266_init1[] = {
+       REG_TUNE,
+       0x00, 0x00, 0x28, 0x00, 0x52, 0x99, 0x3f };
+
+static u8 mt2266_init2[] = {
+       0x17,                                     0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a,
+       0xd4, 0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x77, 0x0f, 0x2d };
+
+static u8 mt2266_init_8mhz[] = {
+       REG_BANDWIDTH,
+       0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 };
+
+static u8 mt2266_init_7mhz[] = {
+       REG_BANDWIDTH,
+       0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 };
+
+static u8 mt2266_init_6mhz[] = {
+       REG_BANDWIDTH,
+       0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7 };
+
+#define FREF 30000       // Quartz oscillator 30 MHz
+
+static int mt2266_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+       struct mt2266_priv *priv;
+       int ret=0;
+       u32 freq;
+       u32 tune;
+       u8  lnaband;
+       u8  b[10];
+       int i;
+
+       priv = fe->tuner_priv;
+
+       mt2266_writereg(priv,0x17,0x6d);
+       mt2266_writereg(priv,0x1c,0xff);
+
+       freq = params->frequency / 1000; // Hz -> kHz
+       priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
+       priv->frequency = freq * 1000;
+       tune=2 * freq * (8192/16) / (FREF/16);
+
+       if (freq <= 495000) lnaband = 0xEE; else
+       if (freq <= 525000) lnaband = 0xDD; else
+       if (freq <= 550000) lnaband = 0xCC; else
+       if (freq <= 580000) lnaband = 0xBB; else
+       if (freq <= 605000) lnaband = 0xAA; else
+       if (freq <= 630000) lnaband = 0x99; else
+       if (freq <= 655000) lnaband = 0x88; else
+       if (freq <= 685000) lnaband = 0x77; else
+       if (freq <= 710000) lnaband = 0x66; else
+       if (freq <= 735000) lnaband = 0x55; else
+       if (freq <= 765000) lnaband = 0x44; else
+       if (freq <= 802000) lnaband = 0x33; else
+       if (freq <= 840000) lnaband = 0x22; else lnaband = 0x11;
+
+       msleep(100);
+       mt2266_writeregs(priv,(params->u.ofdm.bandwidth==BANDWIDTH_6_MHZ)?mt2266_init_6mhz:
+                               (params->u.ofdm.bandwidth==BANDWIDTH_7_MHZ)?mt2266_init_7mhz:
+                               mt2266_init_8mhz,sizeof(mt2266_init_8mhz));
+
+       b[0] = REG_TUNE;
+       b[1] = (tune >> 8) & 0x1F;
+       b[2] = tune & 0xFF;
+       b[3] = tune >> 13;
+       mt2266_writeregs(priv,b,4);
+
+       dprintk("set_parms: tune=%d band=%d",(int)tune,(int)lnaband);
+       dprintk("set_parms: [1..3]: %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3]);
+
+       b[0] = 0x05;
+       b[1] = 0x62;
+       b[2] = lnaband;
+       mt2266_writeregs(priv,b,3);
+
+       //Waits for pll lock or timeout
+       i = 0;
+       do {
+               mt2266_readreg(priv,REG_LOCK,b);
+               if ((b[0] & 0x40)==0x40)
+                       break;
+               msleep(10);
+               i++;
+       } while (i<10);
+       dprintk("Lock when i=%i",(int)i);
+       return ret;
+}
+
+static void mt2266_calibrate(struct mt2266_priv *priv)
+{
+       mt2266_writereg(priv,0x11,0x03);
+       mt2266_writereg(priv,0x11,0x01);
+
+       mt2266_writeregs(priv,mt2266_init1,sizeof(mt2266_init1));
+       mt2266_writeregs(priv,mt2266_init2,sizeof(mt2266_init2));
+
+       mt2266_writereg(priv,0x33,0x5e);
+       mt2266_writereg(priv,0x10,0x10);
+       mt2266_writereg(priv,0x10,0x00);
+
+       mt2266_writeregs(priv,mt2266_init_8mhz,sizeof(mt2266_init_8mhz));
+
+       msleep(25);
+       mt2266_writereg(priv,0x17,0x6d);
+       mt2266_writereg(priv,0x1c,0x00);
+       msleep(75);
+       mt2266_writereg(priv,0x17,0x6d);
+       mt2266_writereg(priv,0x1c,0xff);
+}
+
+static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mt2266_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static int mt2266_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+       struct mt2266_priv *priv = fe->tuner_priv;
+       *bandwidth = priv->bandwidth;
+       return 0;
+}
+
+static int mt2266_init(struct dvb_frontend *fe)
+{
+       struct mt2266_priv *priv = fe->tuner_priv;
+       mt2266_writereg(priv,0x17,0x6d);
+       mt2266_writereg(priv,0x1c,0xff);
+       return 0;
+}
+
+static int mt2266_sleep(struct dvb_frontend *fe)
+{
+       struct mt2266_priv *priv = fe->tuner_priv;
+       mt2266_writereg(priv,0x17,0x6d);
+       mt2266_writereg(priv,0x1c,0x00);
+       return 0;
+}
+
+static int mt2266_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+       return 0;
+}
+
+static const struct dvb_tuner_ops mt2266_tuner_ops = {
+       .info = {
+               .name           = "Microtune MT2266",
+               .frequency_min  = 470000000,
+               .frequency_max  = 860000000,
+               .frequency_step =     50000,
+       },
+       .release       = mt2266_release,
+       .init          = mt2266_init,
+       .sleep         = mt2266_sleep,
+       .set_params    = mt2266_set_params,
+       .get_frequency = mt2266_get_frequency,
+       .get_bandwidth = mt2266_get_bandwidth
+};
+
+struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
+{
+       struct mt2266_priv *priv = NULL;
+       u8 id = 0;
+
+       priv = kzalloc(sizeof(struct mt2266_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg      = cfg;
+       priv->i2c      = i2c;
+
+       if (mt2266_readreg(priv,0,&id) != 0) {
+               kfree(priv);
+               return NULL;
+       }
+       if (id != PART_REV) {
+               kfree(priv);
+               return NULL;
+       }
+       printk(KERN_INFO "MT2266: successfully identified\n");
+       memcpy(&fe->ops.tuner_ops, &mt2266_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+       mt2266_calibrate(priv);
+       return fe;
+}
+EXPORT_SYMBOL(mt2266_attach);
+
+MODULE_AUTHOR("Olivier DANET");
+MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/mt2266.h b/drivers/media/dvb/frontends/mt2266.h
new file mode 100644 (file)
index 0000000..f31dd61
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
+ *
+ *  Copyright (c) 2007 Olivier DANET <odanet@caramail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+
+#ifndef MT2266_H
+#define MT2266_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mt2266_config {
+       u8 i2c_address;
+};
+
+#if defined(CONFIG_DVB_TUNER_MT2266) || (defined(CONFIG_DVB_TUNER_MT2266_MODULE) && defined(MODULE))
+extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg);
+#else
+static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+       return NULL;
+}
+#endif // CONFIG_DVB_TUNER_MT2266
+
+#endif
index 1ef821825641c1f725a17807f594d404f96e49b7..0606b9a5b616fff9558848c7aa5a2bc6e1e112b9 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 
index 87e31ca7e1084e9d7916468eb9038e0dae6d71a5..5dd9b731f6f29bdb10eee01122e2959613e4adde 100644 (file)
@@ -32,7 +32,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/string.h>
index ddc84899cf862f3b8834f90977fe84396e7ac8b2..fcf964fe1d6bebb2ca9f62847fdcfd67ee8d05b1 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 
index 3cc8b444b8f2d903b820c748b2db8e5821d313d8..b314a1f2deed4ed12e16390aea097f039bcbd966 100644 (file)
@@ -36,7 +36,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/string.h>
index f46d5a46683abd868bcc6d2827dce226e4a6e53b..f02bd94459556a6874a5d23d83afb28a6bfebc87 100644 (file)
@@ -32,7 +32,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/string.h>
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
new file mode 100644 (file)
index 0000000..30e8a70
--- /dev/null
@@ -0,0 +1,729 @@
+/*
+    Samsung S5H1409 VSB/QAM demodulator driver
+
+    Copyright (C) 2006 Steven Toth <stoth@hauppauge.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "dvb-pll.h"
+#include "s5h1409.h"
+
+struct s5h1409_state {
+
+       struct i2c_adapter* i2c;
+
+       /* configuration settings */
+       const struct s5h1409_config* config;
+
+       struct dvb_frontend frontend;
+
+       /* previous uncorrected block counter */
+       fe_modulation_t current_modulation;
+
+       u32 current_frequency;
+};
+
+static int debug = 0;
+#define dprintk        if (debug) printk
+
+/* Register values to initialise the demod, this will set VSB by default */
+static struct init_tab {
+       u8      reg;
+       u16     data;
+} init_tab[] = {
+       { 0x00, 0x0071, },
+       { 0x01, 0x3213, },
+       { 0x09, 0x0025, },
+       { 0x1c, 0x001d, },
+       { 0x1f, 0x002d, },
+       { 0x20, 0x001d, },
+       { 0x22, 0x0022, },
+       { 0x23, 0x0020, },
+       { 0x29, 0x110f, },
+       { 0x2a, 0x10b4, },
+       { 0x2b, 0x10ae, },
+       { 0x2c, 0x0031, },
+       { 0x31, 0x010d, },
+       { 0x32, 0x0100, },
+       { 0x44, 0x0510, },
+       { 0x54, 0x0104, },
+       { 0x58, 0x2222, },
+       { 0x59, 0x1162, },
+       { 0x5a, 0x3211, },
+       { 0x5d, 0x0370, },
+       { 0x5e, 0x0296, },
+       { 0x61, 0x0010, },
+       { 0x63, 0x4a00, },
+       { 0x65, 0x0800, },
+       { 0x71, 0x0003, },
+       { 0x72, 0x0470, },
+       { 0x81, 0x0002, },
+       { 0x82, 0x0600, },
+       { 0x86, 0x0002, },
+       { 0x8a, 0x2c38, },
+       { 0x8b, 0x2a37, },
+       { 0x92, 0x302f, },
+       { 0x93, 0x3332, },
+       { 0x96, 0x000c, },
+       { 0x99, 0x0101, },
+       { 0x9c, 0x2e37, },
+       { 0x9d, 0x2c37, },
+       { 0x9e, 0x2c37, },
+       { 0xab, 0x0100, },
+       { 0xac, 0x1003, },
+       { 0xad, 0x103f, },
+       { 0xe2, 0x0100, },
+       { 0x28, 0x1010, },
+       { 0xb1, 0x000e, },
+};
+
+/* VSB SNR lookup table */
+static struct vsb_snr_tab {
+       u16     val;
+       u16     data;
+} vsb_snr_tab[] = {
+       { 1023, 770, },
+       {  923, 300, },
+       {  918, 295, },
+       {  915, 290, },
+       {  911, 285, },
+       {  906, 280, },
+       {  901, 275, },
+       {  896, 270, },
+       {  891, 265, },
+       {  885, 260, },
+       {  879, 255, },
+       {  873, 250, },
+       {  864, 245, },
+       {  858, 240, },
+       {  850, 235, },
+       {  841, 230, },
+       {  832, 225, },
+       {  823, 220, },
+       {  812, 215, },
+       {  802, 210, },
+       {  788, 205, },
+       {  778, 200, },
+       {  767, 195, },
+       {  753, 190, },
+       {  740, 185, },
+       {  725, 180, },
+       {  707, 175, },
+       {  689, 170, },
+       {  671, 165, },
+       {  656, 160, },
+       {  637, 155, },
+       {  616, 150, },
+       {  542, 145, },
+       {  519, 140, },
+       {  507, 135, },
+       {  497, 130, },
+       {  492, 125, },
+       {  474, 120, },
+       {  300, 111, },
+       {    0,   0, },
+};
+
+/* QAM64 SNR lookup table */
+static struct qam64_snr_tab {
+       u16     val;
+       u16     data;
+} qam64_snr_tab[] = {
+       {   12, 300, },
+       {   15, 290, },
+       {   18, 280, },
+       {   22, 270, },
+       {   23, 268, },
+       {   24, 266, },
+       {   25, 264, },
+       {   27, 262, },
+       {   28, 260, },
+       {   29, 258, },
+       {   30, 256, },
+       {   32, 254, },
+       {   33, 252, },
+       {   34, 250, },
+       {   35, 249, },
+       {   36, 248, },
+       {   37, 247, },
+       {   38, 246, },
+       {   39, 245, },
+       {   40, 244, },
+       {   41, 243, },
+       {   42, 241, },
+       {   43, 240, },
+       {   44, 239, },
+       {   45, 238, },
+       {   46, 237, },
+       {   47, 236, },
+       {   48, 235, },
+       {   49, 234, },
+       {   50, 233, },
+       {   51, 232, },
+       {   52, 231, },
+       {   53, 230, },
+       {   55, 229, },
+       {   56, 228, },
+       {   57, 227, },
+       {   58, 226, },
+       {   59, 225, },
+       {   60, 224, },
+       {   62, 223, },
+       {   63, 222, },
+       {   65, 221, },
+       {   66, 220, },
+       {   68, 219, },
+       {   69, 218, },
+       {   70, 217, },
+       {   72, 216, },
+       {   73, 215, },
+       {   75, 214, },
+       {   76, 213, },
+       {   78, 212, },
+       {   80, 211, },
+       {   81, 210, },
+       {   83, 209, },
+       {   84, 208, },
+       {   85, 207, },
+       {   87, 206, },
+       {   89, 205, },
+       {   91, 204, },
+       {   93, 203, },
+       {   95, 202, },
+       {   96, 201, },
+       {  104, 200, },
+};
+
+/* QAM256 SNR lookup table */
+static struct qam256_snr_tab {
+       u16     val;
+       u16     data;
+} qam256_snr_tab[] = {
+       {   12, 400, },
+       {   13, 390, },
+       {   15, 380, },
+       {   17, 360, },
+       {   19, 350, },
+       {   22, 348, },
+       {   23, 346, },
+       {   24, 344, },
+       {   25, 342, },
+       {   26, 340, },
+       {   27, 336, },
+       {   28, 334, },
+       {   29, 332, },
+       {   30, 330, },
+       {   31, 328, },
+       {   32, 326, },
+       {   33, 325, },
+       {   34, 322, },
+       {   35, 320, },
+       {   37, 318, },
+       {   39, 316, },
+       {   40, 314, },
+       {   41, 312, },
+       {   42, 310, },
+       {   43, 308, },
+       {   46, 306, },
+       {   47, 304, },
+       {   49, 302, },
+       {   51, 300, },
+       {   53, 298, },
+       {   54, 297, },
+       {   55, 296, },
+       {   56, 295, },
+       {   57, 294, },
+       {   59, 293, },
+       {   60, 292, },
+       {   61, 291, },
+       {   63, 290, },
+       {   64, 289, },
+       {   65, 288, },
+       {   66, 287, },
+       {   68, 286, },
+       {   69, 285, },
+       {   71, 284, },
+       {   72, 283, },
+       {   74, 282, },
+       {   75, 281, },
+       {   76, 280, },
+       {   77, 279, },
+       {   78, 278, },
+       {   81, 277, },
+       {   83, 276, },
+       {   84, 275, },
+       {   86, 274, },
+       {   87, 273, },
+       {   89, 272, },
+       {   90, 271, },
+       {   92, 270, },
+       {   93, 269, },
+       {   95, 268, },
+       {   96, 267, },
+       {   98, 266, },
+       {  100, 265, },
+       {  102, 264, },
+       {  104, 263, },
+       {  105, 262, },
+       {  106, 261, },
+       {  110, 260, },
+};
+
+/* 8 bit registers, 16 bit values */
+static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data)
+{
+       int ret;
+       u8 buf [] = { reg, data >> 8,  data & 0xff };
+
+       struct i2c_msg msg = { .addr = state->config->demod_address,
+                              .flags = 0, .buf = buf, .len = 3 };
+
+       ret = i2c_transfer(state->i2c, &msg, 1);
+
+       if (ret != 1)
+               printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
+                      "ret == %i)\n", __FUNCTION__, reg, data, ret);
+
+       return (ret != 1) ? -1 : 0;
+}
+
+static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg)
+{
+       int ret;
+       u8 b0 [] = { reg };
+       u8 b1 [] = { 0, 0 };
+
+       struct i2c_msg msg [] = {
+               { .addr = state->config->demod_address, .flags = 0,
+                 .buf = b0, .len = 1 },
+               { .addr = state->config->demod_address, .flags = I2C_M_RD,
+                 .buf = b1, .len = 2 } };
+
+       ret = i2c_transfer(state->i2c, msg, 2);
+
+       if (ret != 2)
+               printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
+       return (b1[0] << 8) | b1[1];
+}
+
+static int s5h1409_softreset(struct dvb_frontend* fe)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+
+       dprintk("%s()\n", __FUNCTION__);
+
+       s5h1409_writereg(state, 0xf5, 0);
+       s5h1409_writereg(state, 0xf5, 1);
+       return 0;
+}
+
+static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+       int ret = 0;
+
+       dprintk("%s(%d KHz)\n", __FUNCTION__, KHz);
+
+       if( (KHz == 44000) || (KHz == 5380) ) {
+               s5h1409_writereg(state, 0x87, 0x01be);
+               s5h1409_writereg(state, 0x88, 0x0436);
+               s5h1409_writereg(state, 0x89, 0x054d);
+       } else {
+               printk("%s() Invalid arg = %d KHz\n", __FUNCTION__, KHz);
+               ret = -1;
+       }
+
+       return ret;
+}
+
+static int s5h1409_set_spectralinversion(struct dvb_frontend* fe, int inverted)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+
+       dprintk("%s()\n", __FUNCTION__);
+
+       if(inverted == 1)
+               return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */
+       else
+               return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */
+}
+
+static int s5h1409_enable_modulation(struct dvb_frontend* fe,
+                                    fe_modulation_t m)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+
+       dprintk("%s(0x%08x)\n", __FUNCTION__, m);
+
+       switch(m) {
+       case VSB_8:
+               dprintk("%s() VSB_8\n", __FUNCTION__);
+               s5h1409_writereg(state, 0xf4, 0);
+               break;
+       case QAM_64:
+               dprintk("%s() QAM_64\n", __FUNCTION__);
+               s5h1409_writereg(state, 0xf4, 1);
+               s5h1409_writereg(state, 0x85, 0x100);
+               break;
+       case QAM_256:
+               dprintk("%s() QAM_256\n", __FUNCTION__);
+               s5h1409_writereg(state, 0xf4, 1);
+               s5h1409_writereg(state, 0x85, 0x101);
+               break;
+       default:
+               dprintk("%s() Invalid modulation\n", __FUNCTION__);
+               return -EINVAL;
+       }
+
+       state->current_modulation = m;
+       s5h1409_softreset(fe);
+
+       return 0;
+}
+
+static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+
+       dprintk("%s(%d)\n", __FUNCTION__, enable);
+
+       if (enable)
+               return s5h1409_writereg(state, 0xf3, 1);
+       else
+               return s5h1409_writereg(state, 0xf3, 0);
+}
+
+static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+
+       dprintk("%s(%d)\n", __FUNCTION__, enable);
+
+       if (enable)
+               return s5h1409_writereg(state, 0xe3, 0x1100);
+       else
+               return s5h1409_writereg(state, 0xe3, 0);
+}
+
+static int s5h1409_sleep(struct dvb_frontend* fe, int enable)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+
+       dprintk("%s(%d)\n", __FUNCTION__, enable);
+
+       return s5h1409_writereg(state, 0xf2, enable);
+}
+
+static int s5h1409_register_reset(struct dvb_frontend* fe)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+
+       dprintk("%s()\n", __FUNCTION__);
+
+       return s5h1409_writereg(state, 0xfa, 0);
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+static int s5h1409_set_frontend (struct dvb_frontend* fe,
+                                struct dvb_frontend_parameters *p)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+
+       dprintk("%s(frequency=%d)\n", __FUNCTION__, p->frequency);
+
+       s5h1409_softreset(fe);
+
+       state->current_frequency = p->frequency;
+
+       s5h1409_enable_modulation(fe, p->u.vsb.modulation);
+
+       if (fe->ops.tuner_ops.set_params) {
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1);
+               fe->ops.tuner_ops.set_params(fe, p);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
+
+       return 0;
+}
+
+/* Reset the demod hardware and reset all of the configuration registers
+   to a default state. */
+static int s5h1409_init (struct dvb_frontend* fe)
+{
+       int i;
+
+       struct s5h1409_state* state = fe->demodulator_priv;
+       dprintk("%s()\n", __FUNCTION__);
+
+       s5h1409_sleep(fe, 0);
+       s5h1409_register_reset(fe);
+
+       for (i=0; i < ARRAY_SIZE(init_tab); i++)
+               s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data);
+
+       /* The datasheet says that after initialisation, VSB is default */
+       state->current_modulation = VSB_8;
+
+       if (state->config->output_mode == S5H1409_SERIAL_OUTPUT)
+               s5h1409_writereg(state, 0xab, 0x100); /* Serial */
+       else
+               s5h1409_writereg(state, 0xab, 0x0); /* Parallel */
+
+       s5h1409_set_spectralinversion(fe, state->config->inversion);
+       s5h1409_set_if_freq(fe, state->config->if_freq);
+       s5h1409_set_gpio(fe, state->config->gpio);
+       s5h1409_softreset(fe);
+
+       /* Note: Leaving the I2C gate open here. */
+       s5h1409_i2c_gate_ctrl(fe, 1);
+
+       return 0;
+}
+
+static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+       u16 reg;
+       u32 tuner_status = 0;
+
+       *status = 0;
+
+       /* Get the demodulator status */
+       reg = s5h1409_readreg(state, 0xf1);
+       if(reg & 0x1000)
+               *status |= FE_HAS_VITERBI;
+       if(reg & 0x8000)
+               *status |= FE_HAS_LOCK | FE_HAS_SYNC;
+
+       switch(state->config->status_mode) {
+       case S5H1409_DEMODLOCKING:
+               if (*status & FE_HAS_VITERBI)
+                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+               break;
+       case S5H1409_TUNERLOCKING:
+               /* Get the tuner status */
+               if (fe->ops.tuner_ops.get_status) {
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 1);
+
+                       fe->ops.tuner_ops.get_status(fe, &tuner_status);
+
+                       if (fe->ops.i2c_gate_ctrl)
+                               fe->ops.i2c_gate_ctrl(fe, 0);
+               }
+               if (tuner_status)
+                       *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+               break;
+       }
+
+       dprintk("%s() status 0x%08x\n", __FUNCTION__, *status);
+
+       return 0;
+}
+
+static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
+{
+       int i, ret = -EINVAL;
+       dprintk("%s()\n", __FUNCTION__);
+
+       for (i=0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
+               if (v < qam256_snr_tab[i].val) {
+                       *snr = qam256_snr_tab[i].data;
+                       ret = 0;
+                       break;
+               }
+       }
+       return ret;
+}
+
+static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
+{
+       int i, ret = -EINVAL;
+       dprintk("%s()\n", __FUNCTION__);
+
+       for (i=0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
+               if (v < qam64_snr_tab[i].val) {
+                       *snr = qam64_snr_tab[i].data;
+                       ret = 0;
+                       break;
+               }
+       }
+       return ret;
+}
+
+static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
+{
+       int i, ret = -EINVAL;
+       dprintk("%s()\n", __FUNCTION__);
+
+       for (i=0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
+               if (v > vsb_snr_tab[i].val) {
+                       *snr = vsb_snr_tab[i].data;
+                       ret = 0;
+                       break;
+               }
+       }
+       dprintk("%s() snr=%d\n", __FUNCTION__, *snr);
+       return ret;
+}
+
+static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+       u16 reg;
+       dprintk("%s()\n", __FUNCTION__);
+
+       reg = s5h1409_readreg(state, 0xf1) & 0x1ff;
+
+       switch(state->current_modulation) {
+       case QAM_64:
+               return s5h1409_qam64_lookup_snr(fe, snr, reg);
+       case QAM_256:
+               return s5h1409_qam256_lookup_snr(fe, snr, reg);
+       case VSB_8:
+               return s5h1409_vsb_lookup_snr(fe, snr, reg);
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int s5h1409_read_signal_strength(struct dvb_frontend* fe,
+                                       u16* signal_strength)
+{
+       return s5h1409_read_snr(fe, signal_strength);
+}
+
+static int s5h1409_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+
+       *ucblocks = s5h1409_readreg(state, 0xb5);
+
+       return 0;
+}
+
+static int s5h1409_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+       return s5h1409_read_ucblocks(fe, ber);
+}
+
+static int s5h1409_get_frontend(struct dvb_frontend* fe,
+                               struct dvb_frontend_parameters *p)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+
+       p->frequency = state->current_frequency;
+       p->u.vsb.modulation = state->current_modulation;
+
+       return 0;
+}
+
+static int s5h1409_get_tune_settings(struct dvb_frontend* fe,
+                                    struct dvb_frontend_tune_settings *tune)
+{
+       tune->min_delay_ms = 1000;
+       return 0;
+}
+
+static void s5h1409_release(struct dvb_frontend* fe)
+{
+       struct s5h1409_state* state = fe->demodulator_priv;
+       kfree(state);
+}
+
+static struct dvb_frontend_ops s5h1409_ops;
+
+struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
+                                   struct i2c_adapter* i2c)
+{
+       struct s5h1409_state* state = NULL;
+
+       /* allocate memory for the internal state */
+       state = kmalloc(sizeof(struct s5h1409_state), GFP_KERNEL);
+       if (state == NULL)
+               goto error;
+
+       /* setup the state */
+       state->config = config;
+       state->i2c = i2c;
+       state->current_modulation = 0;
+
+       /* check if the demod exists */
+       if (s5h1409_readreg(state, 0x04) != 0x0066)
+               goto error;
+
+       /* create dvb_frontend */
+       memcpy(&state->frontend.ops, &s5h1409_ops,
+              sizeof(struct dvb_frontend_ops));
+       state->frontend.demodulator_priv = state;
+
+       /* Note: Leaving the I2C gate open here. */
+       s5h1409_writereg(state, 0xf3, 1);
+
+       return &state->frontend;
+
+error:
+       kfree(state);
+       return NULL;
+}
+
+static struct dvb_frontend_ops s5h1409_ops = {
+
+       .info = {
+               .name                   = "Samsung S5H1409 QAM/8VSB Frontend",
+               .type                   = FE_ATSC,
+               .frequency_min          = 54000000,
+               .frequency_max          = 858000000,
+               .frequency_stepsize     = 62500,
+               .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+       },
+
+       .init                 = s5h1409_init,
+       .i2c_gate_ctrl        = s5h1409_i2c_gate_ctrl,
+       .set_frontend         = s5h1409_set_frontend,
+       .get_frontend         = s5h1409_get_frontend,
+       .get_tune_settings    = s5h1409_get_tune_settings,
+       .read_status          = s5h1409_read_status,
+       .read_ber             = s5h1409_read_ber,
+       .read_signal_strength = s5h1409_read_signal_strength,
+       .read_snr             = s5h1409_read_snr,
+       .read_ucblocks        = s5h1409_read_ucblocks,
+       .release              = s5h1409_release,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(s5h1409_attach);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h
new file mode 100644 (file)
index 0000000..20f9af1
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+    Samsung S5H1409 VSB/QAM demodulator driver
+
+    Copyright (C) 2006 Steven Toth <stoth@hauppauge.com>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __S5H1409_H__
+#define __S5H1409_H__
+
+#include <linux/dvb/frontend.h>
+
+struct s5h1409_config
+{
+       /* the demodulator's i2c address */
+       u8 demod_address;
+
+       /* serial/parallel output */
+#define S5H1409_PARALLEL_OUTPUT 0
+#define S5H1409_SERIAL_OUTPUT   1
+       u8 output_mode;
+
+       /* GPIO Setting */
+#define S5H1409_GPIO_OFF 0
+#define S5H1409_GPIO_ON  1
+       u8 gpio;
+
+       /* IF Freq in KHz */
+       u16 if_freq;
+
+       /* Spectral Inversion */
+#define S5H1409_INVERSION_OFF 0
+#define S5H1409_INVERSION_ON  1
+       u8 inversion;
+
+       /* Return lock status based on tuner lock, or demod lock */
+#define S5H1409_TUNERLOCKING 0
+#define S5H1409_DEMODLOCKING 1
+       u8 status_mode;
+};
+
+#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) && defined(MODULE))
+extern struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
+                                          struct i2c_adapter* i2c);
+#else
+static inline struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
+                                                 struct i2c_adapter* i2c)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+       return NULL;
+}
+#endif /* CONFIG_DVB_S5H1409 */
+
+#endif /* __S5H1409_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
index d98fd5c2e13e12e6a1dc1f17253e4f4d7de71143..da876f7bfe32b045595a568297c77c3f79aed534 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/delay.h>
index 5c2f8f4e0ae554873a9ba9b8f1443070422b72d7..1aa2539f5099b7528afb1cde568d48c97c0d1d9f 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/string.h>
index 9a343972ff50589c5a5fed69f78bd03a0ad8a270..17e5cb561cd8569a77752f0a3df7984648f056d3 100644 (file)
@@ -680,8 +680,8 @@ static struct dvb_frontend_ops stv0297_ops = {
        .info = {
                 .name = "ST STV0297 DVB-C",
                 .type = FE_QAM,
-                .frequency_min = 64000000,
-                .frequency_max = 1300000000,
+                .frequency_min = 47000000,
+                .frequency_max = 862000000,
                 .frequency_stepsize = 62500,
                 .symbol_rate_min = 870000,
                 .symbol_rate_max = 11700000,
index 6c607302c1b6c3d08b73015f9312786bcd019105..035dd7ba65194577aec5a8b52f30bfccfe14779c 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
index e725f612a6b72c2b8d34965297aac2b73dc8e62e..4cd9e82c4669fd857eb07d37981c2483e12f876c 100644 (file)
@@ -439,8 +439,8 @@ static struct dvb_frontend_ops tda10021_ops = {
                .name = "Philips TDA10021 DVB-C",
                .type = FE_QAM,
                .frequency_stepsize = 62500,
-               .frequency_min = 51000000,
-               .frequency_max = 858000000,
+               .frequency_min = 47000000,
+               .frequency_max = 862000000,
                .symbol_rate_min = (XIN/2)/64,     /* SACLK/64 == (XIN/2)/64 */
                .symbol_rate_max = (XIN/2)/4,      /* SACLK/4 */
        #if 0
index 4bb06f97938b8638cfca51a85bf21d17af14dbdc..364bc01971a0c7c4071ac98d0fd9f6e5e86fced8 100644 (file)
@@ -215,12 +215,6 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
        s16 SFIL=0;
        u16 NDEC = 0;
 
-       if (sr > (SYSCLK/(2*4)))
-               sr=SYSCLK/(2*4);
-
-       if (sr<870000)
-               sr=870000;
-
        if (sr < (u32)(SYSCLK/98.40)) {
                NDEC=3;
                SFIL=1;
@@ -506,8 +500,8 @@ static struct dvb_frontend_ops tda10023_ops = {
                .name = "Philips TDA10023 DVB-C",
                .type = FE_QAM,
                .frequency_stepsize = 62500,
-               .frequency_min = 51000000,
-               .frequency_max = 858000000,
+               .frequency_min = 47000000,
+               .frequency_max = 862000000,
                .symbol_rate_min = (SYSCLK/2)/64,     /* SACLK/64 == (SYSCLK/2)/64 */
                .symbol_rate_max = (SYSCLK/2)/4,      /* SACLK/4 */
                .caps = 0x400 | //FE_CAN_QAM_4
index 33a84372c9e6ce079b3bacb9104e37b73c77b1ab..8415a8a5247a09381f196ead24b4935d5b680c73 100644 (file)
@@ -31,7 +31,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/jiffies.h>
 #include <linux/string.h>
index 0f2d4b415560f75fdc1132de3ae68c6f82e4628b..9a8ddc537f8f338d9c055d186321a499d66e1b4c 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/device.h>
 #include <linux/jiffies.h>
 #include <linux/string.h>
index 67415c9db6f7ae180095355858b45045ad9829b7..011b74f798a031207fbe71eb7313c106b377bf73 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
@@ -443,12 +442,12 @@ static struct dvb_frontend_ops tda8083_ops = {
        .info = {
                .name                   = "Philips TDA8083 DVB-S",
                .type                   = FE_QPSK,
-               .frequency_min          = 950000,     /* FIXME: guessed! */
-               .frequency_max          = 1400000,    /* FIXME: guessed! */
+               .frequency_min          = 920000,     /* TDA8060 */
+               .frequency_max          = 2200000,    /* TDA8060 */
                .frequency_stepsize     = 125,   /* kHz for QPSK frontends */
        /*      .frequency_tolerance    = ???,*/
-               .symbol_rate_min        = 1000000,   /* FIXME: guessed! */
-               .symbol_rate_max        = 45000000,  /* FIXME: guessed! */
+               .symbol_rate_min        = 12000000,
+               .symbol_rate_max        = 30000000,
        /*      .symbol_rate_tolerance  = ???,*/
                .caps = FE_CAN_INVERSION_AUTO |
                        FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
index 9b57576bfeb411738495687aa490a3460bfc3f1b..066b73b75698e88e674ab4f0534b3e76835fc1f7 100644 (file)
@@ -410,8 +410,8 @@ static struct dvb_frontend_ops ves1820_ops = {
                .name = "VLSI VES1820 DVB-C",
                .type = FE_QAM,
                .frequency_stepsize = 62500,
-               .frequency_min = 51000000,
-               .frequency_max = 858000000,
+               .frequency_min = 47000000,
+               .frequency_max = 862000000,
                .caps = FE_CAN_QAM_16 |
                        FE_CAN_QAM_32 |
                        FE_CAN_QAM_64 |
index 245f9b7dddfa58cb6d4476bbb904755bd9216ca4..a97a7fd2c89132a596027619d8e3e9fbfedc6be9 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/string.h>
index 8178832d14a809dd55b3866df2088571a1a36ef5..8b8144f77a739b7637ce5c9de526c199a3daf389 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/smp_lock.h>
 
 #include <linux/kernel.h>
-#include <linux/moduleparam.h>
 #include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
@@ -1543,7 +1542,7 @@ static int get_firmware(struct av7110* av7110)
        }
 
        /* check if the firmware is available */
-       av7110->bin_fw = (unsigned char *) vmalloc(fw->size);
+       av7110->bin_fw = vmalloc(fw->size);
        if (NULL == av7110->bin_fw) {
                dprintk(1, "out of memory\n");
                release_firmware(fw);
index 515e8232e0203e0d31240c380752886a91ea817c..a468aa2e485475ba5583765b0e643781943f4ae1 100644 (file)
@@ -978,24 +978,24 @@ static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 ble
 
 static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
 {
-       int i;
-       int length = last - first + 1;
+       int i;
+       int length = last - first + 1;
 
-       if (length * 4 > DATA_BUFF3_SIZE)
-              return -EINVAL;
+       if (length * 4 > DATA_BUFF3_SIZE)
+               return -EINVAL;
 
-       for (i = 0; i < length; i++) {
-              u32 color, blend, yuv;
+       for (i = 0; i < length; i++) {
+               u32 color, blend, yuv;
 
-              if (get_user(color, colors + i))
-                      return -EFAULT;
-              blend = (color & 0xF0000000) >> 4;
-              yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF,
+               if (get_user(color, colors + i))
+                       return -EFAULT;
+               blend = (color & 0xF0000000) >> 4;
+               yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF,
                                     (color >> 16) & 0xFF) | blend : 0;
-              yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16);
-              wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4);
-       }
-       return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Palette, 4,
+               yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16);
+               wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4);
+       }
+       return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Palette, 4,
                            av7110->osdwin,
                            bpp2pal[av7110->osdbpp[av7110->osdwin]],
                            first, last);
index 6322800ee12b9bef96519113c912af47e32d8105..5d19c402dad13fbf8096aa05147f28f684d93258 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/proc_fs.h>
 #include <linux/kernel.h>
 #include <asm/bitops.h>
@@ -280,7 +279,7 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
        if (count < size)
                return -EINVAL;
 
-       page = (char *) vmalloc(size);
+       page = vmalloc(size);
        if (!page)
                return -ENOMEM;
 
index 87afaebc07032721ba6a70e5f41e13bfc3b318a5..76cca003252fdf6c69e5274651a0428aae4100fd 100644 (file)
@@ -129,23 +129,25 @@ static struct v4l2_input inputs[4] = {
 
 static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
 {
+       struct av7110 *av7110 = dev->ext_priv;
        u8 buf[] = { 0x00, reg, data };
        struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
 
        dprintk(4, "dev: %p\n", dev);
 
-       if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
+       if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1))
                return -1;
        return 0;
 }
 
 static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
 {
+       struct av7110 *av7110 = dev->ext_priv;
        struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
 
        dprintk(4, "dev: %p\n", dev);
 
-       if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
+       if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1))
                return -1;
        return 0;
 }
index 0aee7a13a070f4fdcf87f24339030a10bf46a547..3439c9864f67084e538239f2b3ba316b3a165b16 100644 (file)
@@ -1232,7 +1232,7 @@ static struct saa7146_ext_vv vv_data = {
        .capabilities = 0,      // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
        .flags = 0,
        .stds = &standard[0],
-       .num_stds = sizeof(standard) / sizeof(struct saa7146_standard),
+       .num_stds = ARRAY_SIZE(standard),
        .ioctls = &ioctls[0],
        .ioctl = av_ioctl,
 };
index 873c3ba296f25688925172921bd8b4e79de3767e..509349211d4fc40594fb99a27980eeed2ae66e31 100644 (file)
@@ -214,7 +214,6 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
        case 0x100f:
        case 0x1011:
        case 0x1012:
-       case 0x1017:
                /* The hauppauge keymap is a superset of these remotes */
                ir_input_init(input_dev, &budget_ci->ir.state,
                              IR_TYPE_RC5, ir_codes_hauppauge_new);
@@ -225,6 +224,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
                        budget_ci->ir.rc5_device = rc5_device;
                break;
        case 0x1010:
+       case 0x1017:
                /* for the Technotrend 1500 bundled remote */
                ir_input_init(input_dev, &budget_ci->ir.state,
                              IR_TYPE_RC5, ir_codes_tt_1500);
index b611f2b1f8bc48602be277a84e61edb8cb31fd6c..0252081f013c56d86d3217d37c5a586f67c7da6e 100644 (file)
@@ -34,7 +34,6 @@
  * the project's page is at http://www.linuxtv.org/dvb/
  */
 
-#include <linux/moduleparam.h>
 
 #include "budget.h"
 #include "ttpci-eeprom.h"
index b60cdc93d6dbddab7031a69128acb3114c5f9852..288e79f2cb0f9fba41f29fdc7b940edfe9489bef 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/usb.h>
 #include <linux/delay.h>
 #include <linux/time.h>
index 78c98b0899759d48f33174e152e3a0ae3fbb29ef..5e691fd79904e98cbbc8cc5b9a6ddacf1b6d0658 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
index f8bf9fe37d36a57ce135f958704dcb20aaf073ac..11e962f1a97f955f9d6504fb4b88af522ac5a11a 100644 (file)
@@ -111,11 +111,16 @@ config RADIO_AZTECH_PORT
          jumper sets the card to 0x358.
 
 config RADIO_GEMTEK
-       tristate "GemTek Radio Card support"
+       tristate "GemTek Radio card (or compatible) support"
        depends on ISA && VIDEO_V4L2
        ---help---
          Choose Y here if you have this FM radio card, and then fill in the
-         port address below.
+         I/O port address and settings below. The following cards either have
+         GemTek Radio tuner or are rebranded GemTek Radio cards:
+
+         - Sound Vision 16 Gold with FM Radio
+         - Typhoon Radio card (some models)
+         - Hama Radio card
 
          In order to control your radio card, you will need to use programs
          that are compatible with the Video For Linux API.  Information on
@@ -126,14 +131,25 @@ config RADIO_GEMTEK
          module will be called radio-gemtek.
 
 config RADIO_GEMTEK_PORT
-       hex "GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)"
+       hex "Fixed I/O port (0x20c, 0x30c, 0x24c, 0x34c, 0c24c or 0x28c)"
        depends on RADIO_GEMTEK=y
        default "34c"
        help
          Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is
          0x34c, if you haven't changed the jumper setting on the card. On
          Sound Vision 16 Gold PnP with FM Radio (ESS1869+FM Gemtek), the I/O
-         port is 0x28c.
+         port is 0x20c, 0x248 or 0x28c.
+         If automatic I/O port probing is enabled this port will be used only
+         in case of automatic probing failure, ie. as a fallback.
+
+config RADIO_GEMTEK_PROBE
+       bool "Automatic I/O port probing"
+       depends on RADIO_GEMTEK=y
+       default y
+       help
+         Say Y here to enable automatic probing for GemTek Radio card. The
+         following ports will be probed: 0x20c, 0x30c, 0x24c, 0x34c, 0x248 and
+         0x28c.
 
 config RADIO_GEMTEK_PCI
        tristate "GemTek PCI Radio Card support"
index eab8c80a2e47db0665b61fdbbfec5ba8041f2cc2..0c963db03614b4232e002f2b1e0e3ebd5da6feaa 100644 (file)
 #include <media/v4l2-common.h>
 #include <linux/spinlock.h>
 
-#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+#include <linux/version.h>     /* for KERNEL_VERSION MACRO     */
+#define RADIO_VERSION KERNEL_VERSION(0,0,3)
+#define RADIO_BANNER "GemTek Radio card driver: v0.0.3"
 
-static struct v4l2_queryctrl radio_qctrl[] = {
-       {
-               .id            = V4L2_CID_AUDIO_MUTE,
-               .name          = "Mute",
-               .minimum       = 0,
-               .maximum       = 1,
-               .default_value = 1,
-               .type          = V4L2_CTRL_TYPE_BOOLEAN,
-       },{
-               .id            = V4L2_CID_AUDIO_VOLUME,
-               .name          = "Volume",
-               .minimum       = 0,
-               .maximum       = 65535,
-               .step          = 65535,
-               .default_value = 0xff,
-               .type          = V4L2_CTRL_TYPE_INTEGER,
-       }
-};
+/*
+ * Module info.
+ */
+
+MODULE_AUTHOR("Jonas Munsin, Pekka Seppänen <pexu@kapsi.fi>");
+MODULE_DESCRIPTION("A driver for the GemTek Radio card.");
+MODULE_LICENSE("GPL");
+
+/*
+ * Module params.
+ */
 
 #ifndef CONFIG_RADIO_GEMTEK_PORT
 #define CONFIG_RADIO_GEMTEK_PORT -1
 #endif
+#ifndef CONFIG_RADIO_GEMTEK_PROBE
+#define CONFIG_RADIO_GEMTEK_PROBE 1
+#endif
 
-static int io = CONFIG_RADIO_GEMTEK_PORT;
-static int radio_nr = -1;
-static spinlock_t lock;
+static int io          = CONFIG_RADIO_GEMTEK_PORT;
+static int probe       = CONFIG_RADIO_GEMTEK_PROBE;
+static int hardmute;
+static int shutdown    = 1;
+static int keepmuted   = 1;
+static int initmute    = 1;
+static int radio_nr    = -1;
 
-struct gemtek_device
-{
-       int port;
-       unsigned long curfreq;
+module_param(io, int, 0444);
+MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic"
+        "probing is disabled or fails. The most common I/O ports are: 0x20c "
+        "0x30c, 0x24c or 0x34c (0x20c, 0x248 and 0x28c have been reported to "
+        " work for the combined sound/radiocard).");
+
+module_param(probe, bool, 0444);
+MODULE_PARM_DESC(probe, "Enable automatic device probing. Note: only the most "
+       "common I/O ports used by the card are probed.");
+
+module_param(hardmute, bool, 0644);
+MODULE_PARM_DESC(hardmute, "Enable `hard muting' by shutting down PLL, may "
+        "reduce static noise.");
+
+module_param(shutdown, bool, 0644);
+MODULE_PARM_DESC(shutdown, "Enable shutting down PLL and muting line when "
+        "module is unloaded.");
+
+module_param(keepmuted, bool, 0644);
+MODULE_PARM_DESC(keepmuted, "Keep card muted even when frequency is changed.");
+
+module_param(initmute, bool, 0444);
+MODULE_PARM_DESC(initmute, "Mute card when module is loaded.");
+
+module_param(radio_nr, int, 0444);
+
+/*
+ * Functions for controlling the card.
+ */
+#define GEMTEK_LOWFREQ (87*16000)
+#define GEMTEK_HIGHFREQ        (108*16000)
+
+/*
+ * Frequency calculation constants.  Intermediate frequency 10.52 MHz (nominal
+ * value 10.7 MHz), reference divisor 6.39 kHz (nominal 6.25 kHz).
+ */
+#define FSCALE         8
+#define IF_OFFSET      ((unsigned int)(10.52 * 16000 * (1<<FSCALE)))
+#define REF_FREQ       ((unsigned int)(6.39 * 16 * (1<<FSCALE)))
+
+#define GEMTEK_CK              0x01    /* Clock signal                 */
+#define GEMTEK_DA              0x02    /* Serial data                  */
+#define GEMTEK_CE              0x04    /* Chip enable                  */
+#define GEMTEK_NS              0x08    /* No signal                    */
+#define GEMTEK_MT              0x10    /* Line mute                    */
+#define GEMTEK_STDF_3_125_KHZ  0x01    /* Standard frequency 3.125 kHz */
+#define GEMTEK_PLL_OFF         0x07    /* PLL off                      */
+
+#define BU2614_BUS_SIZE        32      /* BU2614 / BU2614FS bus size           */
+
+#define SHORT_DELAY 5          /* usec */
+#define LONG_DELAY 75          /* usec */
+
+struct gemtek_device {
+       unsigned long lastfreq;
        int muted;
+       u32 bu2614data;
 };
 
+#define BU2614_FREQ_BITS       16 /* D0..D15, Frequency data           */
+#define BU2614_PORT_BITS       3 /* P0..P2, Output port control data   */
+#define BU2614_VOID_BITS       4 /* unused                             */
+#define BU2614_FMES_BITS       1 /* CT, Frequency measurement beginning data */
+#define BU2614_STDF_BITS       3 /* R0..R2, Standard frequency data    */
+#define BU2614_SWIN_BITS       1 /* S, Switch between FMIN / AMIN      */
+#define BU2614_SWAL_BITS        1 /* PS, Swallow counter division (AMIN only)*/
+#define BU2614_VOID2_BITS      1 /* unused                             */
+#define BU2614_FMUN_BITS       1 /* GT, Frequency measurement time & unlock */
+#define BU2614_TEST_BITS       1 /* TS, Test data is input             */
+
+#define BU2614_FREQ_SHIFT      0
+#define BU2614_PORT_SHIFT      (BU2614_FREQ_BITS + BU2614_FREQ_SHIFT)
+#define BU2614_VOID_SHIFT      (BU2614_PORT_BITS + BU2614_PORT_SHIFT)
+#define BU2614_FMES_SHIFT      (BU2614_VOID_BITS + BU2614_VOID_SHIFT)
+#define BU2614_STDF_SHIFT      (BU2614_FMES_BITS + BU2614_FMES_SHIFT)
+#define BU2614_SWIN_SHIFT      (BU2614_STDF_BITS + BU2614_STDF_SHIFT)
+#define BU2614_SWAL_SHIFT      (BU2614_SWIN_BITS + BU2614_SWIN_SHIFT)
+#define BU2614_VOID2_SHIFT     (BU2614_SWAL_BITS + BU2614_SWAL_SHIFT)
+#define BU2614_FMUN_SHIFT      (BU2614_VOID2_BITS + BU2614_VOID2_SHIFT)
+#define BU2614_TEST_SHIFT      (BU2614_FMUN_BITS + BU2614_FMUN_SHIFT)
+
+#define MKMASK(field)  (((1<<BU2614_##field##_BITS) - 1) << \
+                       BU2614_##field##_SHIFT)
+#define BU2614_PORT_MASK       MKMASK(PORT)
+#define BU2614_FREQ_MASK       MKMASK(FREQ)
+#define BU2614_VOID_MASK       MKMASK(VOID)
+#define BU2614_FMES_MASK       MKMASK(FMES)
+#define BU2614_STDF_MASK       MKMASK(STDF)
+#define BU2614_SWIN_MASK       MKMASK(SWIN)
+#define BU2614_SWAL_MASK       MKMASK(SWAL)
+#define BU2614_VOID2_MASK      MKMASK(VOID2)
+#define BU2614_FMUN_MASK       MKMASK(FMUN)
+#define BU2614_TEST_MASK       MKMASK(TEST)
 
-/* local things */
+static struct gemtek_device gemtek_unit;
 
-/* the correct way to mute the gemtek may be to write the last written
- * frequency || 0x10, but just writing 0x10 once seems to do it as well
+static spinlock_t lock;
+
+/*
+ * Set data which will be sent to BU2614FS.
  */
-static void gemtek_mute(struct gemtek_device *dev)
+#define gemtek_bu2614_set(dev, field, data) ((dev)->bu2614data = \
+       ((dev)->bu2614data & ~field##_MASK) | ((data) << field##_SHIFT))
+
+/*
+ * Transmit settings to BU2614FS over GemTek IC.
+ */
+static void gemtek_bu2614_transmit(struct gemtek_device *dev)
 {
-       if(dev->muted)
-               return;
+       int i, bit, q, mute;
+
        spin_lock(&lock);
-       outb(0x10, io);
+
+       mute = dev->muted ? GEMTEK_MT : 0x00;
+
+       outb_p(mute | GEMTEK_DA | GEMTEK_CK, io);
+       udelay(SHORT_DELAY);
+       outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, io);
+       udelay(LONG_DELAY);
+
+       for (i = 0, q = dev->bu2614data; i < 32; i++, q >>= 1) {
+           bit = (q & 1) ? GEMTEK_DA : 0;
+           outb_p(mute | GEMTEK_CE | bit, io);
+           udelay(SHORT_DELAY);
+           outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, io);
+           udelay(SHORT_DELAY);
+       }
+
+       outb_p(mute | GEMTEK_DA | GEMTEK_CK, io);
+       udelay(SHORT_DELAY);
+       outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, io);
+       udelay(LONG_DELAY);
+
        spin_unlock(&lock);
-       dev->muted = 1;
 }
 
-static void gemtek_unmute(struct gemtek_device *dev)
+/*
+ * Calculate divisor from FM-frequency for BU2614FS (3.125 KHz STDF expected).
+ */
+static unsigned long gemtek_convfreq(unsigned long freq)
 {
-       if(dev->muted == 0)
+       return ((freq<<FSCALE) + IF_OFFSET + REF_FREQ/2) / REF_FREQ;
+}
+
+/*
+ * Set FM-frequency.
+ */
+static void gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
+{
+
+       if (keepmuted && hardmute && dev->muted)
                return;
-       spin_lock(&lock);
-       outb(0x20, io);
-       spin_unlock(&lock);
+
+       if (freq < GEMTEK_LOWFREQ)
+               freq = GEMTEK_LOWFREQ;
+       else if (freq > GEMTEK_HIGHFREQ)
+               freq = GEMTEK_HIGHFREQ;
+
+       dev->lastfreq = freq;
        dev->muted = 0;
+
+       gemtek_bu2614_set(dev, BU2614_PORT, 0);
+       gemtek_bu2614_set(dev, BU2614_FMES, 0);
+       gemtek_bu2614_set(dev, BU2614_SWIN, 0); /* FM-mode      */
+       gemtek_bu2614_set(dev, BU2614_SWAL, 0);
+       gemtek_bu2614_set(dev, BU2614_FMUN, 1); /* GT bit set   */
+       gemtek_bu2614_set(dev, BU2614_TEST, 0);
+
+       gemtek_bu2614_set(dev, BU2614_STDF, GEMTEK_STDF_3_125_KHZ);
+       gemtek_bu2614_set(dev, BU2614_FREQ, gemtek_convfreq(freq));
+
+       gemtek_bu2614_transmit(dev);
 }
 
-static void zero(void)
+/*
+ * Set mute flag.
+ */
+static void gemtek_mute(struct gemtek_device *dev)
 {
-       outb_p(0x04, io);
-       udelay(5);
-       outb_p(0x05, io);
-       udelay(5);
+       int i;
+       dev->muted = 1;
+
+       if (hardmute) {
+               /* Turn off PLL, disable data output */
+               gemtek_bu2614_set(dev, BU2614_PORT, 0);
+               gemtek_bu2614_set(dev, BU2614_FMES, 0); /* CT bit off   */
+               gemtek_bu2614_set(dev, BU2614_SWIN, 0); /* FM-mode      */
+               gemtek_bu2614_set(dev, BU2614_SWAL, 0);
+               gemtek_bu2614_set(dev, BU2614_FMUN, 0); /* GT bit off   */
+               gemtek_bu2614_set(dev, BU2614_TEST, 0);
+               gemtek_bu2614_set(dev, BU2614_STDF, GEMTEK_PLL_OFF);
+               gemtek_bu2614_set(dev, BU2614_FREQ, 0);
+               gemtek_bu2614_transmit(dev);
+       } else {
+               spin_lock(&lock);
+
+               /* Read bus contents (CE, CK and DA). */
+               i = inb_p(io);
+               /* Write it back with mute flag set. */
+               outb_p((i >> 5) | GEMTEK_MT, io);
+               udelay(SHORT_DELAY);
+
+               spin_unlock(&lock);
+       }
 }
 
-static void one(void)
+/*
+ * Unset mute flag.
+ */
+static void gemtek_unmute(struct gemtek_device *dev)
 {
-       outb_p(0x06, io);
-       udelay(5);
-       outb_p(0x07, io);
-       udelay(5);
+       int i;
+       dev->muted = 0;
+
+       if (hardmute) {
+               /* Turn PLL back on. */
+               gemtek_setfreq(dev, dev->lastfreq);
+       } else {
+               spin_lock(&lock);
+
+               i = inb_p(io);
+               outb_p(i >> 5, io);
+               udelay(SHORT_DELAY);
+
+               spin_unlock(&lock);
+       }
 }
 
-static int gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
+/*
+ * Get signal strength (= stereo status).
+ */
+static inline int gemtek_getsigstr(void)
 {
-       int i;
+       return inb_p(io) & GEMTEK_NS ? 0 : 1;
+}
 
-/*        freq = 78.25*((float)freq/16000.0 + 10.52); */
+/*
+ * Check if requested card acts like GemTek Radio card.
+ */
+static int gemtek_verify(int port)
+{
+       static int verified = -1;
+       int i, q;
 
-       freq /= 16;
-       freq += 10520;
-       freq *= 7825;
-       freq /= 100000;
+       if (verified == port)
+               return 1;
 
        spin_lock(&lock);
 
-       /* 2 start bits */
-       outb_p(0x03, io);
-       udelay(5);
-       outb_p(0x07, io);
-       udelay(5);
+       q = inb_p(port);        /* Read bus contents before probing. */
+       /* Try to turn on CE, CK and DA respectively and check if card responds
+          properly. */
+       for (i = 0; i < 3; ++i) {
+               outb_p(1 << i, port);
+               udelay(SHORT_DELAY);
 
-       /* 28 frequency bits (lsb first) */
-       for (i = 0; i < 14; i++)
-               if (freq & (1 << i))
-                       one();
-               else
-                       zero();
-       /* 36 unknown bits */
-       for (i = 0; i < 11; i++)
-               zero();
-       one();
-       for (i = 0; i < 4; i++)
-               zero();
-       one();
-       zero();
-
-       /* 2 end bits */
-       outb_p(0x03, io);
-       udelay(5);
-       outb_p(0x07, io);
-       udelay(5);
+               if ((inb_p(port) & (~GEMTEK_NS)) != (0x17 | (1 << (i + 5)))) {
+                       spin_unlock(&lock);
+                       return 0;
+               }
+       }
+       outb_p(q >> 5, port);   /* Write bus contents back. */
+       udelay(SHORT_DELAY);
 
        spin_unlock(&lock);
+       verified = port;
 
-       return 0;
+       return 1;
 }
 
-static int gemtek_getsigstr(struct gemtek_device *dev)
+/*
+ * Automatic probing for card.
+ */
+static int gemtek_probe(void)
 {
-       spin_lock(&lock);
-       inb(io);
-       udelay(5);
-       spin_unlock(&lock);
-       if (inb(io) & 8)                /* bit set = no signal present */
-               return 0;
-       return 1;               /* signal present */
+       int ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c };
+       int i;
+
+       if (!probe) {
+               printk(KERN_INFO "Automatic device probing disabled.\n");
+               return -1;
+       }
+
+       printk(KERN_INFO "Automatic device probing enabled.\n");
+
+       for (i = 0; i < ARRAY_SIZE(ioports); ++i) {
+               printk(KERN_INFO "Trying I/O port 0x%x...\n", ioports[i]);
+
+               if (!request_region(ioports[i], 1, "gemtek-probe")) {
+                       printk(KERN_WARNING "I/O port 0x%x busy!\n",
+                              ioports[i]);
+                       continue;
+               }
+
+               if (gemtek_verify(ioports[i])) {
+                       printk(KERN_INFO "Card found from I/O port "
+                              "0x%x!\n", ioports[i]);
+
+                       release_region(ioports[i], 1);
+
+                       io = ioports[i];
+                       return io;
+               }
+
+               release_region(ioports[i], 1);
+       }
+
+       printk(KERN_ERR "Automatic probing failed!\n");
+
+       return -1;
 }
 
-static int vidioc_querycap(struct file *file, void  *priv,
-                                       struct v4l2_capability *v)
+/*
+ * Video 4 Linux stuff.
+ */
+
+static struct v4l2_queryctrl radio_qctrl[] = {
+       {
+               .id = V4L2_CID_AUDIO_MUTE,
+               .name = "Mute",
+               .minimum = 0,
+               .maximum = 1,
+               .default_value = 1,
+               .type = V4L2_CTRL_TYPE_BOOLEAN,
+       }, {
+               .id = V4L2_CID_AUDIO_VOLUME,
+               .name = "Volume",
+               .minimum = 0,
+               .maximum = 65535,
+               .step = 65535,
+               .default_value = 0xff,
+               .type = V4L2_CTRL_TYPE_INTEGER,
+       }
+};
+
+static struct file_operations gemtek_fops = {
+       .owner          = THIS_MODULE,
+       .open           = video_exclusive_open,
+       .release        = video_exclusive_release,
+       .ioctl          = video_ioctl2,
+       .compat_ioctl   = v4l_compat_ioctl32,
+       .llseek         = no_llseek
+};
+
+static int vidioc_querycap(struct file *file, void *priv,
+                          struct v4l2_capability *v)
 {
        strlcpy(v->driver, "radio-gemtek", sizeof(v->driver));
        strlcpy(v->card, "GemTek", sizeof(v->card));
@@ -172,28 +412,29 @@ static int vidioc_querycap(struct file *file, void  *priv,
        return 0;
 }
 
-static int vidioc_g_tuner(struct file *file, void *priv,
-                                       struct v4l2_tuner *v)
+static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
 {
-       struct video_device *dev = video_devdata(file);
-       struct gemtek_device *rt = dev->priv;
-
        if (v->index > 0)
                return -EINVAL;
 
        strcpy(v->name, "FM");
        v->type = V4L2_TUNER_RADIO;
-       v->rangelow = (87*16000);
-       v->rangehigh = (108*16000);
-       v->rxsubchans = V4L2_TUNER_SUB_MONO;
-       v->capability = V4L2_TUNER_CAP_LOW;
-       v->audmode = V4L2_TUNER_MODE_MONO;
-       v->signal = 0xffff*gemtek_getsigstr(rt);
+       v->rangelow = GEMTEK_LOWFREQ;
+       v->rangehigh = GEMTEK_HIGHFREQ;
+       v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+       v->signal = 0xffff * gemtek_getsigstr();
+       if (v->signal) {
+               v->audmode = V4L2_TUNER_MODE_STEREO;
+               v->rxsubchans = V4L2_TUNER_SUB_STEREO;
+       } else {
+               v->audmode = V4L2_TUNER_MODE_MONO;
+               v->rxsubchans = V4L2_TUNER_SUB_MONO;
+       }
+
        return 0;
 }
 
-static int vidioc_s_tuner(struct file *file, void *priv,
-                                       struct v4l2_tuner *v)
+static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
 {
        if (v->index > 0)
                return -EINVAL;
@@ -201,38 +442,35 @@ static int vidioc_s_tuner(struct file *file, void *priv,
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
-                                       struct v4l2_frequency *f)
+                             struct v4l2_frequency *f)
 {
        struct video_device *dev = video_devdata(file);
        struct gemtek_device *rt = dev->priv;
 
-       rt->curfreq = f->frequency;
-       /* needs to be called twice in order for getsigstr to work */
-       gemtek_setfreq(rt, rt->curfreq);
-       gemtek_setfreq(rt, rt->curfreq);
+       gemtek_setfreq(rt, f->frequency);
+
        return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
-                                       struct v4l2_frequency *f)
+                             struct v4l2_frequency *f)
 {
        struct video_device *dev = video_devdata(file);
        struct gemtek_device *rt = dev->priv;
 
        f->type = V4L2_TUNER_RADIO;
-       f->frequency = rt->curfreq;
+       f->frequency = rt->lastfreq;
        return 0;
 }
 
 static int vidioc_queryctrl(struct file *file, void *priv,
-                                       struct v4l2_queryctrl *qc)
+                           struct v4l2_queryctrl *qc)
 {
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
+       for (i = 0; i < ARRAY_SIZE(radio_qctrl); ++i) {
                if (qc->id && qc->id == radio_qctrl[i].id) {
-                       memcpy(qc, &(radio_qctrl[i]),
-                                               sizeof(*qc));
+                       memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
                        return 0;
                }
        }
@@ -240,7 +478,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
 }
 
 static int vidioc_g_ctrl(struct file *file, void *priv,
-                                       struct v4l2_control *ctrl)
+                        struct v4l2_control *ctrl)
 {
        struct video_device *dev = video_devdata(file);
        struct gemtek_device *rt = dev->priv;
@@ -260,7 +498,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
 }
 
 static int vidioc_s_ctrl(struct file *file, void *priv,
-                                       struct v4l2_control *ctrl)
+                        struct v4l2_control *ctrl)
 {
        struct video_device *dev = video_devdata(file);
        struct gemtek_device *rt = dev->priv;
@@ -282,8 +520,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
        return -EINVAL;
 }
 
-static int vidioc_g_audio (struct file *file, void *priv,
-                                       struct v4l2_audio *a)
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
 {
        if (a->index > 1)
                return -EINVAL;
@@ -306,99 +543,102 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
        return 0;
 }
 
-static int vidioc_s_audio(struct file *file, void *priv,
-                                       struct v4l2_audio *a)
+static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
 {
        if (a->index != 0)
                return -EINVAL;
        return 0;
 }
 
-static struct gemtek_device gemtek_unit;
-
-static const struct file_operations gemtek_fops = {
-       .owner          = THIS_MODULE,
-       .open           = video_exclusive_open,
-       .release        = video_exclusive_release,
-       .ioctl          = video_ioctl2,
-       .compat_ioctl   = v4l_compat_ioctl32,
-       .llseek         = no_llseek,
+static struct video_device gemtek_radio = {
+       .owner                  = THIS_MODULE,
+       .name                   = "GemTek Radio card",
+       .type                   = VID_TYPE_TUNER,
+       .hardware               = VID_HARDWARE_GEMTEK,
+       .fops                   = &gemtek_fops,
+       .vidioc_querycap        = vidioc_querycap,
+       .vidioc_g_tuner         = vidioc_g_tuner,
+       .vidioc_s_tuner         = vidioc_s_tuner,
+       .vidioc_g_audio         = vidioc_g_audio,
+       .vidioc_s_audio         = vidioc_s_audio,
+       .vidioc_g_input         = vidioc_g_input,
+       .vidioc_s_input         = vidioc_s_input,
+       .vidioc_g_frequency     = vidioc_g_frequency,
+       .vidioc_s_frequency     = vidioc_s_frequency,
+       .vidioc_queryctrl       = vidioc_queryctrl,
+       .vidioc_g_ctrl          = vidioc_g_ctrl,
+       .vidioc_s_ctrl          = vidioc_s_ctrl
 };
 
-static struct video_device gemtek_radio=
-{
-       .owner          = THIS_MODULE,
-       .name           = "GemTek radio",
-       .type           = VID_TYPE_TUNER,
-       .fops           = &gemtek_fops,
-       .vidioc_querycap    = vidioc_querycap,
-       .vidioc_g_tuner     = vidioc_g_tuner,
-       .vidioc_s_tuner     = vidioc_s_tuner,
-       .vidioc_g_audio     = vidioc_g_audio,
-       .vidioc_s_audio     = vidioc_s_audio,
-       .vidioc_g_input     = vidioc_g_input,
-       .vidioc_s_input     = vidioc_s_input,
-       .vidioc_g_frequency = vidioc_g_frequency,
-       .vidioc_s_frequency = vidioc_s_frequency,
-       .vidioc_queryctrl   = vidioc_queryctrl,
-       .vidioc_g_ctrl      = vidioc_g_ctrl,
-       .vidioc_s_ctrl      = vidioc_s_ctrl,
-};
+/*
+ * Initialization / cleanup related stuff.
+ */
 
+/*
+ * Initilize card.
+ */
 static int __init gemtek_init(void)
 {
-       if(io==-1)
-       {
-               printk(KERN_ERR "You must set an I/O address with io=0x20c, io=0x30c, io=0x24c or io=0x34c (io=0x020c or io=0x248 for the combined sound/radiocard)\n");
-               return -EINVAL;
-       }
+       printk(KERN_INFO RADIO_BANNER "\n");
 
-       if (!request_region(io, 4, "gemtek"))
-       {
-               printk(KERN_ERR "gemtek: port 0x%x already in use\n", io);
-               return -EBUSY;
-       }
+       spin_lock_init(&lock);
 
-       gemtek_radio.priv=&gemtek_unit;
+       gemtek_probe();
+       if (io) {
+               if (!request_region(io, 1, "gemtek")) {
+                       printk(KERN_ERR "I/O port 0x%x already in use.\n", io);
+                       return -EBUSY;
+               }
 
-       if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr)==-1)
-       {
-               release_region(io, 4);
+               if (!gemtek_verify(io))
+                       printk(KERN_WARNING "Card at I/O port 0x%x does not "
+                              "respond properly, check your "
+                              "configuration.\n", io);
+               else
+                       printk(KERN_INFO "Using I/O port 0x%x.\n", io);
+       } else if (probe) {
+               printk(KERN_ERR "Automatic probing failed and no "
+                      "fixed I/O port defined.\n");
+               return -ENODEV;
+       } else {
+               printk(KERN_ERR "Automatic probing disabled but no fixed "
+                      "I/O port defined.");
                return -EINVAL;
        }
-       printk(KERN_INFO "GemTek Radio Card driver.\n");
 
-       spin_lock_init(&lock);
+       gemtek_radio.priv = &gemtek_unit;
 
-       /* this is _maybe_ unnecessary */
-       outb(0x01, io);
+       if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO,
+               radio_nr) == -1) {
+               release_region(io, 1);
+               return -EBUSY;
+       }
 
-       /* mute card - prevents noisy bootups */
-       gemtek_unit.muted = 0;
-       gemtek_mute(&gemtek_unit);
+       /* Set defaults */
+       gemtek_unit.lastfreq = GEMTEK_LOWFREQ;
+       gemtek_unit.bu2614data = 0;
+
+       if (initmute)
+               gemtek_mute(&gemtek_unit);
 
        return 0;
 }
 
-MODULE_AUTHOR("Jonas Munsin");
-MODULE_DESCRIPTION("A driver for the GemTek Radio Card");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x34c (0x20c or 0x248 have been reported to work for the combined sound/radiocard)).");
-module_param(radio_nr, int, 0);
-
-static void __exit gemtek_cleanup(void)
+/*
+ * Module cleanup
+ */
+static void __exit gemtek_exit(void)
 {
+       if (shutdown) {
+               hardmute = 1;   /* Turn off PLL */
+               gemtek_mute(&gemtek_unit);
+       } else {
+               printk(KERN_INFO "Module unloaded but card not muted!\n");
+       }
+
        video_unregister_device(&gemtek_radio);
-       release_region(io,4);
+       release_region(io, 1);
 }
 
 module_init(gemtek_init);
-module_exit(gemtek_cleanup);
-
-/*
-  Local variables:
-  compile-command: "gcc -c -DMODVERSIONS -D__KERNEL__ -DMODULE -O6 -Wall -Wstrict-prototypes -I /home/blp/tmp/linux-2.1.111-rtrack/include radio-rtrack2.c"
-  End:
-*/
+module_exit(gemtek_exit);
index 7e1911c3d54e2f5663219daa00f4f28ea7b444f7..535ffe8c81028508ac773c05510a8f895c35678d 100644 (file)
@@ -173,7 +173,7 @@ static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
                i--;
                p--;
                temp = temp/2;
-       }
+       }
 
        spin_lock(&lock);
 
index e204e7b4028a986c7b3de8c5b8b95f86eac58180..2e571eb9313ae6d5b8e49b5829c83ec8a590c354 100644 (file)
@@ -148,6 +148,15 @@ config VIDEO_WM8739
          To compile this driver as a module, choose M here: the
          module will be called wm8739.
 
+config VIDEO_VP27SMPX
+       tristate "Panasonic VP27s internal MPX"
+       depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+       ---help---
+         Support for the internal MPX of the Panasonic VP27s tuner.
+
+         To compile this driver as a module, choose M here: the
+         module will be called vp27smpx.
+
 comment "Video decoders"
 
 config VIDEO_BT819
@@ -197,6 +206,13 @@ config VIDEO_OV7670
          OV7670 VGA camera.  It currently only works with the M88ALP01
          controller.
 
+config VIDEO_TCM825X
+       tristate "TCM825x camera sensor support"
+       depends on I2C && VIDEO_V4L2
+       ---help---
+         This is a driver for the Toshiba TCM825x VGA camera sensor.
+         It is used for example in Nokia N800.
+
 config VIDEO_SAA7110
        tristate "Philips SAA7110 video decoder"
        depends on VIDEO_V4L1 && I2C
@@ -348,7 +364,7 @@ endmenu # encoder / decoder chips
 config VIDEO_VIVI
        tristate "Virtual Video Driver"
        depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI
-       select VIDEO_BUF
+       select VIDEOBUF_VMALLOC
        default n
        ---help---
          Enables a virtual video driver. This device shows a color bar
@@ -489,15 +505,6 @@ config TUNER_3036
          Say Y here to include support for Philips SAB3036 compatible tuners.
          If in doubt, say N.
 
-config TUNER_TEA5761
-       bool "TEA 5761 radio tuner (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
-       depends on I2C
-       select VIDEO_TUNER
-       help
-         Say Y here to include support for Philips TEA5761 radio tuner.
-         If in doubt, say N.
-
 config VIDEO_VINO
        tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
        depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2
@@ -661,6 +668,8 @@ config VIDEO_HEXIUM_GEMINI
 
 source "drivers/media/video/cx88/Kconfig"
 
+source "drivers/media/video/cx23885/Kconfig"
+
 source "drivers/media/video/ivtv/Kconfig"
 
 config VIDEO_M32R_AR
index 10b4d44690162c361737ab3008e8860c2608a67c..b5a064163e03f49231cd957db20790a11c19ac68 100644 (file)
@@ -4,14 +4,12 @@
 
 zr36067-objs   :=      zoran_procfs.o zoran_device.o \
                        zoran_driver.o zoran_card.o
-tuner-objs     :=      tuner-core.o tuner-types.o tuner-simple.o \
-                       mt20xx.o tda8290.o tea5767.o tda9887.o
-
-tuner-$(CONFIG_TUNER_TEA5761)  += tea5761.o
+tuner-objs     :=      tuner-core.o tuner-types.o tda9887.o
 
 msp3400-objs   :=      msp3400-driver.o msp3400-kthreads.o
 
-obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o
+obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o \
+                          v4l2-int-device.o
 
 ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
   obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
@@ -63,7 +61,6 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
 obj-$(CONFIG_VIDEO_MEYE) += meye.o
 obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
 obj-$(CONFIG_VIDEO_CX88) += cx88/
-obj-$(CONFIG_VIDEO_IVTV) += ivtv/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
 obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
 obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
@@ -73,6 +70,7 @@ obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
 obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
 obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
 obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
+obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
 obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
 obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
 obj-$(CONFIG_VIDEO_MXB) += mxb.o
@@ -82,8 +80,17 @@ obj-$(CONFIG_VIDEO_DPC) += dpc7146.o
 obj-$(CONFIG_TUNER_3036) += tuner-3036.o
 
 obj-$(CONFIG_VIDEO_TUNER) += tuner.o
-obj-$(CONFIG_VIDEO_BUF)   += video-buf.o
-obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o
+
+obj-$(CONFIG_TUNER_SIMPLE) += tuner-simple.o
+obj-$(CONFIG_TUNER_MT20XX) += mt20xx.o
+obj-$(CONFIG_TUNER_TDA8290) += tda8290.o
+obj-$(CONFIG_TUNER_TEA5767) += tea5767.o
+obj-$(CONFIG_TUNER_TEA5761) += tea5761.o
+
+obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o
+obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o
+obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
+obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
 obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
 obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
 
@@ -97,6 +104,8 @@ obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
 obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
 obj-$(CONFIG_VIDEO_OV7670)     += ov7670.o
 
+obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
+
 obj-$(CONFIG_USB_DABUSB)        += dabusb.o
 obj-$(CONFIG_USB_OV511)         += ov511.o
 obj-$(CONFIG_USB_SE401)         += se401.o
@@ -114,6 +123,9 @@ obj-$(CONFIG_USB_KONICAWC)      += usbvideo/
 obj-$(CONFIG_USB_VICAM)         += usbvideo/
 obj-$(CONFIG_USB_QUICKCAM_MESSENGER)   += usbvideo/
 
+obj-$(CONFIG_VIDEO_IVTV) += ivtv/
+
 obj-$(CONFIG_VIDEO_VIVI) += vivi.o
+obj-$(CONFIG_VIDEO_CX23885) += cx23885/
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
index 649f52f9ad27602c8d27956f9384dc3694fb0d2d..19e9929ffa0fb74adc7c2df4ebf9944b2e551632 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
@@ -442,7 +441,7 @@ static int ar_do_ioctl(struct inode *inode, struct file *file,
        {
                struct video_window *w = arg;
                DEBUG(1, "VIDIOCGWIN:\n");
-               memset(w, 0, sizeof(w));
+               memset(w, 0, sizeof(*w));
                w->width = ar->width;
                w->height = ar->height;
                return 0;
index 58eae887a62992c4a542193a219a81c4f4061f8d..2ca162b390a219fe7b7cb8501ab99eb18f06f048 100644 (file)
@@ -4,7 +4,7 @@ config VIDEO_BT848
        select I2C_ALGOBIT
        select FW_LOADER
        select VIDEO_BTCX
-       select VIDEO_BUF
+       select VIDEOBUF_DMA_SG
        select VIDEO_IR
        select VIDEO_TUNER
        select VIDEO_TVEEPROM
index f6715007d409089cad347d660f6680fb35fa4111..dd6a7d68b07fca263b2648136c21aedadaf97c2e 100644 (file)
@@ -27,7 +27,6 @@
 
 #include <linux/delay.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kmod.h>
 #include <linux/init.h>
 #include <linux/pci.h>
@@ -2989,6 +2988,23 @@ struct tvcard bttv_tvcards[] = {
                .no_tda9875     = 1,
                .no_tda7432     = 1,
        },
+       /* ---- card 0x95---------------------------------- */
+       [BTTV_BOARD_TYPHOON_TVTUNERPCI] = {
+               .name           = "Typhoon TV-Tuner PCI (50684)",
+               .video_inputs   = 3,
+               .audio_inputs   = 1,
+               .tuner          = 0,
+               .svhs           = 2,
+               .gpiomask       = 0x3014f,
+               .muxsel         = { 2, 3, 1, 1 },
+               .gpiomux        = { 0x20001,0x10001, 0, 0 },
+               .gpiomute       = 10,
+               .needs_tvaudio  = 1,
+               .pll            = PLL_28,
+               .tuner_type     = TUNER_PHILIPS_PAL_I,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+       },
 };
 
 static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3276,15 +3292,15 @@ static void eagle_muxsel(struct bttv *btv, unsigned int input)
        btaor((2)<<5, ~(3<<5), BT848_IFORM);
        gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]);
 
-       /* composite */
-       /* set chroma ADC to sleep */
-       btor(BT848_ADC_C_SLEEP, BT848_ADC);
-       /* set to composite video */
-       btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
-       btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
+       /* composite */
+       /* set chroma ADC to sleep */
+       btor(BT848_ADC_C_SLEEP, BT848_ADC);
+       /* set to composite video */
+       btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
+       btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
 
-       /* switch sync drive off */
-       gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
+       /* switch sync drive off */
+       gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
 }
 
 static void gvc1100_muxsel(struct bttv *btv, unsigned int input)
@@ -3453,7 +3469,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
                        printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr);
                }
                break;
-       case BTTV_BOARD_STB2:
+       case BTTV_BOARD_STB2:
                if (btv->cardid == 0x3060121a) {
                        /* Fix up entry for 3DFX VoodooTV 100,
                           which is an OEM STB card variant. */
@@ -3784,7 +3800,7 @@ static void __devinit osprey_eeprom(struct bttv *btv, const u8 ee[256])
                        for (i = 12; i < 21; i++)
                                serial *= 10, serial += ee[i] - '0';
                }
-       } else {
+       } else {
                unsigned short type;
 
                for (i = 4*16; i < 8*16; i += 16) {
index cb555f2c40f95802749ae5ac791d4f68eb7e7e5d..7a332b3efe51e0aefe5564b5ba58da13c3c6dcb9 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
@@ -155,13 +154,14 @@ MODULE_LICENSE("GPL");
 /* ----------------------------------------------------------------------- */
 /* sysfs                                                                   */
 
-static ssize_t show_card(struct class_device *cd, char *buf)
+static ssize_t show_card(struct device *cd,
+                        struct device_attribute *attr, char *buf)
 {
        struct video_device *vfd = to_video_device(cd);
        struct bttv *btv = dev_get_drvdata(vfd->dev);
        return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
 }
-static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
+static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
 
 /* ----------------------------------------------------------------------- */
 /* dvb auto-load setup                                                     */
@@ -2583,7 +2583,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
        if (check_btres(fh, RESOURCE_OVERLAY)) {
                struct bttv_buffer *new;
 
-               new = videobuf_alloc(sizeof(*new));
+               new = videobuf_pci_alloc(sizeof(*new));
                new->crop = btv->crop[!!fh->do_crop].rect;
                bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
                retval = bttv_switch_overlay(btv,fh,new);
@@ -3049,7 +3049,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                mutex_lock(&fh->cap.lock);
                if (*on) {
                        fh->ov.tvnorm = btv->tvnorm;
-                       new = videobuf_alloc(sizeof(*new));
+                       new = videobuf_pci_alloc(sizeof(*new));
                        new->crop = btv->crop[!!fh->do_crop].rect;
                        bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
                } else {
@@ -3072,6 +3072,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                                             V4L2_MEMORY_MMAP);
                if (retval < 0)
                        goto fh_unlock_and_return;
+
+               gbuffers = retval;
                memset(mbuf,0,sizeof(*mbuf));
                mbuf->frames = gbuffers;
                mbuf->size   = gbuffers * gbufsize;
@@ -3142,9 +3144,12 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                        retval = -EIO;
                        /* fall through */
                case STATE_DONE:
-                       videobuf_dma_sync(&fh->cap,&buf->vb.dma);
+               {
+                       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
+                       videobuf_dma_sync(&fh->cap,dma);
                        bttv_dma_free(&fh->cap,btv,buf);
                        break;
+               }
                default:
                        retval = -EINVAL;
                        break;
@@ -3338,7 +3343,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                        if (check_btres(fh, RESOURCE_OVERLAY)) {
                                struct bttv_buffer *new;
 
-                               new = videobuf_alloc(sizeof(*new));
+                               new = videobuf_pci_alloc(sizeof(*new));
                                new->crop = btv->crop[!!fh->do_crop].rect;
                                bttv_overlay_risc(btv,&fh->ov,fh->ovfmt,new);
                                retval = bttv_switch_overlay(btv,fh,new);
@@ -3697,7 +3702,7 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
                                mutex_unlock(&fh->cap.lock);
                                return POLLERR;
                        }
-                       fh->cap.read_buf = videobuf_alloc(fh->cap.msize);
+                       fh->cap.read_buf = videobuf_pci_alloc(fh->cap.msize);
                        if (NULL == fh->cap.read_buf) {
                                mutex_unlock(&fh->cap.lock);
                                return POLLERR;
@@ -3764,13 +3769,13 @@ static int bttv_open(struct inode *inode, struct file *file)
        fh->ov.setup_ok = 0;
        v4l2_prio_open(&btv->prio,&fh->prio);
 
-       videobuf_queue_init(&fh->cap, &bttv_video_qops,
+       videobuf_queue_pci_init(&fh->cap, &bttv_video_qops,
                            btv->c.pci, &btv->s_lock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_INTERLACED,
                            sizeof(struct bttv_buffer),
                            fh);
-       videobuf_queue_init(&fh->vbi, &bttv_vbi_qops,
+       videobuf_queue_pci_init(&fh->vbi, &bttv_vbi_qops,
                            btv->c.pci, &btv->s_lock,
                            V4L2_BUF_TYPE_VBI_CAPTURE,
                            V4L2_FIELD_SEQ_TB,
@@ -4613,9 +4618,9 @@ static int __devinit bttv_register_video(struct bttv *btv)
                goto err;
        printk(KERN_INFO "bttv%d: registered device video%d\n",
               btv->c.nr,btv->video_dev->minor & 0x1f);
-       if (class_device_create_file(&btv->video_dev->class_dev,
-                                    &class_device_attr_card)<0) {
-               printk(KERN_ERR "bttv%d: class_device_create_file 'card' "
+       if (device_create_file(&btv->video_dev->class_dev,
+                                    &dev_attr_card)<0) {
+               printk(KERN_ERR "bttv%d: device_create_file 'card' "
                       "failed\n", btv->c.nr);
                goto err;
        }
index 84154c26f9c5fb3c4bed9d1a099073260e9ff0c8..dce6dae5740efa55586cd9bf88e24a675e0cd41e 100644 (file)
@@ -106,11 +106,9 @@ int bttv_sub_add_device(struct bttv_core *core, char *name)
 
 int bttv_sub_del_devices(struct bttv_core *core)
 {
-       struct bttv_sub_device *sub;
-       struct list_head *item,*save;
+       struct bttv_sub_device *sub, *save;
 
-       list_for_each_safe(item,save,&core->subs) {
-               sub = list_entry(item,struct bttv_sub_device,list);
+       list_for_each_entry_safe(sub, save, &core->subs, list) {
                list_del(&sub->list);
                device_unregister(&sub->dev);
        }
index 0dfa49b66418be935bb2da5bd64812eae9c806e1..844f1762c45ab516cc99dbaf7383a2a53d2382c5 100644 (file)
@@ -28,7 +28,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 
index 4201552bc3c0689393e127ddaacfe51dfec0baef..e7c521b8444afea5dca779091a9fa4bda2b8c691 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index e7104d9cb4bd14d14da412c4ac644e09cd6ab167..58986f1a5f1a492d93e11780df80d747a18ab974 100644 (file)
@@ -574,10 +574,12 @@ bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
 void
 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
 {
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
+
        BUG_ON(in_interrupt());
        videobuf_waiton(&buf->vb,0,0);
-       videobuf_dma_unmap(q, &buf->vb.dma);
-       videobuf_dma_free(&buf->vb.dma);
+       videobuf_dma_unmap(q, dma);
+       videobuf_dma_free(dma);
        btcx_riscmem_free(btv->c.pci,&buf->bottom);
        btcx_riscmem_free(btv->c.pci,&buf->top);
        buf->vb.state = STATE_NEEDS_INIT;
@@ -699,6 +701,7 @@ int
 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
 {
        const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 
        dprintk(KERN_DEBUG
                "bttv%d: buffer field: %s  format: %s  size: %dx%d\n",
@@ -716,25 +719,25 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
 
                switch (buf->vb.field) {
                case V4L2_FIELD_TOP:
-                       bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
+                       bttv_risc_packed(btv,&buf->top,dma->sglist,
                                         /* offset */ 0,bpl,
                                         /* padding */ 0,/* skip_lines */ 0,
                                         buf->vb.height);
                        break;
                case V4L2_FIELD_BOTTOM:
-                       bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
+                       bttv_risc_packed(btv,&buf->bottom,dma->sglist,
                                         0,bpl,0,0,buf->vb.height);
                        break;
                case V4L2_FIELD_INTERLACED:
-                       bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
+                       bttv_risc_packed(btv,&buf->top,dma->sglist,
                                         0,bpl,bpl,0,buf->vb.height >> 1);
-                       bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
+                       bttv_risc_packed(btv,&buf->bottom,dma->sglist,
                                         bpl,bpl,bpl,0,buf->vb.height >> 1);
                        break;
                case V4L2_FIELD_SEQ_TB:
-                       bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
+                       bttv_risc_packed(btv,&buf->top,dma->sglist,
                                         0,bpl,0,0,buf->vb.height >> 1);
-                       bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
+                       bttv_risc_packed(btv,&buf->bottom,dma->sglist,
                                         bpf,bpl,0,0,buf->vb.height >> 1);
                        break;
                default:
@@ -767,7 +770,7 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
                        bttv_calc_geo(btv,&buf->geo,buf->vb.width,
                                      buf->vb.height,/* both_fields */ 0,
                                      tvnorm,&buf->crop);
-                       bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist,
+                       bttv_risc_planar(btv, &buf->top, dma->sglist,
                                         0,buf->vb.width,0,buf->vb.height,
                                         uoffset,voffset,buf->fmt->hshift,
                                         buf->fmt->vshift,0);
@@ -776,7 +779,7 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
                        bttv_calc_geo(btv,&buf->geo,buf->vb.width,
                                      buf->vb.height,0,
                                      tvnorm,&buf->crop);
-                       bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
+                       bttv_risc_planar(btv, &buf->bottom, dma->sglist,
                                         0,buf->vb.width,0,buf->vb.height,
                                         uoffset,voffset,buf->fmt->hshift,
                                         buf->fmt->vshift,0);
@@ -789,14 +792,14 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
                        ypadding = buf->vb.width;
                        cpadding = buf->vb.width >> buf->fmt->hshift;
                        bttv_risc_planar(btv,&buf->top,
-                                        buf->vb.dma.sglist,
+                                        dma->sglist,
                                         0,buf->vb.width,ypadding,lines,
                                         uoffset,voffset,
                                         buf->fmt->hshift,
                                         buf->fmt->vshift,
                                         cpadding);
                        bttv_risc_planar(btv,&buf->bottom,
-                                        buf->vb.dma.sglist,
+                                        dma->sglist,
                                         ypadding,buf->vb.width,ypadding,lines,
                                         uoffset+cpadding,
                                         voffset+cpadding,
@@ -812,7 +815,7 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
                        ypadding = buf->vb.width;
                        cpadding = buf->vb.width >> buf->fmt->hshift;
                        bttv_risc_planar(btv,&buf->top,
-                                        buf->vb.dma.sglist,
+                                        dma->sglist,
                                         0,buf->vb.width,0,lines,
                                         uoffset >> 1,
                                         voffset >> 1,
@@ -820,7 +823,7 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
                                         buf->fmt->vshift,
                                         0);
                        bttv_risc_planar(btv,&buf->bottom,
-                                        buf->vb.dma.sglist,
+                                        dma->sglist,
                                         lines * ypadding,buf->vb.width,0,lines,
                                         lines * ypadding + (uoffset >> 1),
                                         lines * ypadding + (voffset >> 1),
@@ -839,10 +842,10 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
                buf->vb.field = V4L2_FIELD_SEQ_TB;
                bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
                              1,tvnorm,&buf->crop);
-               bttv_risc_packed(btv, &buf->top,  buf->vb.dma.sglist,
+               bttv_risc_packed(btv, &buf->top,  dma->sglist,
                                 /* offset */ 0, RAW_BPL, /* padding */ 0,
                                 /* skip_lines */ 0, RAW_LINES);
-               bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
+               bttv_risc_packed(btv, &buf->bottom, dma->sglist,
                                 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
        }
 
index 93e35de5a1811de578b03b5344ba173ab0d39263..346ce019bdcbd76c52379f9c7581d8171432c8c5 100644 (file)
@@ -24,7 +24,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
@@ -151,13 +150,14 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
 
        if (redo_dma_risc) {
                unsigned int bpl, padding, offset;
+               struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 
                bpl = 2044; /* max. vbipack */
                padding = VBI_BPL - bpl;
 
                if (fh->vbi_fmt.fmt.count[0] > 0) {
                        rc = bttv_risc_packed(btv, &buf->top,
-                                             buf->vb.dma.sglist,
+                                             dma->sglist,
                                              /* offset */ 0, bpl,
                                              padding, skip_lines0,
                                              fh->vbi_fmt.fmt.count[0]);
@@ -169,7 +169,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
                        offset = fh->vbi_fmt.fmt.count[0] * VBI_BPL;
 
                        rc = bttv_risc_packed(btv, &buf->bottom,
-                                             buf->vb.dma.sglist,
+                                             dma->sglist,
                                              offset, bpl,
                                              padding, skip_lines1,
                                              fh->vbi_fmt.fmt.count[1]);
index dcc847dc2486dbc1ac405da7e745be168bea89cb..19e75d50a107924d6559d68b7ba14bddc83443f2 100644 (file)
 #define BTTV_BOARD_SSAI_ULTRASOUND        0x92
 #define BTTV_BOARD_VOODOOTV_200                   0x93
 #define BTTV_BOARD_DVICO_FUSIONHDTV_2     0x94
+#define BTTV_BOARD_TYPHOON_TVTUNERPCI     0x95
+
 
 /* more card-specific defines */
 #define PT2254_L_CHANNEL 0x10
index 5b25faca150411f7b227622b8e9327d77d2bfc89..0b92c35a8435cd86a8abbd9b7df5cf2fa5218cb7 100644 (file)
@@ -41,7 +41,7 @@
 #include <media/v4l2-common.h>
 
 #include <linux/device.h>
-#include <media/video-buf.h>
+#include <media/videobuf-dma-sg.h>
 #include <media/tuner.h>
 #include <media/tveeprom.h>
 #include <media/ir-common.h>
index b4aca7249276af3bd5830aee6e2fde1852883a0f..ce0840ccd594e42332767d7d0b87bc4e4cbdc4d5 100644 (file)
@@ -23,7 +23,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
index 7d47cbe6ad25ac23654eb26d5789e5f7d848c843..7f7e3d3398d0d24e51654d55cf2a1e22aa64e1ba 100644 (file)
@@ -104,6 +104,17 @@ static inline void write_lpdata(struct qcam_device *q, int d)
 
 static inline void write_lpcontrol(struct qcam_device *q, int d)
 {
+       if (d & 0x20) {
+               /* Set bidirectional mode to reverse (data in) */
+               parport_data_reverse(q->pport);
+       } else {
+               /* Set bidirectional mode to forward (data out) */
+               parport_data_forward(q->pport);
+       }
+
+       /* Now issue the regular port command, but strip out the
+        * direction flag */
+       d &= ~0x20;
        parport_write_control(q->pport, d);
 }
 
@@ -344,10 +355,13 @@ static int qc_detect(struct qcam_device *q)
        /* Be (even more) liberal in what you accept...  */
 
 /*     if (count > 30 && count < 200) */
-       if (count > 20 && count < 300)
+       if (count > 20 && count < 400) {
                return 1;       /* found */
-       else
+       } else {
+               printk(KERN_ERR "No Quickcam found on port %s\n",
+                       q->pport->name);
                return 0;       /* not found */
+       }
 }
 
 
index ef5361824f878f01266567839226871cb07a89f9..b63cab33692072a6163463211aaace9fb29619e1 100644 (file)
@@ -14,7 +14,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/pci.h>
@@ -63,13 +62,13 @@ MODULE_SUPPORTED_DEVICE("Video");
  */
 
 #define MAX_DMA_BUFS 3
-static int alloc_bufs_at_load = 0;
-module_param(alloc_bufs_at_load, bool, 0444);
-MODULE_PARM_DESC(alloc_bufs_at_load,
-               "Non-zero value causes DMA buffers to be allocated at module "
-               "load time.  This increases the chances of successfully getting "
-               "those buffers, but at the cost of nailing down the memory from "
-               "the outset.");
+static int alloc_bufs_at_read = 0;
+module_param(alloc_bufs_at_read, bool, 0444);
+MODULE_PARM_DESC(alloc_bufs_at_read,
+               "Non-zero value causes DMA buffers to be allocated when the "
+               "video capture device is read, rather than at module load "
+               "time.  This saves memory, but decreases the chances of "
+               "successfully getting those buffers.");
 
 static int n_dma_bufs = 3;
 module_param(n_dma_bufs, uint, 0644);
@@ -1198,7 +1197,7 @@ static int cafe_setup_siobuf(struct cafe_camera *cam, int index)
        buf->v4lbuf.field = V4L2_FIELD_NONE;
        buf->v4lbuf.memory = V4L2_MEMORY_MMAP;
        /*
-        * Offset: must be 32-bit even on a 64-bit system.  video-buf
+        * Offset: must be 32-bit even on a 64-bit system.  videobuf-dma-sg
         * just uses the length times the index, but the spec warns
         * against doing just that - vma merging problems.  So we
         * leave a gap between each pair of buffers.
@@ -1503,7 +1502,7 @@ static int cafe_v4l_release(struct inode *inode, struct file *filp)
        }
        if (cam->users == 0) {
                cafe_ctlr_power_down(cam);
-               if (! alloc_bufs_at_load)
+               if (alloc_bufs_at_read)
                        cafe_free_dma_bufs(cam);
        }
        mutex_unlock(&cam->s_mutex);
@@ -2162,7 +2161,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
        /*
         * If so requested, try to get our DMA buffers now.
         */
-       if (alloc_bufs_at_load) {
+       if (!alloc_bufs_at_read) {
                if (cafe_alloc_dma_bufs(cam, 1))
                        cam_warn(cam, "Unable to alloc DMA buffers at load"
                                        " will try again later.");
index f065ad12cc6119c3ca69db39d74e74ff827a612d..cefd1381e8de89eba2e75bb7056b27720e5afda0 100644 (file)
@@ -848,6 +848,8 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
        case VIDIOCSFREQ32:
        case VIDIOCGAUDIO:
        case VIDIOCSAUDIO:
+       case VIDIOCGVBIFMT:
+       case VIDIOCSVBIFMT:
 #endif
        case VIDIOC_QUERYCAP:
        case VIDIOC_ENUM_FMT:
@@ -874,7 +876,10 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
        case VIDIOC_ENUMINPUT:
        case VIDIOC_ENUMINPUT32:
        case VIDIOC_G_CTRL:
+       case VIDIOC_S_CTRL:
        case VIDIOC_S_CTRL32:
+       case VIDIOC_S_FREQUENCY:
+       case VIDIOC_G_FREQUENCY:
        case VIDIOC_QUERYCTRL:
        case VIDIOC_G_INPUT32:
        case VIDIOC_S_INPUT32:
index 78c9699eafbbe46e791cc7c228c413b47182394c..a1d02e5ce0fda4dbcf83c8371f3f31e29abb3d6a 100644 (file)
@@ -28,7 +28,6 @@
 
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/vmalloc.h>
index 92778cd1d7356a7a12bc81d1ab70b0dabfb4c4af..e3aaba1e0e0a285a7cfca4970102098ea884852c 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/moduleparam.h>
 
 #include "cpia2.h"
 #include "cpia2dev.h"
index d73c86aeeaacb9a13e5f190492cb8ad31f419882..62304255dcae120cbf669f451942003227f4330e 100644 (file)
@@ -20,7 +20,6 @@
 
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -191,17 +190,21 @@ static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
 
 /* Map the control ID to the correct field in the cx2341x_mpeg_params
    struct. Return -EINVAL if the ID is unknown, else return 0. */
-static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
+static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
                struct v4l2_ext_control *ctrl)
 {
        switch (ctrl->id) {
        case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+               if (busy)
+                       return -EBUSY;
                params->audio_sampling_freq = ctrl->value;
                break;
        case V4L2_CID_MPEG_AUDIO_ENCODING:
                params->audio_encoding = ctrl->value;
                break;
        case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+               if (busy)
+                       return -EBUSY;
                params->audio_l2_bitrate = ctrl->value;
                break;
        case V4L2_CID_MPEG_AUDIO_MODE:
@@ -246,6 +249,8 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
                params->video_gop_closure = ctrl->value;
                break;
        case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+               if (busy)
+                       return -EBUSY;
                /* MPEG-1 only allows CBR */
                if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
                    ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
@@ -253,9 +258,13 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
                params->video_bitrate_mode = ctrl->value;
                break;
        case V4L2_CID_MPEG_VIDEO_BITRATE:
+               if (busy)
+                       return -EBUSY;
                params->video_bitrate = ctrl->value;
                break;
        case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+               if (busy)
+                       return -EBUSY;
                params->video_bitrate_peak = ctrl->value;
                break;
        case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
@@ -268,6 +277,8 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params,
                params->video_mute_yuv = ctrl->value;
                break;
        case V4L2_CID_MPEG_STREAM_TYPE:
+               if (busy)
+                       return -EBUSY;
                params->stream_type = ctrl->value;
                params->video_encoding =
                        (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
@@ -632,7 +643,7 @@ static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
                (params->audio_crc << 14);
 }
 
-int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params,
+int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
                  struct v4l2_ext_controls *ctrls, unsigned int cmd)
 {
        int err = 0;
@@ -664,7 +675,7 @@ int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params,
                err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
                if (err)
                        break;
-               err = cx2341x_set_ctrl(params, ctrl);
+               err = cx2341x_set_ctrl(params, busy, ctrl);
                if (err)
                        break;
        }
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
new file mode 100644 (file)
index 0000000..72004a0
--- /dev/null
@@ -0,0 +1,20 @@
+config VIDEO_CX23885
+       tristate "Conexant cx23885 (2388x successor) support"
+       depends on DVB_CORE && VIDEO_DEV && PCI && I2C
+       select I2C_ALGOBIT
+       select FW_LOADER
+       select VIDEO_BTCX
+       select VIDEO_TUNER
+       select VIDEO_TVEEPROM
+       select VIDEO_IR
+       select VIDEOBUF_DVB
+       select DVB_TUNER_MT2131 if !DVB_FE_CUSTOMISE
+       select DVB_S5H1409 if !DVB_FE_CUSTOMISE
+       select DVB_PLL if !DVB_FE_CUSTOMISE
+       ---help---
+         This is a video4linux driver for Conexant 23885 based
+         TV cards.
+
+         To compile this driver as a module, choose M here: the
+         module will be called cx23885
+
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
new file mode 100644 (file)
index 0000000..6650670
--- /dev/null
@@ -0,0 +1,9 @@
+cx23885-objs   := cx23885-cards.o cx23885-core.o cx23885-i2c.o cx23885-dvb.o
+
+obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
+
+EXTRA_CFLAGS += -Idrivers/media/video
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
new file mode 100644 (file)
index 0000000..b9012ac
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ *  Driver for the Conexant CX23885 PCIe bridge
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#include "cx23885.h"
+
+/* ------------------------------------------------------------------ */
+/* board config info                                                  */
+
+struct cx23885_board cx23885_boards[] = {
+       [CX23885_BOARD_UNKNOWN] = {
+               .name           = "UNKNOWN/GENERIC",
+               .input          = {{
+                       .type   = CX23885_VMUX_COMPOSITE1,
+                       .vmux   = 0,
+               },{
+                       .type   = CX23885_VMUX_COMPOSITE2,
+                       .vmux   = 1,
+               },{
+                       .type   = CX23885_VMUX_COMPOSITE3,
+                       .vmux   = 2,
+               },{
+                       .type   = CX23885_VMUX_COMPOSITE4,
+                       .vmux   = 3,
+               }},
+       },
+       [CX23885_BOARD_HAUPPAUGE_HVR1800lp] = {
+               .name           = "Hauppauge WinTV-HVR1800lp",
+               .portc          = CX23885_MPEG_DVB,
+               .input          = {{
+                       .type   = CX23885_VMUX_TELEVISION,
+                       .vmux   = 0,
+                       .gpio0  = 0xff00,
+               },{
+                       .type   = CX23885_VMUX_DEBUG,
+                       .vmux   = 0,
+                       .gpio0  = 0xff01,
+               },{
+                       .type   = CX23885_VMUX_COMPOSITE1,
+                       .vmux   = 1,
+                       .gpio0  = 0xff02,
+               },{
+                       .type   = CX23885_VMUX_SVIDEO,
+                       .vmux   = 2,
+                       .gpio0  = 0xff02,
+               }},
+       },
+       [CX23885_BOARD_HAUPPAUGE_HVR1800] = {
+               .name           = "Hauppauge WinTV-HVR1800",
+               .portc          = CX23885_MPEG_DVB,
+               .input          = {{
+                       .type   = CX23885_VMUX_TELEVISION,
+                       .vmux   = 0,
+                       .gpio0  = 0xff00,
+               },{
+                       .type   = CX23885_VMUX_DEBUG,
+                       .vmux   = 0,
+                       .gpio0  = 0xff01,
+               },{
+                       .type   = CX23885_VMUX_COMPOSITE1,
+                       .vmux   = 1,
+                       .gpio0  = 0xff02,
+               },{
+                       .type   = CX23885_VMUX_SVIDEO,
+                       .vmux   = 2,
+                       .gpio0  = 0xff02,
+               }},
+       },
+       [CX23885_BOARD_HAUPPAUGE_HVR1250] = {
+               .name           = "Hauppauge WinTV-HVR1250",
+               .portc          = CX23885_MPEG_DVB,
+               .input          = {{
+                       .type   = CX23885_VMUX_TELEVISION,
+                       .vmux   = 0,
+                       .gpio0  = 0xff00,
+               },{
+                       .type   = CX23885_VMUX_DEBUG,
+                       .vmux   = 0,
+                       .gpio0  = 0xff01,
+               },{
+                       .type   = CX23885_VMUX_COMPOSITE1,
+                       .vmux   = 1,
+                       .gpio0  = 0xff02,
+               },{
+                       .type   = CX23885_VMUX_SVIDEO,
+                       .vmux   = 2,
+                       .gpio0  = 0xff02,
+               }},
+       },
+       [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = {
+               .name           = "DViCO FusionHDTV5 Express",
+               .portb          = CX23885_MPEG_DVB,
+       },
+};
+const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
+
+/* ------------------------------------------------------------------ */
+/* PCI subsystem IDs                                                  */
+
+struct cx23885_subid cx23885_subids[] = {
+       {
+               .subvendor = 0x0070,
+               .subdevice = 0x3400,
+               .card      = CX23885_BOARD_UNKNOWN,
+       },{
+               .subvendor = 0x0070,
+               .subdevice = 0x7600,
+               .card      = CX23885_BOARD_HAUPPAUGE_HVR1800lp,
+       },{
+               .subvendor = 0x0070,
+               .subdevice = 0x7800,
+               .card      = CX23885_BOARD_HAUPPAUGE_HVR1800,
+       },{
+               .subvendor = 0x0070,
+               .subdevice = 0x7801,
+               .card      = CX23885_BOARD_HAUPPAUGE_HVR1800,
+       },{
+               .subvendor = 0x0070,
+               .subdevice = 0x7911,
+               .card      = CX23885_BOARD_HAUPPAUGE_HVR1250,
+       },{
+               .subvendor = 0x18ac,
+               .subdevice = 0xd500,
+               .card      = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP,
+       },
+};
+const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
+
+void cx23885_card_list(struct cx23885_dev *dev)
+{
+       int i;
+
+       if (0 == dev->pci->subsystem_vendor &&
+           0 == dev->pci->subsystem_device) {
+               printk("%s: Your board has no valid PCIe Subsystem ID and thus can't\n"
+                      "%s: be autodetected.  Please pass card=<n> insmod option to\n"
+                      "%s: workaround that.  Redirect complaints to the vendor of\n"
+                      "%s: the TV card.  Best regards,\n"
+                      "%s:         -- tux\n",
+                      dev->name, dev->name, dev->name, dev->name, dev->name);
+       } else {
+               printk("%s: Your board isn't known (yet) to the driver.  You can\n"
+                      "%s: try to pick one of the existing card configs via\n"
+                      "%s: card=<n> insmod option.  Updating to the latest\n"
+                      "%s: version might help as well.\n",
+                      dev->name, dev->name, dev->name, dev->name);
+       }
+       printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
+              dev->name);
+       for (i = 0; i < cx23885_bcount; i++)
+               printk("%s:    card=%d -> %s\n",
+                      dev->name, i, cx23885_boards[i].name);
+}
+
+static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
+{
+       struct tveeprom tv;
+
+       tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, eeprom_data);
+
+       /* Make sure we support the board model */
+       switch (tv.model)
+       {
+       case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */
+       case 77001: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */
+       case 78501: /* WinTV-HVR1800 (PCIe, Retail, IR, Dual channel ATSC and MPEG2 HW Encoder */
+       case 78521: /* WinTV-HVR1800 (PCIe, Retail, IR, Dual channel ATSC and MPEG2 HW Encoder */
+               break;
+       default:
+               printk("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model);
+               break;
+       }
+
+       printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n",
+                       dev->name, tv.model);
+}
+
+void cx23885_gpio_setup(struct cx23885_dev *dev)
+{
+       switch(dev->board) {
+       case CX23885_BOARD_HAUPPAUGE_HVR1250:
+               /* GPIO-0 cx24227 demodulator reset */
+               cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */
+               break;
+       case CX23885_BOARD_HAUPPAUGE_HVR1800:
+               /* GPIO-0 656_CLK */
+               /* GPIO-1 656_D0 */
+               /* GPIO-2 8295A Reset */
+               /* GPIO-3-10 cx23417 data0-7 */
+               /* GPIO-11-14 cx23417 addr0-3 */
+               /* GPIO-15-18 cx23417 READY, CS, RD, WR */
+               /* GPIO-19 IR_RX */
+               // FIXME: Analog requires the tuner is brought out of reset
+               break;
+       }
+}
+
+int cx23885_ir_init(struct cx23885_dev *dev)
+{
+       switch (dev->board) {
+       case CX23885_BOARD_HAUPPAUGE_HVR1250:
+       case CX23885_BOARD_HAUPPAUGE_HVR1800:
+               /* FIXME: Implement me */
+               break;
+       }
+
+       return 0;
+}
+
+void cx23885_card_setup(struct cx23885_dev *dev)
+{
+       struct cx23885_tsport *ts1 = &dev->ts1;
+       struct cx23885_tsport *ts2 = &dev->ts2;
+
+       static u8 eeprom[256];
+
+       if (dev->i2c_bus[0].i2c_rc == 0) {
+               dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
+               tveeprom_read(&dev->i2c_bus[0].i2c_client,
+                             eeprom, sizeof(eeprom));
+       }
+
+       switch (dev->board) {
+       case CX23885_BOARD_HAUPPAUGE_HVR1250:
+       case CX23885_BOARD_HAUPPAUGE_HVR1800:
+       case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
+               if (dev->i2c_bus[0].i2c_rc == 0)
+                       hauppauge_eeprom(dev, eeprom+0x80);
+               break;
+       }
+
+       switch (dev->board) {
+       case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
+               ts1->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
+               ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+               ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+               break;
+       case CX23885_BOARD_HAUPPAUGE_HVR1250:
+       case CX23885_BOARD_HAUPPAUGE_HVR1800:
+       case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
+       default:
+               ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
+               ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+               ts2->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+       }
+
+}
+
+/* ------------------------------------------------------------------ */
+
+EXPORT_SYMBOL(cx23885_boards);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
+ */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
new file mode 100644 (file)
index 0000000..af16505
--- /dev/null
@@ -0,0 +1,1530 @@
+/*
+ *  Driver for the Conexant CX23885 PCIe bridge
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kmod.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/div64.h>
+
+#include "cx23885.h"
+
+MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
+MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>");
+MODULE_LICENSE("GPL");
+
+static unsigned int debug = 0;
+module_param(debug,int,0644);
+MODULE_PARM_DESC(debug,"enable debug messages");
+
+static unsigned int card[]  = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET };
+module_param_array(card,  int, NULL, 0444);
+MODULE_PARM_DESC(card,"card type");
+
+#define dprintk(level,fmt, arg...)     if (debug >= level) \
+       printk(KERN_DEBUG "%s/0: " fmt, dev->name , ## arg)
+
+static unsigned int cx23885_devcount;
+
+static DEFINE_MUTEX(devlist);
+static LIST_HEAD(cx23885_devlist);
+
+#define NO_SYNC_LINE (-1U)
+
+/*
+ * CX23885 Assumptions
+ * 1 line = 16 bytes of CDT
+ * cmds size = 80
+ * cdt size = 16 * linesize
+ * iqsize = 64
+ * maxlines = 6
+ *
+ * Address Space:
+ * 0x00000000 0x00008fff FIFO clusters
+ * 0x00010000 0x000104af Channel Management Data Structures
+ * 0x000104b0 0x000104ff Free
+ * 0x00010500 0x000108bf 15 channels * iqsize
+ * 0x000108c0 0x000108ff Free
+ * 0x00010900 0x00010e9f IQ's + Cluster Descriptor Tables
+ *                       15 channels * (iqsize + (maxlines * linesize))
+ * 0x00010ea0 0x00010xxx Free
+ */
+
+struct sram_channel cx23885_sram_channels[] = {
+       [SRAM_CH01] = {
+               .name           = "test ch1",
+               .cmds_start     = 0x10000,
+               .ctrl_start     = 0x10500,
+               .cdt            = 0x10900,
+               .fifo_start     = 0x3000,
+               .fifo_size      = 0x1000,
+               .ptr1_reg       = DMA1_PTR1,
+               .ptr2_reg       = DMA1_PTR2,
+               .cnt1_reg       = DMA1_CNT1,
+               .cnt2_reg       = DMA1_CNT2,
+               .jumponly       = 1,
+       },
+       [SRAM_CH02] = {
+               .name           = "ch2",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA2_PTR1,
+               .ptr2_reg       = DMA2_PTR2,
+               .cnt1_reg       = DMA2_CNT1,
+               .cnt2_reg       = DMA2_CNT2,
+       },
+       [SRAM_CH03] = {
+               .name           = "TS1 B",
+               .cmds_start     = 0x100A0,
+               .ctrl_start     = 0x10780,
+               .cdt            = 0x10400,
+               .fifo_start     = 0x5000,
+               .fifo_size      = 0x1000,
+               .ptr1_reg       = DMA3_PTR1,
+               .ptr2_reg       = DMA3_PTR2,
+               .cnt1_reg       = DMA3_CNT1,
+               .cnt2_reg       = DMA3_CNT2,
+       },
+       [SRAM_CH04] = {
+               .name           = "ch4",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA4_PTR1,
+               .ptr2_reg       = DMA4_PTR2,
+               .cnt1_reg       = DMA4_CNT1,
+               .cnt2_reg       = DMA4_CNT2,
+       },
+       [SRAM_CH05] = {
+               .name           = "ch5",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA5_PTR1,
+               .ptr2_reg       = DMA5_PTR2,
+               .cnt1_reg       = DMA5_CNT1,
+               .cnt2_reg       = DMA5_CNT2,
+       },
+       [SRAM_CH06] = {
+               .name           = "TS2 C",
+               .cmds_start     = 0x10140,
+               .ctrl_start     = 0x10680,
+               .cdt            = 0x10480,
+               .fifo_start     = 0x6000,
+               .fifo_size      = 0x1000,
+               .ptr1_reg       = DMA5_PTR1,
+               .ptr2_reg       = DMA5_PTR2,
+               .cnt1_reg       = DMA5_CNT1,
+               .cnt2_reg       = DMA5_CNT2,
+       },
+       [SRAM_CH07] = {
+               .name           = "ch7",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA6_PTR1,
+               .ptr2_reg       = DMA6_PTR2,
+               .cnt1_reg       = DMA6_CNT1,
+               .cnt2_reg       = DMA6_CNT2,
+       },
+       [SRAM_CH08] = {
+               .name           = "ch8",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA7_PTR1,
+               .ptr2_reg       = DMA7_PTR2,
+               .cnt1_reg       = DMA7_CNT1,
+               .cnt2_reg       = DMA7_CNT2,
+       },
+       [SRAM_CH09] = {
+               .name           = "ch9",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA8_PTR1,
+               .ptr2_reg       = DMA8_PTR2,
+               .cnt1_reg       = DMA8_CNT1,
+               .cnt2_reg       = DMA8_CNT2,
+       },
+};
+
+/* FIXME, these allocations will change when
+ * analog arrives. The be reviewed.
+ * CX23887 Assumptions
+ * 1 line = 16 bytes of CDT
+ * cmds size = 80
+ * cdt size = 16 * linesize
+ * iqsize = 64
+ * maxlines = 6
+ *
+ * Address Space:
+ * 0x00000000 0x00008fff FIFO clusters
+ * 0x00010000 0x000104af Channel Management Data Structures
+ * 0x000104b0 0x000104ff Free
+ * 0x00010500 0x000108bf 15 channels * iqsize
+ * 0x000108c0 0x000108ff Free
+ * 0x00010900 0x00010e9f IQ's + Cluster Descriptor Tables
+ *                       15 channels * (iqsize + (maxlines * linesize))
+ * 0x00010ea0 0x00010xxx Free
+ */
+
+struct sram_channel cx23887_sram_channels[] = {
+       [SRAM_CH01] = {
+               .name           = "test ch1",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA1_PTR1,
+               .ptr2_reg       = DMA1_PTR2,
+               .cnt1_reg       = DMA1_CNT1,
+               .cnt2_reg       = DMA1_CNT2,
+       },
+       [SRAM_CH02] = {
+               .name           = "ch2",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA2_PTR1,
+               .ptr2_reg       = DMA2_PTR2,
+               .cnt1_reg       = DMA2_CNT1,
+               .cnt2_reg       = DMA2_CNT2,
+       },
+       [SRAM_CH03] = {
+               .name           = "ch3",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA3_PTR1,
+               .ptr2_reg       = DMA3_PTR2,
+               .cnt1_reg       = DMA3_CNT1,
+               .cnt2_reg       = DMA3_CNT2,
+       },
+       [SRAM_CH04] = {
+               .name           = "ch4",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA4_PTR1,
+               .ptr2_reg       = DMA4_PTR2,
+               .cnt1_reg       = DMA4_CNT1,
+               .cnt2_reg       = DMA4_CNT2,
+       },
+       [SRAM_CH05] = {
+               .name           = "ch5",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA5_PTR1,
+               .ptr2_reg       = DMA5_PTR2,
+               .cnt1_reg       = DMA5_CNT1,
+               .cnt2_reg       = DMA5_CNT2,
+       },
+       [SRAM_CH06] = {
+               .name           = "TS2 C",
+               .cmds_start     = 0x10140,
+               .ctrl_start     = 0x10680,
+               .cdt            = 0x108d0,
+               .fifo_start     = 0x6000,
+               .fifo_size      = 0x1000,
+               .ptr1_reg       = DMA5_PTR1,
+               .ptr2_reg       = DMA5_PTR2,
+               .cnt1_reg       = DMA5_CNT1,
+               .cnt2_reg       = DMA5_CNT2,
+       },
+       [SRAM_CH07] = {
+               .name           = "ch7",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA6_PTR1,
+               .ptr2_reg       = DMA6_PTR2,
+               .cnt1_reg       = DMA6_CNT1,
+               .cnt2_reg       = DMA6_CNT2,
+       },
+       [SRAM_CH08] = {
+               .name           = "ch8",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA7_PTR1,
+               .ptr2_reg       = DMA7_PTR2,
+               .cnt1_reg       = DMA7_CNT1,
+               .cnt2_reg       = DMA7_CNT2,
+       },
+       [SRAM_CH09] = {
+               .name           = "ch9",
+               .cmds_start     = 0x0,
+               .ctrl_start     = 0x0,
+               .cdt            = 0x0,
+               .fifo_start     = 0x0,
+               .fifo_size      = 0x0,
+               .ptr1_reg       = DMA8_PTR1,
+               .ptr2_reg       = DMA8_PTR2,
+               .cnt1_reg       = DMA8_CNT1,
+               .cnt2_reg       = DMA8_CNT2,
+       },
+};
+
+static int cx23885_risc_decode(u32 risc)
+{
+       static char *instr[16] = {
+               [ RISC_SYNC    >> 28 ] = "sync",
+               [ RISC_WRITE   >> 28 ] = "write",
+               [ RISC_WRITEC  >> 28 ] = "writec",
+               [ RISC_READ    >> 28 ] = "read",
+               [ RISC_READC   >> 28 ] = "readc",
+               [ RISC_JUMP    >> 28 ] = "jump",
+               [ RISC_SKIP    >> 28 ] = "skip",
+               [ RISC_WRITERM >> 28 ] = "writerm",
+               [ RISC_WRITECM >> 28 ] = "writecm",
+               [ RISC_WRITECR >> 28 ] = "writecr",
+       };
+       static int incr[16] = {
+               [ RISC_WRITE   >> 28 ] = 3,
+               [ RISC_JUMP    >> 28 ] = 3,
+               [ RISC_SKIP    >> 28 ] = 1,
+               [ RISC_SYNC    >> 28 ] = 1,
+               [ RISC_WRITERM >> 28 ] = 3,
+               [ RISC_WRITECM >> 28 ] = 3,
+               [ RISC_WRITECR >> 28 ] = 4,
+       };
+       static char *bits[] = {
+               "12",   "13",   "14",   "resync",
+               "cnt0", "cnt1", "18",   "19",
+               "20",   "21",   "22",   "23",
+               "irq1", "irq2", "eol",  "sol",
+       };
+       int i;
+
+       printk("0x%08x [ %s", risc,
+              instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
+       for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--)
+               if (risc & (1 << (i + 12)))
+                       printk(" %s", bits[i]);
+       printk(" count=%d ]\n", risc & 0xfff);
+       return incr[risc >> 28] ? incr[risc >> 28] : 1;
+}
+
+void cx23885_wakeup(struct cx23885_tsport *port,
+                   struct cx23885_dmaqueue *q, u32 count)
+{
+       struct cx23885_dev *dev = port->dev;
+       struct cx23885_buffer *buf;
+       int bc;
+
+       for (bc = 0;; bc++) {
+               if (list_empty(&q->active))
+                       break;
+               buf = list_entry(q->active.next,
+                                struct cx23885_buffer, vb.queue);
+
+               /* count comes from the hw and is is 16bit wide --
+                * this trick handles wrap-arounds correctly for
+                * up to 32767 buffers in flight... */
+               if ((s16) (count - buf->count) < 0)
+                       break;
+
+               do_gettimeofday(&buf->vb.ts);
+               dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i,
+                       count, buf->count);
+               buf->vb.state = STATE_DONE;
+               list_del(&buf->vb.queue);
+               wake_up(&buf->vb.done);
+       }
+       if (list_empty(&q->active)) {
+               del_timer(&q->timeout);
+       } else {
+               mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+       }
+       if (bc != 1)
+               printk("%s: %d buffers handled (should be 1)\n",
+                      __FUNCTION__, bc);
+}
+void cx23885_sram_channel_dump(struct cx23885_dev *dev,
+                              struct sram_channel *ch);
+
+int cx23885_sram_channel_setup(struct cx23885_dev *dev,
+                              struct sram_channel *ch,
+                              unsigned int bpl, u32 risc)
+{
+       unsigned int i, lines;
+       u32 cdt;
+
+       if (ch->cmds_start == 0)
+       {
+               dprintk(1, "%s() Erasing channel [%s]\n", __FUNCTION__,
+                       ch->name);
+               cx_write(ch->ptr1_reg, 0);
+               cx_write(ch->ptr2_reg, 0);
+               cx_write(ch->cnt2_reg, 0);
+               cx_write(ch->cnt1_reg, 0);
+               return 0;
+       } else {
+               dprintk(1, "%s() Configuring channel [%s]\n", __FUNCTION__,
+                       ch->name);
+       }
+
+       bpl   = (bpl + 7) & ~7; /* alignment */
+       cdt   = ch->cdt;
+       lines = ch->fifo_size / bpl;
+       if (lines > 6)
+               lines = 6;
+       BUG_ON(lines < 2);
+
+       cx_write(8 + 0, cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC) );
+       cx_write(8 + 4, cpu_to_le32(8) );
+       cx_write(8 + 8, cpu_to_le32(0) );
+
+       /* write CDT */
+       for (i = 0; i < lines; i++) {
+               dprintk(2, "%s() 0x%08x <- 0x%08x\n", __FUNCTION__, cdt + 16*i,
+                       ch->fifo_start + bpl*i);
+               cx_write(cdt + 16*i, ch->fifo_start + bpl*i);
+               cx_write(cdt + 16*i +  4, 0);
+               cx_write(cdt + 16*i +  8, 0);
+               cx_write(cdt + 16*i + 12, 0);
+       }
+
+       /* write CMDS */
+       if (ch->jumponly)
+               cx_write(ch->cmds_start +  0, 8);
+       else
+               cx_write(ch->cmds_start +  0, risc);
+       cx_write(ch->cmds_start +  4, 0); /* 64 bits 63-32 */
+       cx_write(ch->cmds_start +  8, cdt);
+       cx_write(ch->cmds_start + 12, (lines*16) >> 3);
+       cx_write(ch->cmds_start + 16, ch->ctrl_start);
+       if (ch->jumponly)
+               cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2) );
+       else
+               cx_write(ch->cmds_start + 20, 64 >> 2);
+       for (i = 24; i < 80; i += 4)
+               cx_write(ch->cmds_start + i, 0);
+
+       /* fill registers */
+       cx_write(ch->ptr1_reg, ch->fifo_start);
+       cx_write(ch->ptr2_reg, cdt);
+       cx_write(ch->cnt2_reg, (lines*16) >> 3);
+       cx_write(ch->cnt1_reg, (bpl >> 3) -1);
+
+       dprintk(2,"[bridge %d] sram setup %s: bpl=%d lines=%d\n",
+               dev->bridge,
+               ch->name,
+               bpl,
+               lines);
+
+       return 0;
+}
+
+void cx23885_sram_channel_dump(struct cx23885_dev *dev,
+                              struct sram_channel *ch)
+{
+       static char *name[] = {
+               "init risc lo",
+               "init risc hi",
+               "cdt base",
+               "cdt size",
+               "iq base",
+               "iq size",
+               "risc pc lo",
+               "risc pc hi",
+               "iq wr ptr",
+               "iq rd ptr",
+               "cdt current",
+               "pci target lo",
+               "pci target hi",
+               "line / byte",
+       };
+       u32 risc;
+       unsigned int i, j, n;
+
+       printk("%s: %s - dma channel status dump\n",
+              dev->name, ch->name);
+       for (i = 0; i < ARRAY_SIZE(name); i++)
+               printk("%s:   cmds: %-15s: 0x%08x\n",
+                      dev->name, name[i],
+                      cx_read(ch->cmds_start + 4*i));
+
+       for (i = 0; i < 4; i++) {
+               risc = cx_read(ch->cmds_start + 4 * (i + 14));
+               printk("%s:   risc%d: ", dev->name, i);
+               cx23885_risc_decode(risc);
+       }
+       for (i = 0; i < (64 >> 2); i += n) {
+               risc = cx_read(ch->ctrl_start + 4 * i);
+               /* No consideration for bits 63-32 */
+
+               printk("%s:   (0x%08x) iq %x: ", dev->name,
+                      ch->ctrl_start + 4 * i, i);
+               n = cx23885_risc_decode(risc);
+               for (j = 1; j < n; j++) {
+                       risc = cx_read(ch->ctrl_start + 4 * (i + j));
+                       printk("%s:   iq %x: 0x%08x [ arg #%d ]\n",
+                              dev->name, i+j, risc, j);
+               }
+       }
+
+       printk("%s: fifo: 0x%08x -> 0x%x\n",
+              dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
+       printk("%s: ctrl: 0x%08x -> 0x%x\n",
+              dev->name, ch->ctrl_start, ch->ctrl_start + 6*16);
+       printk("%s:   ptr1_reg: 0x%08x\n",
+              dev->name, cx_read(ch->ptr1_reg));
+       printk("%s:   ptr2_reg: 0x%08x\n",
+              dev->name, cx_read(ch->ptr2_reg));
+       printk("%s:   cnt1_reg: 0x%08x\n",
+              dev->name, cx_read(ch->cnt1_reg));
+       printk("%s:   cnt2_reg: 0x%08x\n",
+              dev->name, cx_read(ch->cnt2_reg));
+}
+
+void cx23885_risc_disasm(struct cx23885_tsport *port,
+                        struct btcx_riscmem *risc)
+{
+       struct cx23885_dev *dev = port->dev;
+       unsigned int i, j, n;
+
+       printk("%s: risc disasm: %p [dma=0x%08lx]\n",
+              dev->name, risc->cpu, (unsigned long)risc->dma);
+       for (i = 0; i < (risc->size >> 2); i += n) {
+               printk("%s:   %04d: ", dev->name, i);
+               n = cx23885_risc_decode(risc->cpu[i]);
+               for (j = 1; j < n; j++)
+                       printk("%s:   %04d: 0x%08x [ arg #%d ]\n",
+                              dev->name, i + j, risc->cpu[i + j], j);
+               if (risc->cpu[i] == RISC_JUMP)
+                       break;
+       }
+}
+
+void cx23885_shutdown(struct cx23885_dev *dev)
+{
+       /* disable RISC controller */
+       cx_write(DEV_CNTRL2, 0);
+
+       /* Disable all IR activity */
+       cx_write(IR_CNTRL_REG, 0);
+
+       /* Disable Video A/B activity */
+       cx_write(VID_A_DMA_CTL, 0);
+       cx_write(VID_B_DMA_CTL, 0);
+       cx_write(VID_C_DMA_CTL, 0);
+
+       /* Disable Audio activity */
+       cx_write(AUD_INT_DMA_CTL, 0);
+       cx_write(AUD_EXT_DMA_CTL, 0);
+
+       /* Disable Serial port */
+       cx_write(UART_CTL, 0);
+
+       /* Disable Interrupts */
+       cx_write(PCI_INT_MSK, 0);
+       cx_write(VID_A_INT_MSK, 0);
+       cx_write(VID_B_INT_MSK, 0);
+       cx_write(VID_C_INT_MSK, 0);
+       cx_write(AUDIO_INT_INT_MSK, 0);
+       cx_write(AUDIO_EXT_INT_MSK, 0);
+
+}
+
+void cx23885_reset(struct cx23885_dev *dev)
+{
+       dprintk(1, "%s()\n", __FUNCTION__);
+
+       cx23885_shutdown(dev);
+
+       cx_write(PCI_INT_STAT, 0xffffffff);
+       cx_write(VID_A_INT_STAT, 0xffffffff);
+       cx_write(VID_B_INT_STAT, 0xffffffff);
+       cx_write(VID_C_INT_STAT, 0xffffffff);
+       cx_write(AUDIO_INT_INT_STAT, 0xffffffff);
+       cx_write(AUDIO_EXT_INT_STAT, 0xffffffff);
+       cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
+
+       mdelay(100);
+
+       cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH01 ], 188*4, 0);
+       cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH02 ], 128, 0);
+       cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH03 ], 188*4, 0);
+       cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH04 ], 128, 0);
+       cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH05 ], 128, 0);
+       cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH06 ], 188*4, 0);
+       cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH07 ], 128, 0);
+       cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH08 ], 128, 0);
+       cx23885_sram_channel_setup(dev, &dev->sram_channels[ SRAM_CH09 ], 128, 0);
+
+       cx23885_gpio_setup(dev);
+}
+
+
+static int cx23885_pci_quirks(struct cx23885_dev *dev)
+{
+       dprintk(1, "%s()\n", __FUNCTION__);
+
+       /* The cx23885 bridge has a weird bug which causes NMI to be asserted
+        * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not
+        * occur on the cx23887 bridge.
+        */
+       if(dev->bridge == CX23885_BRIDGE_885)
+               cx_clear(RDR_TLCTL0, 1 << 4);
+
+       return 0;
+}
+
+static int get_resources(struct cx23885_dev *dev)
+{
+       if (request_mem_region(pci_resource_start(dev->pci,0),
+                              pci_resource_len(dev->pci,0),
+                              dev->name))
+               return 0;
+
+       printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
+               dev->name, (unsigned long long)pci_resource_start(dev->pci,0));
+
+       return -EBUSY;
+}
+
+static void cx23885_timeout(unsigned long data);
+int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
+                        u32 reg, u32 mask, u32 value);
+
+static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno)
+{
+       dprintk(1, "%s(portno=%d)\n", __FUNCTION__, portno);
+
+       /* Transport bus init dma queue  - Common settings */
+       port->dma_ctl_val        = 0x11; /* Enable RISC controller and Fifo */
+       port->ts_int_msk_val     = 0x1111; /* TS port bits for RISC */
+
+       spin_lock_init(&port->slock);
+       port->dev = dev;
+       port->nr = portno;
+
+       INIT_LIST_HEAD(&port->mpegq.active);
+       INIT_LIST_HEAD(&port->mpegq.queued);
+       port->mpegq.timeout.function = cx23885_timeout;
+       port->mpegq.timeout.data = (unsigned long)port;
+       init_timer(&port->mpegq.timeout);
+
+       switch(portno) {
+       case 1:
+               port->reg_gpcnt          = VID_B_GPCNT;
+               port->reg_gpcnt_ctl      = VID_B_GPCNT_CTL;
+               port->reg_dma_ctl        = VID_B_DMA_CTL;
+               port->reg_lngth          = VID_B_LNGTH;
+               port->reg_hw_sop_ctrl    = VID_B_HW_SOP_CTL;
+               port->reg_gen_ctrl       = VID_B_GEN_CTL;
+               port->reg_bd_pkt_status  = VID_B_BD_PKT_STATUS;
+               port->reg_sop_status     = VID_B_SOP_STATUS;
+               port->reg_fifo_ovfl_stat = VID_B_FIFO_OVFL_STAT;
+               port->reg_vld_misc       = VID_B_VLD_MISC;
+               port->reg_ts_clk_en      = VID_B_TS_CLK_EN;
+               port->reg_src_sel        = VID_B_SRC_SEL;
+               port->reg_ts_int_msk     = VID_B_INT_MSK;
+               port->reg_ts_int_stat   = VID_B_INT_STAT;
+               port->sram_chno          = SRAM_CH03; /* VID_B */
+               port->pci_irqmask        = 0x02; /* VID_B bit1 */
+               break;
+       case 2:
+               port->reg_gpcnt          = VID_C_GPCNT;
+               port->reg_gpcnt_ctl      = VID_C_GPCNT_CTL;
+               port->reg_dma_ctl        = VID_C_DMA_CTL;
+               port->reg_lngth          = VID_C_LNGTH;
+               port->reg_hw_sop_ctrl    = VID_C_HW_SOP_CTL;
+               port->reg_gen_ctrl       = VID_C_GEN_CTL;
+               port->reg_bd_pkt_status  = VID_C_BD_PKT_STATUS;
+               port->reg_sop_status     = VID_C_SOP_STATUS;
+               port->reg_fifo_ovfl_stat = VID_C_FIFO_OVFL_STAT;
+               port->reg_vld_misc       = VID_C_VLD_MISC;
+               port->reg_ts_clk_en      = VID_C_TS_CLK_EN;
+               port->reg_src_sel        = 0;
+               port->reg_ts_int_msk     = VID_C_INT_MSK;
+               port->reg_ts_int_stat    = VID_C_INT_STAT;
+               port->sram_chno          = SRAM_CH06; /* VID_C */
+               port->pci_irqmask        = 0x04; /* VID_C bit2 */
+               break;
+       default:
+               BUG();
+       }
+
+       cx23885_risc_stopper(dev->pci, &port->mpegq.stopper,
+                    port->reg_dma_ctl, port->dma_ctl_val, 0x00);
+
+       return 0;
+}
+
+static int cx23885_dev_setup(struct cx23885_dev *dev)
+{
+       int i;
+
+       mutex_init(&dev->lock);
+
+       atomic_inc(&dev->refcount);
+
+       dev->nr = cx23885_devcount++;
+       sprintf(dev->name, "cx23885[%d]", dev->nr);
+
+       mutex_lock(&devlist);
+       list_add_tail(&dev->devlist, &cx23885_devlist);
+       mutex_unlock(&devlist);
+
+       /* Configure the internal memory */
+       if(dev->pci->device == 0x8880) {
+               dev->bridge = CX23885_BRIDGE_887;
+               dev->sram_channels = cx23887_sram_channels;
+       } else
+       if(dev->pci->device == 0x8852) {
+               dev->bridge = CX23885_BRIDGE_885;
+               dev->sram_channels = cx23885_sram_channels;
+       } else
+               BUG();
+
+       dprintk(1, "%s() Memory configured for PCIe bridge type %d\n",
+               __FUNCTION__, dev->bridge);
+
+       /* board config */
+       dev->board = UNSET;
+       if (card[dev->nr] < cx23885_bcount)
+               dev->board = card[dev->nr];
+       for (i = 0; UNSET == dev->board  &&  i < cx23885_idcount; i++)
+               if (dev->pci->subsystem_vendor == cx23885_subids[i].subvendor &&
+                   dev->pci->subsystem_device == cx23885_subids[i].subdevice)
+                       dev->board = cx23885_subids[i].card;
+       if (UNSET == dev->board) {
+               dev->board = CX23885_BOARD_UNKNOWN;
+               cx23885_card_list(dev);
+       }
+
+       dev->pci_bus  = dev->pci->bus->number;
+       dev->pci_slot = PCI_SLOT(dev->pci->devfn);
+       dev->pci_irqmask = 0x001f00;
+
+       /* External Master 1 Bus */
+       dev->i2c_bus[0].nr = 0;
+       dev->i2c_bus[0].dev = dev;
+       dev->i2c_bus[0].reg_stat  = I2C1_STAT;
+       dev->i2c_bus[0].reg_ctrl  = I2C1_CTRL;
+       dev->i2c_bus[0].reg_addr  = I2C1_ADDR;
+       dev->i2c_bus[0].reg_rdata = I2C1_RDATA;
+       dev->i2c_bus[0].reg_wdata = I2C1_WDATA;
+       dev->i2c_bus[0].i2c_period = (0x9d << 24); /* 100kHz */
+
+       /* External Master 2 Bus */
+       dev->i2c_bus[1].nr = 1;
+       dev->i2c_bus[1].dev = dev;
+       dev->i2c_bus[1].reg_stat  = I2C2_STAT;
+       dev->i2c_bus[1].reg_ctrl  = I2C2_CTRL;
+       dev->i2c_bus[1].reg_addr  = I2C2_ADDR;
+       dev->i2c_bus[1].reg_rdata = I2C2_RDATA;
+       dev->i2c_bus[1].reg_wdata = I2C2_WDATA;
+       dev->i2c_bus[1].i2c_period = (0x9d << 24); /* 100kHz */
+
+       /* Internal Master 3 Bus */
+       dev->i2c_bus[2].nr = 2;
+       dev->i2c_bus[2].dev = dev;
+       dev->i2c_bus[2].reg_stat  = I2C3_STAT;
+       dev->i2c_bus[2].reg_ctrl  = I2C3_CTRL;
+       dev->i2c_bus[2].reg_addr  = I2C3_ADDR;
+       dev->i2c_bus[2].reg_rdata = I2C3_RDATA;
+       dev->i2c_bus[2].reg_wdata = I2C3_WDATA;
+       dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */
+
+       if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
+               cx23885_init_tsport(dev, &dev->ts1, 1);
+
+       if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB)
+               cx23885_init_tsport(dev, &dev->ts2, 2);
+
+       if (get_resources(dev) < 0) {
+               printk(KERN_ERR "CORE %s No more PCIe resources for "
+                      "subsystem: %04x:%04x\n",
+                      dev->name, dev->pci->subsystem_vendor,
+                      dev->pci->subsystem_device);
+
+               cx23885_devcount--;
+               goto fail_free;
+       }
+
+       /* PCIe stuff */
+       dev->lmmio = ioremap(pci_resource_start(dev->pci,0),
+                            pci_resource_len(dev->pci,0));
+
+       dev->bmmio = (u8 __iomem *)dev->lmmio;
+
+       printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+              dev->name, dev->pci->subsystem_vendor,
+              dev->pci->subsystem_device, cx23885_boards[dev->board].name,
+              dev->board, card[dev->nr] == dev->board ?
+              "insmod option" : "autodetected");
+
+       cx23885_pci_quirks(dev);
+
+       /* init hardware */
+       cx23885_reset(dev);
+
+       cx23885_i2c_register(&dev->i2c_bus[0]);
+       cx23885_i2c_register(&dev->i2c_bus[1]);
+       cx23885_i2c_register(&dev->i2c_bus[2]);
+       cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
+       cx23885_card_setup(dev);
+       cx23885_ir_init(dev);
+
+       if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) {
+               if (cx23885_dvb_register(&dev->ts1) < 0) {
+                       printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n",
+                              __FUNCTION__);
+               }
+       }
+
+       if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) {
+               if (cx23885_dvb_register(&dev->ts2) < 0) {
+                       printk(KERN_ERR "%s() Failed to register dvb adapters on VID_C\n",
+                              __FUNCTION__);
+               }
+       }
+
+       return 0;
+
+fail_free:
+       kfree(dev);
+       return -ENODEV;
+}
+
+void cx23885_dev_unregister(struct cx23885_dev *dev)
+{
+       release_mem_region(pci_resource_start(dev->pci,0),
+                          pci_resource_len(dev->pci,0));
+
+       if (!atomic_dec_and_test(&dev->refcount))
+               return;
+
+       if(cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
+               cx23885_dvb_unregister(&dev->ts1);
+
+       if(cx23885_boards[dev->board].portc == CX23885_MPEG_DVB)
+               cx23885_dvb_unregister(&dev->ts2);
+
+       cx23885_i2c_unregister(&dev->i2c_bus[2]);
+       cx23885_i2c_unregister(&dev->i2c_bus[1]);
+       cx23885_i2c_unregister(&dev->i2c_bus[0]);
+
+       iounmap(dev->lmmio);
+}
+
+static u32* cx23885_risc_field(u32 *rp, struct scatterlist *sglist,
+                              unsigned int offset, u32 sync_line,
+                              unsigned int bpl, unsigned int padding,
+                              unsigned int lines)
+{
+       struct scatterlist *sg;
+       unsigned int line, todo;
+
+       /* sync instruction */
+       if (sync_line != NO_SYNC_LINE)
+               *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
+
+       /* scan lines */
+       sg = sglist;
+       for (line = 0; line < lines; line++) {
+               while (offset && offset >= sg_dma_len(sg)) {
+                       offset -= sg_dma_len(sg);
+                       sg++;
+               }
+               if (bpl <= sg_dma_len(sg)-offset) {
+                       /* fits into current chunk */
+                       *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
+                       *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
+                       *(rp++)=cpu_to_le32(0); /* bits 63-32 */
+                       offset+=bpl;
+               } else {
+                       /* scanline needs to be split */
+                       todo = bpl;
+                       *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
+                                           (sg_dma_len(sg)-offset));
+                       *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
+                       *(rp++)=cpu_to_le32(0); /* bits 63-32 */
+                       todo -= (sg_dma_len(sg)-offset);
+                       offset = 0;
+                       sg++;
+                       while (todo > sg_dma_len(sg)) {
+                               *(rp++)=cpu_to_le32(RISC_WRITE|
+                                                   sg_dma_len(sg));
+                               *(rp++)=cpu_to_le32(sg_dma_address(sg));
+                               *(rp++)=cpu_to_le32(0); /* bits 63-32 */
+                               todo -= sg_dma_len(sg);
+                               sg++;
+                       }
+                       *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
+                       *(rp++)=cpu_to_le32(sg_dma_address(sg));
+                       *(rp++)=cpu_to_le32(0); /* bits 63-32 */
+                       offset += todo;
+               }
+               offset += padding;
+       }
+
+       return rp;
+}
+
+int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
+                       struct scatterlist *sglist, unsigned int top_offset,
+                       unsigned int bottom_offset, unsigned int bpl,
+                       unsigned int padding, unsigned int lines)
+{
+       u32 instructions, fields;
+       u32 *rp;
+       int rc;
+
+       fields = 0;
+       if (UNSET != top_offset)
+               fields++;
+       if (UNSET != bottom_offset)
+               fields++;
+
+       /* estimate risc mem: worst case is one write per page border +
+          one write per scan line + syncs + jump (all 2 dwords).  Padding
+          can cause next bpl to start close to a page border.  First DMA
+          region may be smaller than PAGE_SIZE */
+       /* write and jump need and extra dword */
+       instructions  = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
+       instructions += 2;
+       if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0)
+               return rc;
+
+       /* write risc instructions */
+       rp = risc->cpu;
+       if (UNSET != top_offset)
+               rp = cx23885_risc_field(rp, sglist, top_offset, 0,
+                                       bpl, padding, lines);
+       if (UNSET != bottom_offset)
+               rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200,
+                                       bpl, padding, lines);
+
+       /* save pointer to jmp instruction address */
+       risc->jmp = rp;
+       BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
+       return 0;
+}
+
+int cx23885_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
+                           struct scatterlist *sglist, unsigned int bpl,
+                           unsigned int lines)
+{
+       u32 instructions;
+       u32 *rp;
+       int rc;
+
+       /* estimate risc mem: worst case is one write per page border +
+          one write per scan line + syncs + jump (all 2 dwords).  Here
+          there is no padding and no sync.  First DMA region may be smaller
+          than PAGE_SIZE */
+       /* Jump and write need an extra dword */
+       instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
+       instructions += 1;
+
+       if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0)
+               return rc;
+
+       /* write risc instructions */
+       rp = risc->cpu;
+       rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines);
+
+       /* save pointer to jmp instruction address */
+       risc->jmp = rp;
+       BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
+       return 0;
+}
+
+int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
+                        u32 reg, u32 mask, u32 value)
+{
+       u32 *rp;
+       int rc;
+
+       if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
+               return rc;
+
+       /* write risc instructions */
+       rp = risc->cpu;
+       *(rp++) = cpu_to_le32(RISC_WRITECR  | RISC_IRQ2);
+       *(rp++) = cpu_to_le32(reg);
+       *(rp++) = cpu_to_le32(value);
+       *(rp++) = cpu_to_le32(mask);
+       *(rp++) = cpu_to_le32(RISC_JUMP);
+       *(rp++) = cpu_to_le32(risc->dma);
+       *(rp++) = cpu_to_le32(0); /* bits 63-32 */
+       return 0;
+}
+
+void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf)
+{
+       struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
+
+       BUG_ON(in_interrupt());
+       videobuf_waiton(&buf->vb, 0, 0);
+       videobuf_dma_unmap(q, dma);
+       videobuf_dma_free(dma);
+       btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
+       buf->vb.state = STATE_NEEDS_INIT;
+}
+
+static int cx23885_start_dma(struct cx23885_tsport *port,
+                            struct cx23885_dmaqueue *q,
+                            struct cx23885_buffer   *buf)
+{
+       struct cx23885_dev *dev = port->dev;
+
+       dprintk(1, "%s() w: %d, h: %d, f: %d\n", __FUNCTION__,
+               buf->vb.width, buf->vb.height, buf->vb.field);
+
+       /* setup fifo + format */
+       cx23885_sram_channel_setup(dev,
+                                  &dev->sram_channels[ port->sram_chno ],
+                                  port->ts_packet_size, buf->risc.dma);
+       if(debug > 5) {
+               cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ] );
+               cx23885_risc_disasm(port, &buf->risc);
+       }
+
+       /* write TS length to chip */
+       cx_write(port->reg_lngth, buf->vb.width);
+
+       if ( (!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) &&
+               (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) ) {
+               printk( "%s() Failed. Unsupported value in .portb/c (0x%08x)/(0x%08x)\n",
+                       __FUNCTION__,
+                       cx23885_boards[dev->board].portb,
+                       cx23885_boards[dev->board].portc );
+               return -EINVAL;
+       }
+
+       udelay(100);
+
+       /* If the port supports SRC SELECT, configure it */
+       if(port->reg_src_sel)
+               cx_write(port->reg_src_sel, port->src_sel_val);
+
+       cx_write(port->reg_hw_sop_ctrl, 0x47 << 16 | 188 << 4);
+       cx_write(port->reg_ts_clk_en, port->ts_clk_en_val);
+       cx_write(port->reg_vld_misc, 0x00);
+       cx_write(port->reg_gen_ctrl, port->gen_ctrl_val);
+       udelay(100);
+
+       // NOTE: this is 2 (reserved) for portb, does it matter?
+       /* reset counter to zero */
+       cx_write(port->reg_gpcnt_ctl, 3);
+       q->count = 1;
+
+       switch(dev->bridge) {
+       case CX23885_BRIDGE_885:
+       case CX23885_BRIDGE_887:
+               /* enable irqs */
+               dprintk(1, "%s() enabling TS int's and DMA\n", __FUNCTION__ );
+               cx_set(port->reg_ts_int_msk,  port->ts_int_msk_val);
+               cx_set(port->reg_dma_ctl, port->dma_ctl_val);
+               cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask);
+               break;
+       default:
+               BUG();
+       }
+
+       cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */
+
+       return 0;
+}
+
+static int cx23885_stop_dma(struct cx23885_tsport *port)
+{
+       struct cx23885_dev *dev = port->dev;
+       dprintk(1, "%s()\n", __FUNCTION__);
+
+       /* Stop interrupts and DMA */
+       cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val);
+       cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
+
+       return 0;
+}
+
+static int cx23885_restart_queue(struct cx23885_tsport *port,
+                               struct cx23885_dmaqueue *q)
+{
+       struct cx23885_dev *dev = port->dev;
+       struct cx23885_buffer *buf;
+
+       dprintk(5, "%s()\n", __FUNCTION__);
+       if (list_empty(&q->active))
+       {
+               struct cx23885_buffer *prev;
+               prev = NULL;
+
+               dprintk(5, "%s() queue is empty\n", __FUNCTION__);
+
+               for (;;) {
+                       if (list_empty(&q->queued))
+                               return 0;
+                       buf = list_entry(q->queued.next, struct cx23885_buffer,
+                                        vb.queue);
+                       if (NULL == prev) {
+                               list_del(&buf->vb.queue);
+                               list_add_tail(&buf->vb.queue, &q->active);
+                               cx23885_start_dma(port, q, buf);
+                               buf->vb.state = STATE_ACTIVE;
+                               buf->count    = q->count++;
+                               mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
+                               dprintk(5, "[%p/%d] restart_queue - first active\n",
+                                       buf, buf->vb.i);
+
+                       } else if (prev->vb.width  == buf->vb.width  &&
+                                  prev->vb.height == buf->vb.height &&
+                                  prev->fmt       == buf->fmt) {
+                               list_del(&buf->vb.queue);
+                               list_add_tail(&buf->vb.queue, &q->active);
+                               buf->vb.state = STATE_ACTIVE;
+                               buf->count    = q->count++;
+                               prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+                               prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */
+                               dprintk(5,"[%p/%d] restart_queue - move to active\n",
+                                       buf, buf->vb.i);
+                       } else {
+                               return 0;
+                       }
+                       prev = buf;
+               }
+               return 0;
+       }
+
+       buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue);
+       dprintk(2, "restart_queue [%p/%d]: restart dma\n",
+               buf, buf->vb.i);
+       cx23885_start_dma(port, q, buf);
+       list_for_each_entry(buf, &q->active, vb.queue)
+               buf->count = q->count++;
+       mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+       return 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port,
+                       struct cx23885_buffer *buf, enum v4l2_field field)
+{
+       struct cx23885_dev *dev = port->dev;
+       int size = port->ts_packet_size * port->ts_packet_count;
+       int rc;
+
+       dprintk(1, "%s: %p\n", __FUNCTION__, buf);
+       if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
+               return -EINVAL;
+
+       if (STATE_NEEDS_INIT == buf->vb.state) {
+               buf->vb.width  = port->ts_packet_size;
+               buf->vb.height = port->ts_packet_count;
+               buf->vb.size   = size;
+               buf->vb.field  = field /*V4L2_FIELD_TOP*/;
+
+               if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
+                       goto fail;
+               cx23885_risc_databuffer(dev->pci, &buf->risc,
+                                       videobuf_to_dma(&buf->vb)->sglist,
+                                       buf->vb.width, buf->vb.height);
+       }
+       buf->vb.state = STATE_PREPARED;
+       return 0;
+
+ fail:
+       cx23885_free_buffer(q, buf);
+       return rc;
+}
+
+void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
+{
+       struct cx23885_buffer    *prev;
+       struct cx23885_dev *dev = port->dev;
+       struct cx23885_dmaqueue  *cx88q = &port->mpegq;
+
+       /* add jump to stopper */
+       buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+       buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);
+       buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
+
+       if (list_empty(&cx88q->active)) {
+               dprintk( 1, "queue is empty - first active\n" );
+               list_add_tail(&buf->vb.queue, &cx88q->active);
+               cx23885_start_dma(port, cx88q, buf);
+               buf->vb.state = STATE_ACTIVE;
+               buf->count    = cx88q->count++;
+               mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT);
+               dprintk(1, "[%p/%d] %s - first active\n",
+                       buf, buf->vb.i, __FUNCTION__);
+       } else {
+               dprintk( 1, "queue is not empty - append to active\n" );
+               prev = list_entry(cx88q->active.prev, struct cx23885_buffer,
+                                 vb.queue);
+               list_add_tail(&buf->vb.queue, &cx88q->active);
+               buf->vb.state = STATE_ACTIVE;
+               buf->count    = cx88q->count++;
+               prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+               prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */
+               dprintk( 1, "[%p/%d] %s - append to active\n",
+                        buf, buf->vb.i, __FUNCTION__);
+       }
+}
+
+/* ----------------------------------------------------------- */
+
+static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
+                             int restart)
+{
+       struct cx23885_dev *dev = port->dev;
+       struct cx23885_dmaqueue *q = &port->mpegq;
+       struct cx23885_buffer *buf;
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->slock, flags);
+       while (!list_empty(&q->active)) {
+               buf = list_entry(q->active.next, struct cx23885_buffer,
+                                vb.queue);
+               list_del(&buf->vb.queue);
+               buf->vb.state = STATE_ERROR;
+               wake_up(&buf->vb.done);
+               dprintk(1, "[%p/%d] %s - dma=0x%08lx\n",
+                       buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
+       }
+       if (restart) {
+               dprintk(1, "restarting queue\n" );
+               cx23885_restart_queue(port, q);
+       }
+       spin_unlock_irqrestore(&port->slock, flags);
+}
+
+void cx23885_cancel_buffers(struct cx23885_tsport *port)
+{
+       struct cx23885_dev *dev = port->dev;
+       struct cx23885_dmaqueue *q = &port->mpegq;
+
+       dprintk(1, "%s()\n", __FUNCTION__);
+       del_timer_sync(&q->timeout);
+       cx23885_stop_dma(port);
+       do_cancel_buffers(port, "cancel", 0);
+}
+
+static void cx23885_timeout(unsigned long data)
+{
+       struct cx23885_tsport *port = (struct cx23885_tsport *)data;
+       struct cx23885_dev *dev = port->dev;
+
+       dprintk(1, "%s()\n",__FUNCTION__);
+
+       if (debug > 5)
+               cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]);
+
+       cx23885_stop_dma(port);
+       do_cancel_buffers(port, "timeout", 1);
+}
+
+static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status)
+{
+       struct cx23885_dev *dev = port->dev;
+       int handled = 0;
+       u32 count;
+
+       if ( (status & VID_BC_MSK_OPC_ERR) ||
+            (status & VID_BC_MSK_BAD_PKT) ||
+            (status & VID_BC_MSK_SYNC) ||
+            (status & VID_BC_MSK_OF))
+       {
+               if (status & VID_BC_MSK_OPC_ERR)
+                       dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR);
+               if (status & VID_BC_MSK_BAD_PKT)
+                       dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", VID_BC_MSK_BAD_PKT);
+               if (status & VID_BC_MSK_SYNC)
+                       dprintk(7, " (VID_BC_MSK_SYNC    0x%08x)\n", VID_BC_MSK_SYNC);
+               if (status & VID_BC_MSK_OF)
+                       dprintk(7, " (VID_BC_MSK_OF      0x%08x)\n", VID_BC_MSK_OF);
+
+               printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name);
+
+               cx_clear(port->reg_dma_ctl, port->dma_ctl_val);
+               cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]);
+
+       } else if (status & VID_BC_MSK_RISCI1) {
+
+               dprintk(7, " (RISCI1            0x%08x)\n", VID_BC_MSK_RISCI1);
+
+               spin_lock(&port->slock);
+               count = cx_read(port->reg_gpcnt);
+               cx23885_wakeup(port, &port->mpegq, count);
+               spin_unlock(&port->slock);
+
+       } else if (status & VID_BC_MSK_RISCI2) {
+
+               dprintk(7, " (RISCI2            0x%08x)\n", VID_BC_MSK_RISCI2);
+
+               spin_lock(&port->slock);
+               cx23885_restart_queue(port, &port->mpegq);
+               spin_unlock(&port->slock);
+
+       }
+       if (status) {
+               cx_write(port->reg_ts_int_stat, status);
+               handled = 1;
+       }
+
+       return handled;
+}
+
+static irqreturn_t cx23885_irq(int irq, void *dev_id)
+{
+       struct cx23885_dev *dev = dev_id;
+       struct cx23885_tsport *ts1 = &dev->ts1;
+       struct cx23885_tsport *ts2 = &dev->ts2;
+       u32 pci_status, pci_mask;
+       u32 ts1_status, ts1_mask;
+       u32 ts2_status, ts2_mask;
+       int ts1_count = 0, ts2_count = 0, handled = 0;
+
+       pci_status = cx_read(PCI_INT_STAT);
+       pci_mask = cx_read(PCI_INT_MSK);
+       ts1_status = cx_read(VID_B_INT_STAT);
+       ts1_mask = cx_read(VID_B_INT_MSK);
+       ts2_status = cx_read(VID_C_INT_STAT);
+       ts2_mask = cx_read(VID_C_INT_MSK);
+
+       if ( (pci_status == 0) && (ts2_status == 0) && (ts1_status == 0) )
+               goto out;
+
+       ts1_count = cx_read(ts1->reg_gpcnt);
+       ts2_count = cx_read(ts2->reg_gpcnt);
+       dprintk(7, "pci_status: 0x%08x  pci_mask: 0x%08x\n", pci_status, pci_mask );
+       dprintk(7, "ts1_status: 0x%08x  ts1_mask: 0x%08x count: 0x%x\n", ts1_status, ts1_mask, ts1_count );
+       dprintk(7, "ts2_status: 0x%08x  ts2_mask: 0x%08x count: 0x%x\n", ts2_status, ts2_mask, ts2_count );
+
+       if ( (pci_status & PCI_MSK_RISC_RD) ||
+            (pci_status & PCI_MSK_RISC_WR) ||
+            (pci_status & PCI_MSK_AL_RD) ||
+            (pci_status & PCI_MSK_AL_WR) ||
+            (pci_status & PCI_MSK_APB_DMA) ||
+            (pci_status & PCI_MSK_VID_C) ||
+            (pci_status & PCI_MSK_VID_B) ||
+            (pci_status & PCI_MSK_VID_A) ||
+            (pci_status & PCI_MSK_AUD_INT) ||
+            (pci_status & PCI_MSK_AUD_EXT) )
+       {
+
+               if (pci_status & PCI_MSK_RISC_RD)
+                       dprintk(7, " (PCI_MSK_RISC_RD   0x%08x)\n", PCI_MSK_RISC_RD);
+               if (pci_status & PCI_MSK_RISC_WR)
+                       dprintk(7, " (PCI_MSK_RISC_WR   0x%08x)\n", PCI_MSK_RISC_WR);
+               if (pci_status & PCI_MSK_AL_RD)
+                       dprintk(7, " (PCI_MSK_AL_RD     0x%08x)\n", PCI_MSK_AL_RD);
+               if (pci_status & PCI_MSK_AL_WR)
+                       dprintk(7, " (PCI_MSK_AL_WR     0x%08x)\n", PCI_MSK_AL_WR);
+               if (pci_status & PCI_MSK_APB_DMA)
+                       dprintk(7, " (PCI_MSK_APB_DMA   0x%08x)\n", PCI_MSK_APB_DMA);
+               if (pci_status & PCI_MSK_VID_C)
+                       dprintk(7, " (PCI_MSK_VID_C     0x%08x)\n", PCI_MSK_VID_C);
+               if (pci_status & PCI_MSK_VID_B)
+                       dprintk(7, " (PCI_MSK_VID_B     0x%08x)\n", PCI_MSK_VID_B);
+               if (pci_status & PCI_MSK_VID_A)
+                       dprintk(7, " (PCI_MSK_VID_A     0x%08x)\n", PCI_MSK_VID_A);
+               if (pci_status & PCI_MSK_AUD_INT)
+                       dprintk(7, " (PCI_MSK_AUD_INT   0x%08x)\n", PCI_MSK_AUD_INT);
+               if (pci_status & PCI_MSK_AUD_EXT)
+                       dprintk(7, " (PCI_MSK_AUD_EXT   0x%08x)\n", PCI_MSK_AUD_EXT);
+
+       }
+
+       if (ts1_status)
+               handled += cx23885_irq_ts(ts1, ts1_status);
+
+       if (ts2_status)
+               handled += cx23885_irq_ts(ts2, ts2_status);
+
+       if (handled)
+               cx_write(PCI_INT_STAT, pci_status);
+out:
+       return IRQ_RETVAL(handled);
+}
+
+static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
+                                    const struct pci_device_id *pci_id)
+{
+       struct cx23885_dev *dev;
+       int err;
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (NULL == dev)
+               return -ENOMEM;
+
+       /* pci init */
+       dev->pci = pci_dev;
+       if (pci_enable_device(pci_dev)) {
+               err = -EIO;
+               goto fail_free;
+       }
+
+       if (cx23885_dev_setup(dev) < 0) {
+               err = -EINVAL;
+               goto fail_free;
+       }
+
+       /* print pci info */
+       pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
+       pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER,  &dev->pci_lat);
+       printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
+              "latency: %d, mmio: 0x%llx\n", dev->name,
+              pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
+              dev->pci_lat, (unsigned long long)pci_resource_start(pci_dev,0));
+
+       pci_set_master(pci_dev);
+       if (!pci_dma_supported(pci_dev, 0xffffffff)) {
+               printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
+               err = -EIO;
+               goto fail_irq;
+       }
+
+       err = request_irq(pci_dev->irq, cx23885_irq,
+                         IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
+       if (err < 0) {
+               printk(KERN_ERR "%s: can't get IRQ %d\n",
+                      dev->name, pci_dev->irq);
+               goto fail_irq;
+       }
+
+       pci_set_drvdata(pci_dev, dev);
+       return 0;
+
+fail_irq:
+       cx23885_dev_unregister(dev);
+fail_free:
+       kfree(dev);
+       return err;
+}
+
+static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
+{
+       struct cx23885_dev *dev = pci_get_drvdata(pci_dev);
+
+       cx23885_shutdown(dev);
+
+       pci_disable_device(pci_dev);
+
+       /* unregister stuff */
+       free_irq(pci_dev->irq, dev);
+       pci_set_drvdata(pci_dev, NULL);
+
+       mutex_lock(&devlist);
+       list_del(&dev->devlist);
+       mutex_unlock(&devlist);
+
+       cx23885_dev_unregister(dev);
+       kfree(dev);
+}
+
+static struct pci_device_id cx23885_pci_tbl[] = {
+       {
+               /* CX23885 */
+               .vendor       = 0x14f1,
+               .device       = 0x8852,
+               .subvendor    = PCI_ANY_ID,
+               .subdevice    = PCI_ANY_ID,
+       },{
+               /* CX23887 Rev 2 */
+               .vendor       = 0x14f1,
+               .device       = 0x8880,
+               .subvendor    = PCI_ANY_ID,
+               .subdevice    = PCI_ANY_ID,
+       },{
+               /* --- end of list --- */
+       }
+};
+MODULE_DEVICE_TABLE(pci, cx23885_pci_tbl);
+
+static struct pci_driver cx23885_pci_driver = {
+       .name     = "cx23885",
+       .id_table = cx23885_pci_tbl,
+       .probe    = cx23885_initdev,
+       .remove   = __devexit_p(cx23885_finidev),
+       /* TODO */
+       .suspend  = NULL,
+       .resume   = NULL,
+};
+
+static int cx23885_init(void)
+{
+       printk(KERN_INFO "cx23885 driver version %d.%d.%d loaded\n",
+              (CX23885_VERSION_CODE >> 16) & 0xff,
+              (CX23885_VERSION_CODE >>  8) & 0xff,
+              CX23885_VERSION_CODE & 0xff);
+#ifdef SNAPSHOT
+       printk(KERN_INFO "cx23885: snapshot date %04d-%02d-%02d\n",
+              SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
+#endif
+       return pci_register_driver(&cx23885_pci_driver);
+}
+
+static void cx23885_fini(void)
+{
+       pci_unregister_driver(&cx23885_pci_driver);
+}
+
+module_init(cx23885_init);
+module_exit(cx23885_fini);
+
+/* ----------------------------------------------------------- */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
+ */
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
new file mode 100644 (file)
index 0000000..eda8c05
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ *  Driver for the Conexant CX23885 PCIe bridge
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/kthread.h>
+#include <linux/file.h>
+#include <linux/suspend.h>
+
+#include "cx23885.h"
+#include <media/v4l2-common.h>
+
+#include "s5h1409.h"
+#include "mt2131.h"
+#include "lgdt330x.h"
+#include "dvb-pll.h"
+
+static unsigned int debug = 0;
+
+#define dprintk(level,fmt, arg...)     if (debug >= level) \
+       printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg)
+
+/* ------------------------------------------------------------------ */
+
+static int dvb_buf_setup(struct videobuf_queue *q,
+                        unsigned int *count, unsigned int *size)
+{
+       struct cx23885_tsport *port = q->priv_data;
+
+       port->ts_packet_size  = 188 * 4;
+       port->ts_packet_count = 32;
+
+       *size  = port->ts_packet_size * port->ts_packet_count;
+       *count = 32;
+       return 0;
+}
+
+static int dvb_buf_prepare(struct videobuf_queue *q,
+                          struct videobuf_buffer *vb, enum v4l2_field field)
+{
+       struct cx23885_tsport *port = q->priv_data;
+       return cx23885_buf_prepare(q, port, (struct cx23885_buffer*)vb, field);
+}
+
+static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
+{
+       struct cx23885_tsport *port = q->priv_data;
+       cx23885_buf_queue(port, (struct cx23885_buffer*)vb);
+}
+
+static void dvb_buf_release(struct videobuf_queue *q,
+                           struct videobuf_buffer *vb)
+{
+       cx23885_free_buffer(q, (struct cx23885_buffer*)vb);
+}
+
+static struct videobuf_queue_ops dvb_qops = {
+       .buf_setup    = dvb_buf_setup,
+       .buf_prepare  = dvb_buf_prepare,
+       .buf_queue    = dvb_buf_queue,
+       .buf_release  = dvb_buf_release,
+};
+
+static struct s5h1409_config hauppauge_generic_config = {
+       .demod_address = 0x32 >> 1,
+       .output_mode   = S5H1409_SERIAL_OUTPUT,
+       .gpio          = S5H1409_GPIO_ON,
+       .if_freq       = 44000,
+       .inversion     = S5H1409_INVERSION_OFF,
+       .status_mode   = S5H1409_DEMODLOCKING
+};
+
+static struct s5h1409_config hauppauge_hvr1800lp_config = {
+       .demod_address = 0x32 >> 1,
+       .output_mode   = S5H1409_SERIAL_OUTPUT,
+       .gpio          = S5H1409_GPIO_OFF,
+       .if_freq       = 44000,
+       .inversion     = S5H1409_INVERSION_OFF,
+       .status_mode   = S5H1409_DEMODLOCKING
+};
+
+static struct mt2131_config hauppauge_generic_tunerconfig = {
+       0x61
+};
+
+static struct lgdt330x_config fusionhdtv_5_express = {
+       .demod_address = 0x0e,
+       .demod_chip = LGDT3303,
+       .serial_mpeg = 0x40,
+};
+
+static int dvb_register(struct cx23885_tsport *port)
+{
+       struct cx23885_dev *dev = port->dev;
+       struct cx23885_i2c *i2c_bus = NULL;
+
+       /* init struct videobuf_dvb */
+       port->dvb.name = dev->name;
+
+       /* init frontend */
+       switch (dev->board) {
+       case CX23885_BOARD_HAUPPAUGE_HVR1250:
+       case CX23885_BOARD_HAUPPAUGE_HVR1800:
+               i2c_bus = &dev->i2c_bus[0];
+               port->dvb.frontend = dvb_attach(s5h1409_attach,
+                                               &hauppauge_generic_config,
+                                               &i2c_bus->i2c_adap);
+               if (port->dvb.frontend != NULL) {
+                       dvb_attach(mt2131_attach, port->dvb.frontend,
+                                  &i2c_bus->i2c_adap,
+                                  &hauppauge_generic_tunerconfig, 0);
+               }
+               break;
+       case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
+               i2c_bus = &dev->i2c_bus[0];
+               port->dvb.frontend = dvb_attach(s5h1409_attach,
+                                               &hauppauge_hvr1800lp_config,
+                                               &i2c_bus->i2c_adap);
+               if (port->dvb.frontend != NULL) {
+                       dvb_attach(mt2131_attach, port->dvb.frontend,
+                                  &i2c_bus->i2c_adap,
+                                  &hauppauge_generic_tunerconfig, 0);
+               }
+               break;
+       case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
+               i2c_bus = &dev->i2c_bus[0];
+               port->dvb.frontend = dvb_attach(lgdt330x_attach,
+                                               &fusionhdtv_5_express,
+                                               &i2c_bus->i2c_adap);
+               if (port->dvb.frontend != NULL) {
+                       dvb_attach(dvb_pll_attach, port->dvb.frontend, 0x61,
+                                  &i2c_bus->i2c_adap, DVB_PLL_LG_TDVS_H06XF);
+               }
+               break;
+       default:
+               printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
+                      dev->name);
+               break;
+       }
+       if (NULL == port->dvb.frontend) {
+               printk("%s: frontend initialization failed\n", dev->name);
+               return -1;
+       }
+
+       /* Put the analog decoder in standby to keep it quiet */
+       cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
+
+       /* register everything */
+       return videobuf_dvb_register(&port->dvb, THIS_MODULE, port,
+                                    &dev->pci->dev);
+}
+
+int cx23885_dvb_register(struct cx23885_tsport *port)
+{
+       struct cx23885_dev *dev = port->dev;
+       int err;
+
+       dprintk(1, "%s\n", __FUNCTION__);
+       dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
+               dev->board,
+               dev->name,
+               dev->pci_bus,
+               dev->pci_slot);
+
+       err = -ENODEV;
+
+       /* dvb stuff */
+       printk("%s: cx23885 based dvb card\n", dev->name);
+       videobuf_queue_pci_init(&port->dvb.dvbq, &dvb_qops, dev->pci, &port->slock,
+                           V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP,
+                           sizeof(struct cx23885_buffer), port);
+       err = dvb_register(port);
+       if (err != 0)
+               printk("%s() dvb_register failed err = %d\n", __FUNCTION__, err);
+
+       return err;
+}
+
+int cx23885_dvb_unregister(struct cx23885_tsport *port)
+{
+       /* dvb */
+       if(port->dvb.frontend)
+               videobuf_dvb_unregister(&port->dvb);
+
+       return 0;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
+*/
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
new file mode 100644 (file)
index 0000000..b517c8b
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ *  Driver for the Conexant CX23885 PCIe bridge
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#include "cx23885.h"
+
+#include <media/v4l2-common.h>
+
+static unsigned int i2c_debug = 0;
+module_param(i2c_debug, int, 0644);
+MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
+
+static unsigned int i2c_scan = 0;
+module_param(i2c_scan, int, 0444);
+MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
+
+#define dprintk(level,fmt, arg...)     if (i2c_debug >= level) \
+       printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg)
+
+#define I2C_WAIT_DELAY 32
+#define I2C_WAIT_RETRY 64
+
+#define I2C_EXTEND  (1 << 3)
+#define I2C_NOSTOP  (1 << 4)
+
+static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
+{
+       struct cx23885_i2c *bus = i2c_adap->algo_data;
+       struct cx23885_dev *dev = bus->dev;
+       return cx_read(bus->reg_stat) & 0x01;
+}
+
+static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
+{
+       struct cx23885_i2c *bus = i2c_adap->algo_data;
+       struct cx23885_dev *dev = bus->dev;
+       return cx_read(bus->reg_stat) & 0x02 ? 1 : 0;
+}
+
+static int i2c_wait_done(struct i2c_adapter *i2c_adap)
+{
+       int count;
+
+       for (count = 0; count < I2C_WAIT_RETRY; count++) {
+               if (!i2c_is_busy(i2c_adap))
+                       break;
+               udelay(I2C_WAIT_DELAY);
+       }
+
+       if (I2C_WAIT_RETRY == count)
+               return 0;
+
+       return 1;
+}
+
+static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
+                        const struct i2c_msg *msg, int last)
+{
+       struct cx23885_i2c *bus = i2c_adap->algo_data;
+       struct cx23885_dev *dev = bus->dev;
+       u32 wdata, addr, ctrl;
+       int retval, cnt;
+
+       dprintk(1, "%s()\n", __FUNCTION__);
+       /* Deal with i2c probe functions with zero payload */
+       if (msg->len == 0) {
+               cx_write(bus->reg_addr, msg->addr << 25);
+               cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2));
+               if (!i2c_wait_done(i2c_adap))
+                       return -EIO;
+               if (!i2c_slave_did_ack(i2c_adap))
+                       return -EIO;
+
+               dprintk(1, "%s() returns 0\n", __FUNCTION__);
+               return 0;
+       }
+
+
+       /* dev, reg + first byte */
+       addr = (msg->addr << 25) | msg->buf[0];
+       wdata = msg->buf[0];
+       ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
+
+       if (msg->len > 1)
+               ctrl |= I2C_NOSTOP | I2C_EXTEND;
+
+       cx_write(bus->reg_addr, addr);
+       cx_write(bus->reg_wdata, wdata);
+       cx_write(bus->reg_ctrl, ctrl);
+
+       retval = i2c_wait_done(i2c_adap);
+       if (retval < 0)
+               goto err;
+       if (retval == 0)
+               goto eio;
+       if (i2c_debug) {
+               printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]);
+               if (!(ctrl & I2C_NOSTOP))
+                       printk(" >\n");
+       }
+
+       for (cnt = 1; cnt < msg->len; cnt++ ) {
+               /* following bytes */
+               wdata = msg->buf[cnt];
+               ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
+
+               if (cnt < msg->len-1 || !last)
+                       ctrl |= I2C_NOSTOP | I2C_EXTEND;
+
+               cx_write(bus->reg_addr, addr);
+               cx_write(bus->reg_wdata, wdata);
+               cx_write(bus->reg_ctrl, ctrl);
+
+               retval = i2c_wait_done(i2c_adap);
+               if (retval < 0)
+                       goto err;
+               if (retval == 0)
+                       goto eio;
+               if (i2c_debug) {
+                       printk(" %02x", msg->buf[cnt]);
+                       if (!(ctrl & I2C_NOSTOP))
+                               printk(" >\n");
+               }
+       }
+       return msg->len;
+
+ eio:
+       retval = -EIO;
+ err:
+       printk(" ERR: %d\n", retval);
+       return retval;
+}
+
+static int i2c_readbytes(struct i2c_adapter *i2c_adap,
+                        const struct i2c_msg *msg, int last)
+{
+       struct cx23885_i2c *bus = i2c_adap->algo_data;
+       struct cx23885_dev *dev = bus->dev;
+       u32 ctrl, cnt;
+       int retval;
+
+       dprintk(1, "%s()\n", __FUNCTION__);
+
+       /* Deal with i2c probe functions with zero payload */
+       if (msg->len == 0) {
+               cx_write(bus->reg_addr, msg->addr << 25);
+               cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1);
+               if (!i2c_wait_done(i2c_adap))
+                       return -EIO;
+               if (!i2c_slave_did_ack(i2c_adap))
+                       return -EIO;
+
+
+               dprintk(1, "%s() returns 0\n", __FUNCTION__);
+               return 0;
+       }
+
+       for(cnt = 0; cnt < msg->len; cnt++) {
+
+               ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
+
+               if (cnt < msg->len-1 || !last)
+                       ctrl |= I2C_NOSTOP | I2C_EXTEND;
+
+               cx_write(bus->reg_addr, msg->addr << 25);
+               cx_write(bus->reg_ctrl, ctrl);
+
+               retval = i2c_wait_done(i2c_adap);
+               if (retval < 0)
+                       goto err;
+               if (retval == 0)
+                       goto eio;
+               msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
+               if (i2c_debug) {
+                       if (!(ctrl & I2C_NOSTOP))
+                               printk(" <R %02x", (msg->addr << 1) +1);
+                       printk(" =%02x", msg->buf[cnt]);
+                       if (!(ctrl & I2C_NOSTOP))
+                               printk(" >\n");
+               }
+       }
+       return msg->len;
+
+ eio:
+       retval = -EIO;
+ err:
+       printk(" ERR: %d\n", retval);
+       return retval;
+}
+
+static int i2c_xfer(struct i2c_adapter *i2c_adap,
+                   struct i2c_msg *msgs, int num)
+{
+       struct cx23885_i2c *bus = i2c_adap->algo_data;
+       struct cx23885_dev *dev = bus->dev;
+       int i, retval = 0;
+
+       dprintk(1, "%s(num = %d)\n", __FUNCTION__, num);
+
+       for (i = 0 ; i < num; i++) {
+               dprintk(1, "%s(num = %d) addr = 0x%02x  len = 0x%x\n",
+                       __FUNCTION__, num, msgs[i].addr, msgs[i].len);
+               if (msgs[i].flags & I2C_M_RD) {
+                       /* read */
+                       retval = i2c_readbytes(i2c_adap, &msgs[i], i+1 == num);
+                       if (retval < 0)
+                               goto err;
+               } else {
+                       /* write */
+                       retval = i2c_sendbytes(i2c_adap, &msgs[i], i+1 == num);
+                       if (retval < 0)
+                               goto err;
+               }
+       }
+       return num;
+
+ err:
+       return retval;
+}
+
+static int attach_inform(struct i2c_client *client)
+{
+       struct cx23885_dev *dev = i2c_get_adapdata(client->adapter);
+
+       dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
+               client->driver->driver.name, client->addr, client->name);
+
+       if (!client->driver->command)
+               return 0;
+
+       return 0;
+}
+
+static int detach_inform(struct i2c_client *client)
+{
+       struct cx23885_dev *dev = i2c_get_adapdata(client->adapter);
+
+       dprintk(1, "i2c detach [client=%s]\n", client->name);
+
+       return 0;
+}
+
+void cx23885_call_i2c_clients(struct cx23885_i2c *bus,
+                             unsigned int cmd, void *arg)
+{
+       if (bus->i2c_rc != 0)
+               return;
+
+       i2c_clients_command(&bus->i2c_adap, cmd, arg);
+}
+
+static int cx23885_algo_control(struct i2c_adapter *adap,
+                               unsigned int cmd, unsigned long arg)
+{
+       return 0;
+}
+
+static u32 cx23885_functionality(struct i2c_adapter *adap)
+{
+       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm cx23885_i2c_algo_template = {
+       .master_xfer    = i2c_xfer,
+       .algo_control   = cx23885_algo_control,
+       .functionality  = cx23885_functionality,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_adapter cx23885_i2c_adap_template = {
+       .name              = "cx23885",
+       .owner             = THIS_MODULE,
+       .id                = I2C_HW_B_CX23885,
+       .algo              = &cx23885_i2c_algo_template,
+       .client_register   = attach_inform,
+       .client_unregister = detach_inform,
+};
+
+static struct i2c_client cx23885_i2c_client_template = {
+       .name   = "cx23885 internal",
+};
+
+static char *i2c_devs[128] = {
+       [ 0x1c >> 1 ] = "lgdt3303",
+       [ 0x86 >> 1 ] = "tda9887",
+       [ 0x32 >> 1 ] = "cx24227",
+       [ 0x88 >> 1 ] = "cx25837",
+       [ 0x84 >> 1 ] = "tda8295",
+       [ 0xa0 >> 1 ] = "eeprom",
+       [ 0xc0 >> 1 ] = "tuner/mt2131/tda8275",
+       [ 0xc2 >> 1 ] = "tuner/mt2131/tda8275",
+};
+
+static void do_i2c_scan(char *name, struct i2c_client *c)
+{
+       unsigned char buf;
+       int i, rc;
+
+       for (i = 0; i < 128; i++) {
+               c->addr = i;
+               rc = i2c_master_recv(c, &buf, 0);
+               if (rc < 0)
+                       continue;
+               printk("%s: i2c scan: found device @ 0x%x  [%s]\n",
+                      name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
+       }
+}
+
+/* init + register i2c algo-bit adapter */
+int cx23885_i2c_register(struct cx23885_i2c *bus)
+{
+       struct cx23885_dev *dev = bus->dev;
+
+       dprintk(1, "%s(bus = %d)\n", __FUNCTION__, bus->nr);
+
+       memcpy(&bus->i2c_adap, &cx23885_i2c_adap_template,
+              sizeof(bus->i2c_adap));
+       memcpy(&bus->i2c_algo, &cx23885_i2c_algo_template,
+              sizeof(bus->i2c_algo));
+       memcpy(&bus->i2c_client, &cx23885_i2c_client_template,
+              sizeof(bus->i2c_client));
+
+       bus->i2c_adap.dev.parent = &dev->pci->dev;
+
+       strlcpy(bus->i2c_adap.name, bus->dev->name,
+               sizeof(bus->i2c_adap.name));
+
+       bus->i2c_algo.data = bus;
+       bus->i2c_adap.algo_data = bus;
+       i2c_add_adapter(&bus->i2c_adap);
+
+       bus->i2c_client.adapter = &bus->i2c_adap;
+
+       if (0 == bus->i2c_rc) {
+               printk("%s: i2c bus %d registered\n", dev->name, bus->nr);
+               if (i2c_scan)
+                       do_i2c_scan(dev->name, &bus->i2c_client);
+       } else
+               printk("%s: i2c bus %d register FAILED\n", dev->name, bus->nr);
+
+       return bus->i2c_rc;
+}
+
+int cx23885_i2c_unregister(struct cx23885_i2c *bus)
+{
+       i2c_del_adapter(&bus->i2c_adap);
+       return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+EXPORT_SYMBOL(cx23885_call_i2c_clients);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
new file mode 100644 (file)
index 0000000..162169f
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ *  Driver for the Conexant CX23885 PCIe bridge
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _CX23885_REG_H_
+#define _CX23885_REG_H_
+
+/*
+Address Map
+0x00000000 -> 0x00009000   TX SRAM  (Fifos)
+0x00010000 -> 0x00013c00   RX SRAM  CMDS + CDT
+
+EACH CMDS struct is 0x80 bytes long
+
+DMAx_PTR1 = 0x03040 address of first cluster
+DMAx_PTR2 = 0x10600 address of the CDT
+DMAx_CNT1 = cluster size in (bytes >> 4) -1
+DMAx_CNT2 = total cdt size for all entries >> 3
+
+Cluster Descriptor entry = 4 DWORDS
+ DWORD 0 -> ptr to cluster
+ DWORD 1 Reserved
+ DWORD 2 Reserved
+ DWORD 3 Reserved
+
+Channel manager Data Structure entry = 20 DWORD
+  0  IntialProgramCounterLow
+  1  IntialProgramCounterHigh
+  2  ClusterDescriptorTableBase
+  3  ClusterDescriptorTableSize
+  4  InstructionQueueBase
+  5  InstructionQueueSize
+...  Reserved
+ 19  Reserved
+*/
+
+/* Risc Instructions */
+#define RISC_CNT_INC            0x00010000
+#define RISC_CNT_RESET          0x00030000
+#define RISC_IRQ1               0x01000000
+#define RISC_IRQ2               0x02000000
+#define RISC_EOL                0x04000000
+#define RISC_SOL                0x08000000
+#define RISC_WRITE              0x10000000
+#define RISC_SKIP               0x20000000
+#define RISC_JUMP               0x70000000
+#define RISC_SYNC               0x80000000
+#define RISC_RESYNC             0x80008000
+#define RISC_READ               0x90000000
+#define RISC_WRITERM            0xB0000000
+#define RISC_WRITECM            0xC0000000
+#define RISC_WRITECR            0xD0000000
+#define RISC_WRITEC             0x50000000
+#define RISC_READC              0xA0000000
+
+
+/* Audio and Video Core */
+#define HOST_REG1              0x00000000
+#define HOST_REG2              0x00000001
+#define HOST_REG3              0x00000002
+
+/* Chip Configuration Registers */
+#define CHIP_CTRL              0x00000100
+#define AFE_CTRL               0x00000104
+#define VID_PLL_INT_POST       0x00000108
+#define VID_PLL_FRAC           0x0000010C
+#define AUX_PLL_INT_POST       0x00000110
+#define AUX_PLL_FRAC           0x00000114
+#define SYS_PLL_INT_POST       0x00000118
+#define SYS_PLL_FRAC           0x0000011C
+#define PIN_CTRL               0x00000120
+#define AUD_IO_CTRL            0x00000124
+#define AUD_LOCK1              0x00000128
+#define AUD_LOCK2              0x0000012C
+#define POWER_CTRL             0x00000130
+#define AFE_DIAG_CTRL1         0x00000134
+#define AFE_DIAG_CTRL3         0x0000013C
+#define PLL_DIAG_CTRL          0x00000140
+#define AFE_CLK_OUT_CTRL       0x00000144
+#define DLL1_DIAG_CTRL         0x0000015C
+
+/* GPIO[23:19] Output Enable */
+#define GPIO2_OUT_EN_REG       0x00000160
+/* GPIO[23:19] Data Registers */
+#define GPIO2                  0x00000164
+
+#define IFADC_CTRL             0x00000180
+
+/* Infrared Remote Registers */
+#define IR_CNTRL_REG   0x00000200
+#define IR_TXCLK_REG   0x00000204
+#define IR_RXCLK_REG   0x00000208
+#define IR_CDUTY_REG   0x0000020C
+#define IR_STAT_REG    0x00000210
+#define IR_IRQEN_REG   0x00000214
+#define IR_FILTR_REG   0x00000218
+#define IR_FIFO_REG    0x0000023C
+
+/* Video Decoder Registers */
+#define MODE_CTRL              0x00000400
+#define OUT_CTRL1              0x00000404
+#define OUT_CTRL2              0x00000408
+#define GEN_STAT               0x0000040C
+#define INT_STAT_MASK          0x00000410
+#define LUMA_CTRL              0x00000414
+#define HSCALE_CTRL            0x00000418
+#define VSCALE_CTRL            0x0000041C
+#define CHROMA_CTRL            0x00000420
+#define VBI_LINE_CTRL1         0x00000424
+#define VBI_LINE_CTRL2         0x00000428
+#define VBI_LINE_CTRL3         0x0000042C
+#define VBI_LINE_CTRL4         0x00000430
+#define VBI_LINE_CTRL5         0x00000434
+#define VBI_FC_CFG             0x00000438
+#define VBI_MISC_CFG1          0x0000043C
+#define VBI_MISC_CFG2          0x00000440
+#define VBI_PAY1               0x00000444
+#define VBI_PAY2               0x00000448
+#define VBI_CUST1_CFG1         0x0000044C
+#define VBI_CUST1_CFG2         0x00000450
+#define VBI_CUST1_CFG3         0x00000454
+#define VBI_CUST2_CFG1         0x00000458
+#define VBI_CUST2_CFG2         0x0000045C
+#define VBI_CUST2_CFG3         0x00000460
+#define VBI_CUST3_CFG1         0x00000464
+#define VBI_CUST3_CFG2         0x00000468
+#define VBI_CUST3_CFG3         0x0000046C
+#define HORIZ_TIM_CTRL         0x00000470
+#define VERT_TIM_CTRL          0x00000474
+#define SRC_COMB_CFG           0x00000478
+#define CHROMA_VBIOFF_CFG      0x0000047C
+#define FIELD_COUNT            0x00000480
+#define MISC_TIM_CTRL          0x00000484
+#define DFE_CTRL1              0x00000488
+#define DFE_CTRL2              0x0000048C
+#define DFE_CTRL3              0x00000490
+#define PLL_CTRL               0x00000494
+#define HTL_CTRL               0x00000498
+#define COMB_CTRL              0x0000049C
+#define CRUSH_CTRL             0x000004A0
+#define SOFT_RST_CTRL          0x000004A4
+#define CX885_VERSION          0x000004B4
+#define VBI_PASS_CTRL          0x000004BC
+
+/* Audio Decoder Registers */
+/* 8051 Configuration */
+#define DL_CTL         0x00000800
+#define STD_DET_STATUS 0x00000804
+#define STD_DET_CTL    0x00000808
+#define DW8051_INT     0x0000080C
+#define GENERAL_CTL    0x00000810
+#define AAGC_CTL       0x00000814
+#define DEMATRIX_CTL   0x000008CC
+#define PATH1_CTL1     0x000008D0
+#define PATH1_VOL_CTL  0x000008D4
+#define PATH1_EQ_CTL   0x000008D8
+#define PATH1_SC_CTL   0x000008DC
+#define PATH2_CTL1     0x000008E0
+#define PATH2_VOL_CTL  0x000008E4
+#define PATH2_EQ_CTL   0x000008E8
+#define PATH2_SC_CTL   0x000008EC
+
+/* Sample Rate Converter */
+#define SRC_CTL                0x000008F0
+#define SRC_LF_COEF    0x000008F4
+#define SRC1_CTL       0x000008F8
+#define SRC2_CTL       0x000008FC
+#define SRC3_CTL       0x00000900
+#define SRC4_CTL       0x00000904
+#define SRC5_CTL       0x00000908
+#define SRC6_CTL       0x0000090C
+#define BAND_OUT_SEL   0x00000910
+#define I2S_N_CTL      0x00000914
+#define I2S_OUT_CTL    0x00000918
+#define AUTOCONFIG_REG 0x000009C4
+
+/* Audio ADC Registers */
+#define DSM_CTRL1      0x00000000
+#define DSM_CTRL2      0x00000001
+#define CHP_EN_CTRL    0x00000002
+#define CHP_CLK_CTRL1  0x00000004
+#define CHP_CLK_CTRL2  0x00000005
+#define BG_REF_CTRL    0x00000006
+#define SD2_SW_CTRL1   0x00000008
+#define SD2_SW_CTRL2   0x00000009
+#define SD2_BIAS_CTRL  0x0000000A
+#define AMP_BIAS_CTRL  0x0000000C
+#define CH_PWR_CTRL1   0x0000000E
+#define CH_PWR_CTRL2   0x0000000F
+#define DSM_STATUS1    0x00000010
+#define DSM_STATUS2    0x00000011
+#define DIG_CTL1       0x00000012
+#define DIG_CTL2       0x00000013
+#define I2S_TX_CFG     0x0000001A
+
+#define DEV_CNTRL2     0x00040000
+
+#define PCI_MSK_APB_DMA   (1 << 12)
+#define PCI_MSK_AL_WR     (1 << 11)
+#define PCI_MSK_AL_RD     (1 << 10)
+#define PCI_MSK_RISC_WR   (1 <<  9)
+#define PCI_MSK_RISC_RD   (1 <<  8)
+#define PCI_MSK_AUD_EXT   (1 <<  4)
+#define PCI_MSK_AUD_INT   (1 <<  3)
+#define PCI_MSK_VID_C     (1 <<  2)
+#define PCI_MSK_VID_B     (1 <<  1)
+#define PCI_MSK_VID_A      1
+#define PCI_INT_MSK    0x00040010
+
+#define PCI_INT_STAT   0x00040014
+#define PCI_INT_MSTAT  0x00040018
+
+#define VID_A_INT_MSK  0x00040020
+#define VID_A_INT_STAT 0x00040024
+#define VID_A_INT_MSTAT        0x00040028
+#define VID_A_INT_SSTAT        0x0004002C
+
+#define VID_B_INT_MSK  0x00040030
+#define VID_B_INT_STAT 0x00040034
+#define VID_B_INT_MSTAT        0x00040038
+#define VID_B_INT_SSTAT        0x0004003C
+
+#define VID_B_MSK_BAD_PKT (1 << 20)
+#define VID_B_MSK_OPC_ERR (1 << 16)
+#define VID_B_MSK_SYNC    (1 << 12)
+#define VID_B_MSK_OF      (1 <<  8)
+#define VID_B_MSK_RISCI2  (1 <<  4)
+#define VID_B_MSK_RISCI1   1
+
+#define VID_C_MSK_BAD_PKT (1 << 20)
+#define VID_C_MSK_OPC_ERR (1 << 16)
+#define VID_C_MSK_SYNC    (1 << 12)
+#define VID_C_MSK_OF      (1 <<  8)
+#define VID_C_MSK_RISCI2  (1 <<  4)
+#define VID_C_MSK_RISCI1   1
+
+/* A superset for testing purposes */
+#define VID_BC_MSK_BAD_PKT (1 << 20)
+#define VID_BC_MSK_OPC_ERR (1 << 16)
+#define VID_BC_MSK_SYNC    (1 << 12)
+#define VID_BC_MSK_OF      (1 <<  8)
+#define VID_BC_MSK_RISCI2  (1 <<  4)
+#define VID_BC_MSK_RISCI1   1
+
+#define VID_C_INT_MSK  0x00040040
+#define VID_C_INT_STAT 0x00040044
+#define VID_C_INT_MSTAT        0x00040048
+#define VID_C_INT_SSTAT        0x0004004C
+
+#define AUDIO_INT_INT_MSK      0x00040050
+#define AUDIO_INT_INT_STAT     0x00040054
+#define AUDIO_INT_INT_MSTAT    0x00040058
+#define AUDIO_INT_INT_SSTAT    0x0004005C
+
+#define AUDIO_EXT_INT_MSK      0x00040060
+#define AUDIO_EXT_INT_STAT     0x00040064
+#define AUDIO_EXT_INT_MSTAT    0x00040068
+#define AUDIO_EXT_INT_SSTAT    0x0004006C
+
+#define RDR_CFG0       0x00050000
+#define RDR_CFG1       0x00050004
+#define RDR_TLCTL0     0x00050318
+
+/* APB DMAC Current Buffer Pointer */
+#define DMA1_PTR1      0x00100000
+#define DMA2_PTR1      0x00100004
+#define DMA3_PTR1      0x00100008
+#define DMA4_PTR1      0x0010000C
+#define DMA5_PTR1      0x00100010
+#define DMA6_PTR1      0x00100014
+#define DMA7_PTR1      0x00100018
+#define DMA8_PTR1      0x0010001C
+
+/* APB DMAC Current Table Pointer */
+#define DMA1_PTR2      0x00100040
+#define DMA2_PTR2      0x00100044
+#define DMA3_PTR2      0x00100048
+#define DMA4_PTR2      0x0010004C
+#define DMA5_PTR2      0x00100050
+#define DMA6_PTR2      0x00100054
+#define DMA7_PTR2      0x00100058
+#define DMA8_PTR2      0x0010005C
+
+/* APB DMAC Buffer Limit */
+#define DMA1_CNT1      0x00100080
+#define DMA2_CNT1      0x00100084
+#define DMA3_CNT1      0x00100088
+#define DMA4_CNT1      0x0010008C
+#define DMA5_CNT1      0x00100090
+#define DMA6_CNT1      0x00100094
+#define DMA7_CNT1      0x00100098
+#define DMA8_CNT1      0x0010009C
+
+/* APB DMAC Table Size */
+#define DMA1_CNT2      0x001000C0
+#define DMA2_CNT2      0x001000C4
+#define DMA3_CNT2      0x001000C8
+#define DMA4_CNT2      0x001000CC
+#define DMA5_CNT2      0x001000D0
+#define DMA6_CNT2      0x001000D4
+#define DMA7_CNT2      0x001000D8
+#define DMA8_CNT2      0x001000DC
+
+/* Timer Counters */
+#define TM_CNT_LDW     0x00110000
+#define TM_CNT_UW      0x00110004
+#define TM_LMT_LDW     0x00110008
+#define TM_LMT_UW      0x0011000C
+
+/* GPIO */
+#define GP0_IO         0x00110010
+#define GPIO_ISM       0x00110014
+#define SOFT_RESET     0x0011001C
+
+/* GPIO (417 Microsoftcontroller) RW Data */
+#define MC417_RWD      0x00110020
+
+/* GPIO (417 Microsoftcontroller) Output Enable, Low Active */
+#define MC417_OEN      0x00110024
+#define MC417_CTL      0x00110028
+#define CLK_DELAY      0x00110048
+#define PAD_CTRL       0x0011004C
+
+/* Video A Interface */
+#define VID_A_GPCNT            0x00130020
+#define VBI_A_GPCNT            0x00130024
+#define VID_A_GPCNT_CTL                0x00130030
+#define VBI_A_GPCNT_CTL                0x00130034
+#define VID_A_DMA_CTL          0x00130040
+#define VID_A_VIP_CTRL         0x00130080
+#define VID_A_PIXEL_FRMT       0x00130084
+#define VID_A_VBI_CTRL         0x00130088
+
+/* Video B Interface */
+#define VID_B_DMA              0x00130100
+#define VBI_B_DMA              0x00130108
+#define VID_B_GPCNT            0x00130120
+#define VBI_B_GPCNT            0x00130124
+#define VID_B_GPCNT_CTL                0x00130134
+#define VBI_B_GPCNT_CTL                0x00130138
+#define VID_B_DMA_CTL          0x00130140
+#define VID_B_SRC_SEL          0x00130144
+#define VID_B_LNGTH            0x00130150
+#define VID_B_HW_SOP_CTL       0x00130154
+#define VID_B_GEN_CTL          0x00130158
+#define VID_B_BD_PKT_STATUS    0x0013015C
+#define VID_B_SOP_STATUS       0x00130160
+#define VID_B_FIFO_OVFL_STAT   0x00130164
+#define VID_B_VLD_MISC         0x00130168
+#define VID_B_TS_CLK_EN                0x0013016C
+#define VID_B_VIP_CTRL         0x00130180
+#define VID_B_PIXEL_FRMT       0x00130184
+
+/* Video C Interface */
+#define VID_C_GPCNT            0x00130220
+#define VID_C_GPCNT_CTL                0x00130230
+#define VBI_C_GPCNT_CTL                0x00130234
+#define VID_C_DMA_CTL          0x00130240
+#define VID_C_LNGTH            0x00130250
+#define VID_C_HW_SOP_CTL       0x00130254
+#define VID_C_GEN_CTL          0x00130258
+#define VID_C_BD_PKT_STATUS    0x0013025C
+#define VID_C_SOP_STATUS       0x00130260
+#define VID_C_FIFO_OVFL_STAT   0x00130264
+#define VID_C_VLD_MISC         0x00130268
+#define VID_C_TS_CLK_EN                0x0013026C
+
+/* Internal Audio Interface */
+#define AUD_INT_A_GPCNT                0x00140020
+#define AUD_INT_B_GPCNT                0x00140024
+#define AUD_INT_A_GPCNT_CTL    0x00140030
+#define AUD_INT_B_GPCNT_CTL    0x00140034
+#define AUD_INT_DMA_CTL                0x00140040
+#define AUD_INT_A_LNGTH                0x00140050
+#define AUD_INT_B_LNGTH                0x00140054
+#define AUD_INT_A_MODE         0x00140058
+#define AUD_INT_B_MODE         0x0014005C
+
+/* External Audio Interface */
+#define AUD_EXT_DMA            0x00140100
+#define AUD_EXT_GPCNT          0x00140120
+#define AUD_EXT_GPCNT_CTL      0x00140130
+#define AUD_EXT_DMA_CTL                0x00140140
+#define AUD_EXT_LNGTH          0x00140150
+#define AUD_EXT_A_MODE         0x00140158
+
+/* I2C Bus 1 */
+#define I2C1_ADDR      0x00180000
+#define I2C1_WDATA     0x00180004
+#define I2C1_CTRL      0x00180008
+#define I2C1_RDATA     0x0018000C
+#define I2C1_STAT      0x00180010
+
+/* I2C Bus 2 */
+#define I2C2_ADDR      0x00190000
+#define I2C2_WDATA     0x00190004
+#define I2C2_CTRL      0x00190008
+#define I2C2_RDATA     0x0019000C
+#define I2C2_STAT      0x00190010
+
+/* I2C Bus 3 */
+#define I2C3_ADDR      0x001A0000
+#define I2C3_WDATA     0x001A0004
+#define I2C3_CTRL      0x001A0008
+#define I2C3_RDATA     0x001A000C
+#define I2C3_STAT      0x001A0010
+
+/* UART */
+#define UART_CTL       0x001B0000
+#define UART_BRD       0x001B0004
+#define UART_ISR       0x001B000C
+#define UART_CNT       0x001B0010
+
+#endif /* _CX23885_REG_H_ */
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
new file mode 100644 (file)
index 0000000..dec4dc2
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ *  Driver for the Conexant CX23885 PCIe bridge
+ *
+ *  Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/pci.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/kdev_t.h>
+
+#include <media/v4l2-common.h>
+#include <media/tuner.h>
+#include <media/tveeprom.h>
+#include <media/videobuf-dma-sg.h>
+#include <media/videobuf-dvb.h>
+
+#include "btcx-risc.h"
+#include "cx23885-reg.h"
+
+#include <linux/version.h>
+#include <linux/mutex.h>
+
+#define CX23885_VERSION_CODE KERNEL_VERSION(0,0,1)
+
+#define UNSET (-1U)
+
+#define CX23885_MAXBOARDS 8
+
+/* Max number of inputs by card */
+#define MAX_CX23885_INPUT 8
+
+#define BUFFER_TIMEOUT     (HZ)  /* 0.5 seconds */
+
+#define CX23885_BOARD_NOAUTO               UNSET
+#define CX23885_BOARD_UNKNOWN                  0
+#define CX23885_BOARD_HAUPPAUGE_HVR1800lp      1
+#define CX23885_BOARD_HAUPPAUGE_HVR1800        2
+#define CX23885_BOARD_HAUPPAUGE_HVR1250        3
+#define CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP   4
+
+enum cx23885_itype {
+       CX23885_VMUX_COMPOSITE1 = 1,
+       CX23885_VMUX_COMPOSITE2,
+       CX23885_VMUX_COMPOSITE3,
+       CX23885_VMUX_COMPOSITE4,
+       CX23885_VMUX_SVIDEO,
+       CX23885_VMUX_TELEVISION,
+       CX23885_VMUX_CABLE,
+       CX23885_VMUX_DVB,
+       CX23885_VMUX_DEBUG,
+       CX23885_RADIO,
+};
+
+enum cx23885_src_sel_type {
+       CX23885_SRC_SEL_EXT_656_VIDEO = 0,
+       CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO
+};
+
+/* buffer for one video frame */
+struct cx23885_buffer {
+       /* common v4l buffer stuff -- must be first */
+       struct videobuf_buffer vb;
+
+       /* cx23885 specific */
+       unsigned int           bpl;
+       struct btcx_riscmem    risc;
+       struct cx23885_fmt     *fmt;
+       u32                    count;
+};
+
+struct cx23885_input {
+       enum cx23885_itype type;
+       unsigned int    vmux;
+       u32             gpio0, gpio1, gpio2, gpio3;
+};
+
+typedef enum {
+       CX23885_MPEG_UNDEFINED = 0,
+       CX23885_MPEG_DVB
+} port_t;
+
+struct cx23885_board {
+       char                    *name;
+       port_t                  portb, portc;
+       struct cx23885_input    input[MAX_CX23885_INPUT];
+};
+
+struct cx23885_subid {
+       u16     subvendor;
+       u16     subdevice;
+       u32     card;
+};
+
+struct cx23885_i2c {
+       struct cx23885_dev *dev;
+
+       int                        nr;
+
+       /* i2c i/o */
+       struct i2c_adapter         i2c_adap;
+       struct i2c_algo_bit_data   i2c_algo;
+       struct i2c_client          i2c_client;
+       u32                        i2c_rc;
+
+       /* 885 registers used for raw addess */
+       u32                        i2c_period;
+       u32                        reg_ctrl;
+       u32                        reg_stat;
+       u32                        reg_addr;
+       u32                        reg_rdata;
+       u32                        reg_wdata;
+};
+
+struct cx23885_dmaqueue {
+       struct list_head       active;
+       struct list_head       queued;
+       struct timer_list      timeout;
+       struct btcx_riscmem    stopper;
+       u32                    count;
+};
+
+struct cx23885_tsport {
+       struct cx23885_dev *dev;
+
+       int                        nr;
+       int                        sram_chno;
+
+       struct videobuf_dvb        dvb;
+
+       /* dma queues */
+       struct cx23885_dmaqueue    mpegq;
+       u32                        ts_packet_size;
+       u32                        ts_packet_count;
+
+       int                        width;
+       int                        height;
+
+       spinlock_t                 slock;
+
+       /* registers */
+       u32                        reg_gpcnt;
+       u32                        reg_gpcnt_ctl;
+       u32                        reg_dma_ctl;
+       u32                        reg_lngth;
+       u32                        reg_hw_sop_ctrl;
+       u32                        reg_gen_ctrl;
+       u32                        reg_bd_pkt_status;
+       u32                        reg_sop_status;
+       u32                        reg_fifo_ovfl_stat;
+       u32                        reg_vld_misc;
+       u32                        reg_ts_clk_en;
+       u32                        reg_ts_int_msk;
+       u32                        reg_ts_int_stat;
+       u32                        reg_src_sel;
+
+       /* Default register vals */
+       int                        pci_irqmask;
+       u32                        dma_ctl_val;
+       u32                        ts_int_msk_val;
+       u32                        gen_ctrl_val;
+       u32                        ts_clk_en_val;
+       u32                        src_sel_val;
+};
+
+struct cx23885_dev {
+       struct list_head           devlist;
+       atomic_t                   refcount;
+
+       /* pci stuff */
+       struct pci_dev             *pci;
+       unsigned char              pci_rev, pci_lat;
+       int                        pci_bus, pci_slot;
+       u32                        __iomem *lmmio;
+       u8                         __iomem *bmmio;
+       int                        pci_irqmask;
+
+       /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
+       struct cx23885_i2c         i2c_bus[3];
+
+       int                        nr;
+       struct mutex               lock;
+
+       /* board details */
+       unsigned int               board;
+       char                       name[32];
+
+       struct cx23885_tsport      ts1, ts2;
+
+       /* sram configuration */
+       struct sram_channel        *sram_channels;
+
+       enum {
+               CX23885_BRIDGE_UNDEFINED = 0,
+               CX23885_BRIDGE_885 = 885,
+               CX23885_BRIDGE_887 = 887,
+       } bridge;
+};
+
+#define SRAM_CH01  0 /* Video A */
+#define SRAM_CH02  1 /* VBI A */
+#define SRAM_CH03  2 /* Video B */
+#define SRAM_CH04  3 /* Transport via B */
+#define SRAM_CH05  4 /* VBI B */
+#define SRAM_CH06  5 /* Video C */
+#define SRAM_CH07  6 /* Transport via C */
+#define SRAM_CH08  7 /* Audio Internal A */
+#define SRAM_CH09  8 /* Audio Internal B */
+#define SRAM_CH10  9 /* Audio External */
+#define SRAM_CH11 10 /* COMB_3D_N */
+#define SRAM_CH12 11 /* Comb 3D N1 */
+#define SRAM_CH13 12 /* Comb 3D N2 */
+#define SRAM_CH14 13 /* MOE Vid */
+#define SRAM_CH15 14 /* MOE RSLT */
+
+struct sram_channel {
+       char *name;
+       u32  cmds_start;
+       u32  ctrl_start;
+       u32  cdt;
+       u32  fifo_start;;
+       u32  fifo_size;
+       u32  ptr1_reg;
+       u32  ptr2_reg;
+       u32  cnt1_reg;
+       u32  cnt2_reg;
+       u32  jumponly;
+};
+
+/* ----------------------------------------------------------- */
+
+#define cx_read(reg)             readl(dev->lmmio + ((reg)>>2))
+#define cx_write(reg,value)      writel((value), dev->lmmio + ((reg)>>2))
+
+#define cx_andor(reg,mask,value) \
+  writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
+  ((value) & (mask)), dev->lmmio+((reg)>>2))
+
+#define cx_set(reg,bit)          cx_andor((reg),(bit),(bit))
+#define cx_clear(reg,bit)        cx_andor((reg),(bit),0)
+
+extern int cx23885_sram_channel_setup(struct cx23885_dev *dev,
+       struct sram_channel *ch,
+       unsigned int bpl, u32 risc);
+
+/* ----------------------------------------------------------- */
+/* cx23885-cards.c                                                */
+
+extern struct cx23885_board cx23885_boards[];
+extern const unsigned int cx23885_bcount;
+
+extern struct cx23885_subid cx23885_subids[];
+extern const unsigned int cx23885_idcount;
+
+extern void cx23885_card_list(struct cx23885_dev *dev);
+extern int  cx23885_ir_init(struct cx23885_dev *dev);
+extern void cx23885_gpio_setup(struct cx23885_dev *dev);
+extern void cx23885_card_setup(struct cx23885_dev *dev);
+extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev);
+
+extern int cx23885_dvb_register(struct cx23885_tsport *port);
+extern int cx23885_dvb_unregister(struct cx23885_tsport *port);
+
+extern int cx23885_buf_prepare(struct videobuf_queue *q,
+                              struct cx23885_tsport *port,
+                              struct cx23885_buffer *buf,
+                              enum v4l2_field field);
+
+extern void cx23885_buf_queue(struct cx23885_tsport *port,
+                             struct cx23885_buffer *buf);
+extern void cx23885_free_buffer(struct videobuf_queue *q,
+                               struct cx23885_buffer *buf);
+
+/* ----------------------------------------------------------- */
+/* cx23885-i2c.c                                                */
+extern int cx23885_i2c_register(struct cx23885_i2c *bus);
+extern int cx23885_i2c_unregister(struct cx23885_i2c *bus);
+extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd,
+                                    void *arg);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
+ */
index f897c1ebd5f3d809f4bf6bf6f111b2754395a4bc..3d46a776df36a44e1b92c668d6f89e567503b33b 100644 (file)
@@ -157,13 +157,12 @@ void cx25840_audio_set_path(struct i2c_client *client)
 {
        struct cx25840_state *state = i2c_get_clientdata(client);
 
+       /* assert soft reset */
+       cx25840_and_or(client, 0x810, ~0x1, 0x01);
+
        /* stop microcontroller */
        cx25840_and_or(client, 0x803, ~0x10, 0);
 
-       /* assert soft reset */
-       if (!state->is_cx25836)
-               cx25840_and_or(client, 0x810, ~0x1, 0x01);
-
        /* Mute everything to prevent the PFFT! */
        cx25840_write(client, 0x8d3, 0x1f);
 
@@ -181,32 +180,46 @@ void cx25840_audio_set_path(struct i2c_client *client)
 
        set_audclk_freq(client, state->audclk_freq);
 
-       /* deassert soft reset */
-       if (!state->is_cx25836)
-               cx25840_and_or(client, 0x810, ~0x1, 0x00);
-
        if (state->aud_input != CX25840_AUDIO_SERIAL) {
                /* When the microcontroller detects the
                 * audio format, it will unmute the lines */
                cx25840_and_or(client, 0x803, ~0x10, 0x10);
        }
+
+       /* deassert soft reset */
+       cx25840_and_or(client, 0x810, ~0x1, 0x00);
 }
 
 static int get_volume(struct i2c_client *client)
 {
+       struct cx25840_state *state = i2c_get_clientdata(client);
+       int vol;
+
+       if (state->unmute_volume >= 0)
+               return state->unmute_volume;
+
        /* Volume runs +18dB to -96dB in 1/2dB steps
         * change to fit the msp3400 -114dB to +12dB range */
 
        /* check PATH1_VOLUME */
-       int vol = 228 - cx25840_read(client, 0x8d4);
+       vol = 228 - cx25840_read(client, 0x8d4);
        vol = (vol / 2) + 23;
        return vol << 9;
 }
 
 static void set_volume(struct i2c_client *client, int volume)
 {
-       /* First convert the volume to msp3400 values (0-127) */
-       int vol = volume >> 9;
+       struct cx25840_state *state = i2c_get_clientdata(client);
+       int vol;
+
+       if (state->unmute_volume >= 0) {
+               state->unmute_volume = volume;
+               return;
+       }
+
+       /* Convert the volume to msp3400 values (0-127) */
+       vol = volume >> 9;
+
        /* now scale it up to cx25840 values
         * -114dB to -96dB maps to 0
         * this should be 19, but in my testing that was 4dB too loud */
@@ -284,30 +297,26 @@ static void set_balance(struct i2c_client *client, int balance)
 
 static int get_mute(struct i2c_client *client)
 {
-       /* check SRC1_MUTE_EN */
-       return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0;
+       struct cx25840_state *state = i2c_get_clientdata(client);
+
+       return state->unmute_volume >= 0;
 }
 
 static void set_mute(struct i2c_client *client, int mute)
 {
        struct cx25840_state *state = i2c_get_clientdata(client);
 
-       if (state->aud_input != CX25840_AUDIO_SERIAL) {
-               /* Must turn off microcontroller in order to mute sound.
-                * Not sure if this is the best method, but it does work.
-                * If the microcontroller is running, then it will undo any
-                * changes to the mute register. */
-               if (mute) {
-                       /* disable microcontroller */
-                       cx25840_and_or(client, 0x803, ~0x10, 0x00);
-                       cx25840_write(client, 0x8d3, 0x1f);
-               } else {
-                       /* enable microcontroller */
-                       cx25840_and_or(client, 0x803, ~0x10, 0x10);
-               }
-       } else {
-               /* SRC1_MUTE_EN */
-               cx25840_and_or(client, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
+       if (mute && state->unmute_volume == -1) {
+               int vol = get_volume(client);
+
+               set_volume(client, 0);
+               state->unmute_volume = vol;
+       }
+       else if (!mute && state->unmute_volume != -1) {
+               int vol = state->unmute_volume;
+
+               state->unmute_volume = -1;
+               set_volume(client, vol);
        }
 }
 
@@ -319,18 +328,18 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
 
        switch (cmd) {
        case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+               if (!state->is_cx25836)
+                       cx25840_and_or(client, 0x810, ~0x1, 1);
                if (state->aud_input != CX25840_AUDIO_SERIAL) {
                        cx25840_and_or(client, 0x803, ~0x10, 0);
                        cx25840_write(client, 0x8d3, 0x1f);
                }
-               if (!state->is_cx25836)
-                       cx25840_and_or(client, 0x810, ~0x1, 1);
                retval = set_audclk_freq(client, *(u32 *)arg);
-               if (!state->is_cx25836)
-                       cx25840_and_or(client, 0x810, ~0x1, 0);
                if (state->aud_input != CX25840_AUDIO_SERIAL) {
                        cx25840_and_or(client, 0x803, ~0x10, 0x10);
                }
+               if (!state->is_cx25836)
+                       cx25840_and_or(client, 0x810, ~0x1, 0);
                return retval;
 
        case VIDIOC_G_CTRL:
index 67bda9f9a44bfa48998de9f3566ef57da7222ded..15f191e170d28318370f2f4c03656a6d8c59ec36 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
+#include <linux/delay.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/cx25840.h>
@@ -133,7 +134,9 @@ static void init_dll1(struct i2c_client *client)
        cx25840_write(client, 0x159, 0x23);
        cx25840_write(client, 0x15a, 0x87);
        cx25840_write(client, 0x15b, 0x06);
+       udelay(10);
        cx25840_write(client, 0x159, 0xe1);
+       udelay(10);
        cx25840_write(client, 0x15a, 0x86);
        cx25840_write(client, 0x159, 0xe0);
        cx25840_write(client, 0x159, 0xe1);
@@ -147,6 +150,7 @@ static void init_dll2(struct i2c_client *client)
        cx25840_write(client, 0x15d, 0xe3);
        cx25840_write(client, 0x15e, 0x86);
        cx25840_write(client, 0x15f, 0x06);
+       udelay(10);
        cx25840_write(client, 0x15d, 0xe1);
        cx25840_write(client, 0x15d, 0xe0);
        cx25840_write(client, 0x15d, 0xe1);
@@ -165,9 +169,7 @@ static void cx25836_initialize(struct i2c_client *client)
        /* 3c. */
        cx25840_and_or(client, 0x159, ~0x02, 0x02);
        /* 3d. */
-       /* There should be a 10-us delay here, but since the
-          i2c bus already has a 10-us delay we don't need to do
-          anything */
+       udelay(10);
        /* 3e. */
        cx25840_and_or(client, 0x159, ~0x02, 0x00);
        /* 3f. */
@@ -179,9 +181,18 @@ static void cx25836_initialize(struct i2c_client *client)
        cx25840_and_or(client, 0x15b, ~0x1e, 0x10);
 }
 
-static void cx25840_initialize(struct i2c_client *client, int loadfw)
+static void cx25840_work_handler(struct work_struct *work)
 {
+       struct cx25840_state *state = container_of(work, struct cx25840_state, fw_work);
+       cx25840_loadfw(state->c);
+       wake_up(&state->fw_wait);
+}
+
+static void cx25840_initialize(struct i2c_client *client)
+{
+       DEFINE_WAIT(wait);
        struct cx25840_state *state = i2c_get_clientdata(client);
+       struct workqueue_struct *q;
 
        /* datasheet startup in numbered steps, refer to page 3-77 */
        /* 2. */
@@ -197,8 +208,19 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw)
        cx25840_write(client, 0x13c, 0x01);
        cx25840_write(client, 0x13c, 0x00);
        /* 5. */
-       if (loadfw)
-               cx25840_loadfw(client);
+       /* Do the firmware load in a work handler to prevent.
+          Otherwise the kernel is blocked waiting for the
+          bit-banging i2c interface to finish uploading the
+          firmware. */
+       INIT_WORK(&state->fw_work, cx25840_work_handler);
+       init_waitqueue_head(&state->fw_wait);
+       q = create_singlethread_workqueue("cx25840_fw");
+       prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);
+       queue_work(q, &state->fw_work);
+       schedule();
+       finish_wait(&state->fw_wait, &wait);
+       destroy_workqueue(q);
+
        /* 6. */
        cx25840_write(client, 0x115, 0x8c);
        cx25840_write(client, 0x116, 0x07);
@@ -251,8 +273,13 @@ static void input_change(struct i2c_client *client)
        }
        cx25840_and_or(client, 0x401, ~0x60, 0);
        cx25840_and_or(client, 0x401, ~0x60, 0x60);
+       cx25840_and_or(client, 0x810, ~0x01, 1);
 
-       if (std & V4L2_STD_525_60) {
+       if (state->radio) {
+               cx25840_write(client, 0x808, 0xf9);
+               cx25840_write(client, 0x80b, 0x00);
+       }
+       else if (std & V4L2_STD_525_60) {
                /* Certain Hauppauge PVR150 models have a hardware bug
                   that causes audio to drop out. For these models the
                   audio standard must be set explicitly.
@@ -281,11 +308,7 @@ static void input_change(struct i2c_client *client)
                cx25840_write(client, 0x80b, 0x10);
        }
 
-       if (cx25840_read(client, 0x803) & 0x10) {
-               /* restart audio decoder microcontroller */
-               cx25840_and_or(client, 0x803, ~0x10, 0x00);
-               cx25840_and_or(client, 0x803, ~0x10, 0x10);
-       }
+       cx25840_and_or(client, 0x810, ~0x01, 0);
 }
 
 static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
@@ -625,6 +648,22 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
        struct v4l2_tuner *vt = arg;
        struct v4l2_routing *route = arg;
 
+       /* ignore these commands */
+       switch (cmd) {
+               case TUNER_SET_TYPE_ADDR:
+                       return 0;
+       }
+
+       if (!state->is_initialized) {
+               v4l_dbg(1, cx25840_debug, client, "cmd %08x triggered fw load\n", cmd);
+               /* initialize on first use */
+               state->is_initialized = 1;
+               if (state->is_cx25836)
+                       cx25836_initialize(client);
+               else
+                       cx25840_initialize(client);
+       }
+
        switch (cmd) {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        /* ioctls to allow direct access to the
@@ -825,7 +864,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
                if (state->is_cx25836)
                        cx25836_initialize(client);
                else
-                       cx25840_initialize(client, 0);
+                       cx25840_initialize(client);
                break;
 
        case VIDIOC_G_CHIP_IDENT:
@@ -856,17 +895,16 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
        if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
                return 0;
 
-       state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
-       if (state == 0)
+       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+       if (client == 0)
                return -ENOMEM;
 
-       client = &state->c;
        client->addr = address;
        client->adapter = adapter;
        client->driver = &i2c_driver_cx25840;
        snprintf(client->name, sizeof(client->name) - 1, "cx25840");
 
-       v4l_dbg(1, cx25840_debug, client, "detecting cx25840 client on address 0x%x\n", address << 1);
+       v4l_dbg(1, cx25840_debug, client, "detecting cx25840 client on address 0x%x\n", client->addr << 1);
 
        device_id = cx25840_read(client, 0x101) << 8;
        device_id |= cx25840_read(client, 0x100);
@@ -875,42 +913,44 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
         * 0x83 for the cx2583x and 0x84 for the cx2584x */
        if ((device_id & 0xff00) == 0x8300) {
                id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6;
-               state->is_cx25836 = 1;
        }
        else if ((device_id & 0xff00) == 0x8400) {
                id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf);
-               state->is_cx25836 = 0;
        }
        else {
                v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");
-               kfree(state);
+               kfree(client);
                return 0;
        }
 
+       state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL);
+       if (state == NULL) {
+               kfree(client);
+               return -ENOMEM;
+       }
+
        /* Note: revision '(device_id & 0x0f) == 2' was never built. The
           marking skips from 0x1 == 22 to 0x3 == 23. */
        v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",
                    (device_id & 0xfff0) >> 4,
                    (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : (device_id & 0x0f),
-                   address << 1, adapter->name);
+                   client->addr << 1, client->adapter->name);
 
        i2c_set_clientdata(client, state);
+       state->c = client;
+       state->is_cx25836 = ((device_id & 0xff00) == 0x8300);
        state->vid_input = CX25840_COMPOSITE7;
        state->aud_input = CX25840_AUDIO8;
        state->audclk_freq = 48000;
        state->pvr150_workaround = 0;
        state->audmode = V4L2_TUNER_MODE_LANG1;
+       state->unmute_volume = -1;
        state->vbi_line_offset = 8;
        state->id = id;
        state->rev = device_id;
 
        i2c_attach_client(client);
 
-       if (state->is_cx25836)
-               cx25836_initialize(client);
-       else
-               cx25840_initialize(client, 1);
-
        return 0;
 }
 
@@ -932,6 +972,7 @@ static int cx25840_detach_client(struct i2c_client *client)
        }
 
        kfree(state);
+       kfree(client);
 
        return 0;
 }
@@ -1056,9 +1097,10 @@ static void log_audio_status(struct i2c_client *client)
        }
        v4l_info(client, "Detected audio standard:   %s\n", p);
        v4l_info(client, "Audio muted:               %s\n",
-                   (mute_ctl & 0x2) ? "yes" : "no");
+                   (state->unmute_volume >= 0) ? "yes" : "no");
        v4l_info(client, "Audio microcontroller:     %s\n",
-                   (download_ctl & 0x10) ? "running" : "stopped");
+                   (download_ctl & 0x10) ?
+                               ((mute_ctl & 0x2) ? "detecting" : "running") : "stopped");
 
        switch (audio_config >> 4) {
        case 0x00: p = "undefined"; break;
index f4b56d2fd6b6cee76c936c1ed645f9e1c628d8da..ea669b1f084d46462f06bbd2b2b78b2bc80877fc 100644 (file)
@@ -35,17 +35,21 @@ extern int cx25840_debug;
 #define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0)
 
 struct cx25840_state {
-       struct i2c_client c;
+       struct i2c_client *c;
        int pvr150_workaround;
        int radio;
        enum cx25840_video_input vid_input;
        enum cx25840_audio_input aud_input;
        u32 audclk_freq;
        int audmode;
+       int unmute_volume; /* -1 if not muted */
        int vbi_line_offset;
        u32 id;
        u32 rev;
        int is_cx25836;
+       int is_initialized;
+       wait_queue_head_t fw_wait;    /* wake up when the fw load is finished */
+       struct work_struct fw_work;   /* work entry for fw load */
 };
 
 /* ----------------------------------------------------------------------- */
index f750a543c96145c30fba197ccbc4b130dc93d0ea..eeb5224ca1018fda4708c8e4fbf29ecb552b46c1 100644 (file)
@@ -4,7 +4,7 @@ config VIDEO_CX88
        select I2C_ALGOBIT
        select FW_LOADER
        select VIDEO_BTCX
-       select VIDEO_BUF
+       select VIDEOBUF_DMA_SG
        select VIDEO_TUNER
        select VIDEO_TVEEPROM
        select VIDEO_IR
@@ -46,7 +46,7 @@ config VIDEO_CX88_BLACKBIRD
 config VIDEO_CX88_DVB
        tristate "DVB/ATSC Support for cx2388x based TV cards"
        depends on VIDEO_CX88 && DVB_CORE
-       select VIDEO_BUF_DVB
+       select VIDEOBUF_DVB
        select DVB_PLL if !DVB_FE_CUSTOMISE
        select DVB_MT352 if !DVB_FE_CUSTOMISE
        select DVB_ZL10353 if !DVB_FE_CUSTOMISE
index 2d666b56020c2a5032747177cda51ab3379076c7..90c36c5705c368bfdb98525af9faf3c7e62d15f9 100644 (file)
@@ -3,6 +3,7 @@
  *  Support for audio capture
  *  PCI function #1 of the cx2388x.
  *
+ *    (c) 2007 Trent Piepho <xyzzy@speakeasy.org>
  *    (c) 2005,2006 Ricardo Cerqueira <v4l@cerqueira.org>
  *    (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
  *    Based on a dummy cx88 module by Gerd Knorr <kraxel@bytesex.org>
@@ -27,7 +28,9 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
+#include <linux/vmalloc.h>
 #include <linux/dma-mapping.h>
+#include <linux/pci.h>
 
 #include <asm/delay.h>
 #include <sound/driver.h>
 #define dprintk_core(level,fmt, arg...)        if (debug >= level) \
        printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg)
 
-
 /****************************************************************************
        Data type declarations - Can be moded to a header file later
  ****************************************************************************/
 
-/* These can be replaced after done */
-#define MIXER_ADDR_LAST MAX_CX88_INPUT
-
 struct cx88_audio_dev {
        struct cx88_core           *core;
        struct cx88_dmaqueue       q;
 
        /* pci i/o */
        struct pci_dev             *pci;
-       unsigned char              pci_rev,pci_lat;
 
        /* audio controls */
        int                        irq;
@@ -68,24 +66,17 @@ struct cx88_audio_dev {
        struct snd_card            *card;
 
        spinlock_t                 reg_lock;
+       atomic_t                   count;
 
        unsigned int               dma_size;
        unsigned int               period_size;
        unsigned int               num_periods;
 
-       struct videobuf_dmabuf dma_risc;
-
-       int                        mixer_volume[MIXER_ADDR_LAST+1][2];
-       int                        capture_source[MIXER_ADDR_LAST+1][2];
-
-       long int read_count;
-       long int read_offset;
-
-       struct cx88_buffer   *buf;
+       struct videobuf_dmabuf     *dma_risc;
 
-       long opened;
-       struct snd_pcm_substream *substream;
+       struct cx88_buffer         *buf;
 
+       struct snd_pcm_substream   *substream;
 };
 typedef struct cx88_audio_dev snd_cx88_card_t;
 
@@ -98,7 +89,6 @@ typedef struct cx88_audio_dev snd_cx88_card_t;
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;     /* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
 static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
-static struct snd_card *snd_cx88_cards[SNDRV_CARDS];
 
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
@@ -136,38 +126,39 @@ static int _cx88_start_audio_dma(snd_cx88_card_t *chip)
        struct cx88_core *core=chip->core;
        struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
 
-
-       dprintk(1, "Starting audio DMA for %i bytes/line and %i (%i) lines at address %08x\n",buf->bpl, chip->num_periods, audio_ch->fifo_size / buf->bpl, audio_ch->fifo_start);
+       /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
+       cx_clear(MO_AUD_DMACNTRL, 0x11);
 
        /* setup fifo + format - out channel */
-       cx88_sram_channel_setup(chip->core, &cx88_sram_channels[SRAM_CH25],
-                               buf->bpl, buf->risc.dma);
+       cx88_sram_channel_setup(chip->core, audio_ch, buf->bpl, buf->risc.dma);
 
        /* sets bpl size */
        cx_write(MO_AUDD_LNGTH, buf->bpl);
 
        /* reset counter */
-       cx_write(MO_AUDD_GPCNTRL,GP_COUNT_CONTROL_RESET);
-
-       dprintk(1,"Enabling IRQ, setting mask from 0x%x to 0x%x\n",chip->core->pci_irqmask,(chip->core->pci_irqmask | 0x02));
-       /* enable irqs */
-       cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | 0x02);
+       cx_write(MO_AUDD_GPCNTRL, GP_COUNT_CONTROL_RESET);
+       atomic_set(&chip->count, 0);
 
+       dprintk(1, "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d "
+               "byte buffer\n", buf->bpl, cx_read(audio_ch->cmds_start + 8)>>1,
+               chip->num_periods, buf->bpl * chip->num_periods);
 
        /* Enables corresponding bits at AUD_INT_STAT */
-       cx_write(MO_AUD_INTMSK,
-                       (1<<16)|
-                       (1<<12)|
-                       (1<<4)|
-                       (1<<0)
-                       );
+       cx_write(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
+                               AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
+
+       /* Clean any pending interrupt bits already set */
+       cx_write(MO_AUD_INTSTAT, ~0);
+
+       /* enable audio irqs */
+       cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | PCI_INT_AUDINT);
 
        /* start dma */
        cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */
        cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable */
 
        if (debug)
-               cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]);
+               cx88_sram_channel_dump(chip->core, audio_ch);
 
        return 0;
 }
@@ -184,13 +175,9 @@ static int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
        cx_clear(MO_AUD_DMACNTRL, 0x11);
 
        /* disable irqs */
-       cx_clear(MO_PCI_INTMSK, 0x02);
-       cx_clear(MO_AUD_INTMSK,
-                       (1<<16)|
-                       (1<<12)|
-                       (1<<4)|
-                       (1<<0)
-                       );
+       cx_clear(MO_PCI_INTMSK, PCI_INT_AUDINT);
+       cx_clear(MO_AUD_INTMSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC |
+                               AUD_INT_DN_RISCI2 | AUD_INT_DN_RISCI1);
 
        if (debug)
                cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]);
@@ -198,7 +185,7 @@ static int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
        return 0;
 }
 
-#define MAX_IRQ_LOOP 10
+#define MAX_IRQ_LOOP 50
 
 /*
  * BOARD Specific: IRQ dma bits
@@ -223,42 +210,32 @@ static void cx8801_aud_irq(snd_cx88_card_t *chip)
 {
        struct cx88_core *core = chip->core;
        u32 status, mask;
-       u32 count;
 
        status = cx_read(MO_AUD_INTSTAT);
        mask   = cx_read(MO_AUD_INTMSK);
-       if (0 == (status & mask)) {
-               spin_unlock(&chip->reg_lock);
+       if (0 == (status & mask))
                return;
-       }
        cx_write(MO_AUD_INTSTAT, status);
        if (debug > 1  ||  (status & mask & ~0xff))
                cx88_print_irqbits(core->name, "irq aud",
                                   cx88_aud_irqs, ARRAY_SIZE(cx88_aud_irqs),
                                   status, mask);
        /* risc op code error */
-       if (status & (1 << 16)) {
-               printk(KERN_WARNING "%s/0: audio risc op code error\n",core->name);
+       if (status & AUD_INT_OPC_ERR) {
+               printk(KERN_WARNING "%s/1: Audio risc op code error\n",core->name);
                cx_clear(MO_AUD_DMACNTRL, 0x11);
                cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH25]);
        }
-
-       /* risc1 downstream */
-       if (status & 0x01) {
-               spin_lock(&chip->reg_lock);
-               count = cx_read(MO_AUDD_GPCNT);
-               spin_unlock(&chip->reg_lock);
-               if (chip->read_count == 0)
-                       chip->read_count += chip->dma_size;
+       if (status & AUD_INT_DN_SYNC) {
+               dprintk(1, "Downstream sync error\n");
+               cx_write(MO_AUDD_GPCNTRL, GP_COUNT_CONTROL_RESET);
+               return;
        }
-
-       if  (chip->read_count >= chip->period_size) {
-               dprintk(2, "Elapsing period\n");
+       /* risc1 downstream */
+       if (status & AUD_INT_DN_RISCI1) {
+               atomic_set(&chip->count, cx_read(MO_AUDD_GPCNT));
                snd_pcm_period_elapsed(chip->substream);
        }
-
-       dprintk(3,"Leaving audio IRQ handler...\n");
-
        /* FIXME: Any other status should deserve a special handling? */
 }
 
@@ -273,27 +250,26 @@ static irqreturn_t cx8801_irq(int irq, void *dev_id)
        int loop, handled = 0;
 
        for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
-               status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x02);
+               status = cx_read(MO_PCI_INTSTAT) &
+                       (core->pci_irqmask | PCI_INT_AUDINT);
                if (0 == status)
                        goto out;
-               dprintk( 3, "cx8801_irq\n" );
-               dprintk( 3, "    loop: %d/%d\n", loop, MAX_IRQ_LOOP );
-               dprintk( 3, "    status: %d\n", status );
+               dprintk(3, "cx8801_irq loop %d/%d, status %x\n",
+                       loop, MAX_IRQ_LOOP, status);
                handled = 1;
                cx_write(MO_PCI_INTSTAT, status);
 
-               if (status & 0x02)
-               {
-                       dprintk( 2, "    ALSA IRQ handling\n" );
+               if (status & core->pci_irqmask)
+                       cx88_core_irq(core, status);
+               if (status & PCI_INT_AUDINT)
                        cx8801_aud_irq(chip);
-               }
-       };
+       }
 
        if (MAX_IRQ_LOOP == loop) {
-               dprintk( 0, "clearing mask\n" );
-               dprintk(1,"%s/0: irq loop -- clearing mask\n",
+               printk(KERN_ERR
+                      "%s/1: IRQ loop detected, disabling interrupts\n",
                       core->name);
-               cx_clear(MO_PCI_INTMSK,0x02);
+               cx_clear(MO_PCI_INTMSK, PCI_INT_AUDINT);
        }
 
  out:
@@ -306,14 +282,15 @@ static int dsp_buffer_free(snd_cx88_card_t *chip)
        BUG_ON(!chip->dma_size);
 
        dprintk(2,"Freeing buffer\n");
-       videobuf_pci_dma_unmap(chip->pci, &chip->dma_risc);
-       videobuf_dma_free(&chip->dma_risc);
+       videobuf_pci_dma_unmap(chip->pci, chip->dma_risc);
+       videobuf_dma_free(chip->dma_risc);
        btcx_riscmem_free(chip->pci,&chip->buf->risc);
        kfree(chip->buf);
 
+       chip->dma_risc = NULL;
        chip->dma_size = 0;
 
-       return 0;
+       return 0;
 }
 
 /****************************************************************************
@@ -323,6 +300,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip)
 /*
  * Digital hardware definition
  */
+#define DEFAULT_FIFO_SIZE      4096
 static struct snd_pcm_hardware snd_cx88_digital_hw = {
        .info = SNDRV_PCM_INFO_MMAP |
                SNDRV_PCM_INFO_INTERLEAVED |
@@ -333,21 +311,17 @@ static struct snd_pcm_hardware snd_cx88_digital_hw = {
        .rates =                SNDRV_PCM_RATE_48000,
        .rate_min =             48000,
        .rate_max =             48000,
-       .channels_min = 1,
+       .channels_min = 2,
        .channels_max = 2,
-       .buffer_bytes_max = (2*2048),
-       .period_bytes_min = 2048,
-       .period_bytes_max = 2048,
-       .periods_min = 2,
-       .periods_max = 2,
+       /* Analog audio output will be full of clicks and pops if there
+          are not exactly four lines in the SRAM FIFO buffer.  */
+       .period_bytes_min = DEFAULT_FIFO_SIZE/4,
+       .period_bytes_max = DEFAULT_FIFO_SIZE/4,
+       .periods_min = 1,
+       .periods_max = 1024,
+       .buffer_bytes_max = (1024*1024),
 };
 
-/*
- * audio pcm capture runtime free
- */
-static void snd_card_cx88_runtime_free(struct snd_pcm_runtime *runtime)
-{
-}
 /*
  * audio pcm capture open callback
  */
@@ -357,26 +331,24 @@ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        int err;
 
-       if (test_and_set_bit(0, &chip->opened))
-               return -EBUSY;
-
-       err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+       err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS);
        if (err < 0)
                goto _error;
 
        chip->substream = substream;
 
-       chip->read_count = 0;
-       chip->read_offset = 0;
-
-       runtime->private_free = snd_card_cx88_runtime_free;
        runtime->hw = snd_cx88_digital_hw;
 
+       if (cx88_sram_channels[SRAM_CH25].fifo_size != DEFAULT_FIFO_SIZE) {
+               unsigned int bpl = cx88_sram_channels[SRAM_CH25].fifo_size / 4;
+               bpl &= ~7; /* must be multiple of 8 */
+               runtime->hw.period_bytes_min = bpl;
+               runtime->hw.period_bytes_max = bpl;
+       }
+
        return 0;
 _error:
        dprintk(1,"Error opening PCM!\n");
-       clear_bit(0, &chip->opened);
-       smp_mb__after_clear_bit();
        return err;
 }
 
@@ -385,11 +357,6 @@ _error:
  */
 static int snd_cx88_close(struct snd_pcm_substream *substream)
 {
-       snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
-
-       clear_bit(0, &chip->opened);
-       smp_mb__after_clear_bit();
-
        return 0;
 }
 
@@ -400,55 +367,67 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
                              struct snd_pcm_hw_params * hw_params)
 {
        snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
+       struct videobuf_dmabuf *dma;
+
        struct cx88_buffer *buf;
+       int ret;
 
        if (substream->runtime->dma_area) {
                dsp_buffer_free(chip);
                substream->runtime->dma_area = NULL;
        }
 
-
        chip->period_size = params_period_bytes(hw_params);
        chip->num_periods = params_periods(hw_params);
        chip->dma_size = chip->period_size * params_periods(hw_params);
 
        BUG_ON(!chip->dma_size);
+       BUG_ON(chip->num_periods & (chip->num_periods-1));
 
-       dprintk(1,"Setting buffer\n");
-
-       buf = kzalloc(sizeof(*buf),GFP_KERNEL);
+       buf = videobuf_pci_alloc(sizeof(*buf));
        if (NULL == buf)
                return -ENOMEM;
 
        buf->vb.memory = V4L2_MEMORY_MMAP;
+       buf->vb.field  = V4L2_FIELD_NONE;
        buf->vb.width  = chip->period_size;
+       buf->bpl       = chip->period_size;
        buf->vb.height = chip->num_periods;
        buf->vb.size   = chip->dma_size;
-       buf->vb.field  = V4L2_FIELD_NONE;
 
-       videobuf_dma_init(&buf->vb.dma);
-       videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE,
+       dma=videobuf_to_dma(&buf->vb);
+       videobuf_dma_init(dma);
+       ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
                        (PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT));
+       if (ret < 0)
+               goto error;
 
-       videobuf_pci_dma_map(chip->pci,&buf->vb.dma);
+       ret = videobuf_pci_dma_map(chip->pci,dma);
+       if (ret < 0)
+               goto error;
 
+       ret = cx88_risc_databuffer(chip->pci, &buf->risc, dma->sglist,
+                                  buf->vb.width, buf->vb.height, 1);
+       if (ret < 0)
+               goto error;
 
-       cx88_risc_databuffer(chip->pci, &buf->risc,
-                       buf->vb.dma.sglist,
-                       buf->vb.width, buf->vb.height);
-
-       buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+       /* Loop back to start of program */
+       buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC);
        buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
 
        buf->vb.state = STATE_PREPARED;
 
-       buf->bpl = chip->period_size;
        chip->buf = buf;
-       chip->dma_risc = buf->vb.dma;
+       chip->dma_risc = dma;
 
-       dprintk(1,"Buffer ready at %u\n",chip->dma_risc.nr_pages);
-       substream->runtime->dma_area = chip->dma_risc.vmalloc;
+       substream->runtime->dma_area = chip->dma_risc->vmalloc;
+       substream->runtime->dma_bytes = chip->dma_size;
+       substream->runtime->dma_addr = 0;
        return 0;
+
+error:
+       kfree(buf);
+       return ret;
 }
 
 /*
@@ -475,7 +454,6 @@ static int snd_cx88_prepare(struct snd_pcm_substream *substream)
        return 0;
 }
 
-
 /*
  * trigger callback
  */
@@ -484,6 +462,7 @@ static int snd_cx88_card_trigger(struct snd_pcm_substream *substream, int cmd)
        snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
        int err;
 
+       /* Local interrupts are already disabled by ALSA */
        spin_lock(&chip->reg_lock);
 
        switch (cmd) {
@@ -510,17 +489,24 @@ static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream)
 {
        snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
        struct snd_pcm_runtime *runtime = substream->runtime;
+       u16 count;
 
-       if (chip->read_count) {
-               chip->read_count -= snd_pcm_lib_period_bytes(substream);
-               chip->read_offset += snd_pcm_lib_period_bytes(substream);
-               if (chip->read_offset == chip->dma_size)
-                       chip->read_offset = 0;
-       }
+       count = atomic_read(&chip->count);
 
-       dprintk(2, "Pointer time, will return %li, read %li\n",chip->read_offset,chip->read_count);
-       return bytes_to_frames(runtime, chip->read_offset);
+//     dprintk(2, "%s - count %d (+%u), period %d, frame %lu\n", __FUNCTION__,
+//             count, new, count & (runtime->periods-1),
+//             runtime->period_size * (count & (runtime->periods-1)));
+       return runtime->period_size * (count & (runtime->periods-1));
+}
 
+/*
+ * page callback (needed for mmap)
+ */
+static struct page *snd_cx88_page(struct snd_pcm_substream *substream,
+                               unsigned long offset)
+{
+       void *pageptr = substream->runtime->dma_area + offset;
+       return vmalloc_to_page(pageptr);
 }
 
 /*
@@ -535,6 +521,7 @@ static struct snd_pcm_ops snd_cx88_pcm_ops = {
        .prepare = snd_cx88_prepare,
        .trigger = snd_cx88_card_trigger,
        .pointer = snd_cx88_pointer,
+       .page = snd_cx88_page,
 };
 
 /*
@@ -562,7 +549,7 @@ static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol,
                                        struct snd_ctl_elem_info *info)
 {
        info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-       info->count = 1;
+       info->count = 2;
        info->value.integer.min = 0;
        info->value.integer.max = 0x3f;
 
@@ -575,8 +562,12 @@ static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol,
 {
        snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
        struct cx88_core *core=chip->core;
+       int vol = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f),
+           bal = cx_read(AUD_BAL_CTL);
 
-       value->value.integer.value[0] = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);
+       value->value.integer.value[(bal & 0x40) ? 0 : 1] = vol;
+       vol -= (bal & 0x3f);
+       value->value.integer.value[(bal & 0x40) ? 1 : 0] = vol < 0 ? 0 : vol;
 
        return 0;
 }
@@ -587,16 +578,31 @@ static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol,
 {
        snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
        struct cx88_core *core=chip->core;
-       int v;
-       u32 old_control;
-
+       int v, b;
+       int changed = 0;
+       u32 old;
+
+       b = value->value.integer.value[1] - value->value.integer.value[0];
+       if (b < 0) {
+           v = 0x3f - value->value.integer.value[0];
+           b = (-b) | 0x40;
+       } else {
+           v = 0x3f - value->value.integer.value[1];
+       }
+       /* Do we really know this will always be called with IRQs on? */
        spin_lock_irq(&chip->reg_lock);
-       old_control = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f);
-       v = 0x3f - (value->value.integer.value[0] & 0x3f);
-       cx_andor(AUD_VOL_CTL, 0x3f, v);
+       old = cx_read(AUD_VOL_CTL);
+       if (v != (old & 0x3f)) {
+           cx_write(AUD_VOL_CTL, (old & ~0x3f) | v);
+           changed = 1;
+       }
+       if (cx_read(AUD_BAL_CTL) != b) {
+           cx_write(AUD_BAL_CTL, b);
+           changed = 1;
+       }
        spin_unlock_irq(&chip->reg_lock);
 
-       return v != old_control;
+       return changed;
 }
 
 static struct snd_kcontrol_new snd_cx88_capture_volume = {
@@ -665,6 +671,7 @@ static int __devinit snd_cx88_create(struct snd_card *card,
        snd_cx88_card_t   *chip;
        struct cx88_core  *core;
        int               err;
+       unsigned char     pci_lat;
 
        *rchip = NULL;
 
@@ -709,13 +716,12 @@ static int __devinit snd_cx88_create(struct snd_card *card,
        }
 
        /* print pci info */
-       pci_read_config_byte(pci, PCI_CLASS_REVISION, &chip->pci_rev);
-       pci_read_config_byte(pci, PCI_LATENCY_TIMER,  &chip->pci_lat);
+       pci_read_config_byte(pci, PCI_LATENCY_TIMER, &pci_lat);
 
        dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, "
               "latency: %d, mmio: 0x%llx\n", core->name, devno,
-              pci_name(pci), chip->pci_rev, pci->irq,
-              chip->pci_lat,(unsigned long long)pci_resource_start(pci,0));
+              pci_name(pci), pci->revision, pci->irq,
+              pci_lat, (unsigned long long)pci_resource_start(pci,0));
 
        chip->irq = pci->irq;
        synchronize_irq(chip->irq);
@@ -753,17 +759,12 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
                return (err);
 
        err = snd_cx88_pcm(chip, 0, "CX88 Digital");
-
-       if (err < 0) {
-               snd_card_free(card);
-               return (err);
-       }
+       if (err < 0)
+               goto error;
 
        err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip));
-       if (err < 0) {
-               snd_card_free(card);
-               return (err);
-       }
+       if (err < 0)
+               goto error;
 
        strcpy (card->driver, "CX88x");
        sprintf(card->shortname, "Conexant CX%x", pci->device);
@@ -775,16 +776,16 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
               card->driver,devno);
 
        err = snd_card_register(card);
-       if (err < 0) {
-               snd_card_free(card);
-               return (err);
-       }
-       snd_cx88_cards[devno] = card;
-
+       if (err < 0)
+               goto error;
        pci_set_drvdata(pci,card);
 
        devno++;
        return 0;
+
+error:
+       snd_card_free(card);
+       return err;
 }
 /*
  * ALSA destructor
index f2fcdb92ecce97d584f3584609c0045c7af6b4be..6d6f5048d7627a1d3f0923f763caafa0a06ac88e 100644 (file)
@@ -27,7 +27,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/delay.h>
@@ -734,14 +733,14 @@ static int vidioc_querycap (struct file *file, void  *priv,
        struct cx88_core  *core = dev->core;
 
        strcpy(cap->driver, "cx88_blackbird");
-       strlcpy(cap->card, cx88_boards[core->board].name,sizeof(cap->card));
+       strlcpy(cap->card, core->board.name, sizeof(cap->card));
        sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
        cap->version = CX88_VERSION_CODE;
        cap->capabilities =
                V4L2_CAP_VIDEO_CAPTURE |
                V4L2_CAP_READWRITE     |
                V4L2_CAP_STREAMING;
-       if (UNSET != core->tuner_type)
+       if (UNSET != core->board.tuner_type)
                cap->capabilities |= V4L2_CAP_TUNER;
        return 0;
 }
@@ -877,7 +876,7 @@ static int vidioc_g_ext_ctrls (struct file *file, void *priv,
 
        if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
                return -EINVAL;
-       return cx2341x_ext_ctrls(&dev->params, f, VIDIOC_G_EXT_CTRLS);
+       return cx2341x_ext_ctrls(&dev->params, 0, f, VIDIOC_G_EXT_CTRLS);
 }
 
 static int vidioc_s_ext_ctrls (struct file *file, void *priv,
@@ -890,7 +889,7 @@ static int vidioc_s_ext_ctrls (struct file *file, void *priv,
        if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
                return -EINVAL;
        p = dev->params;
-       err = cx2341x_ext_ctrls(&p, f, VIDIOC_S_EXT_CTRLS);
+       err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS);
        if (!err) {
                err = cx2341x_update(dev, blackbird_mbox_func, &dev->params, &p);
                dev->params = p;
@@ -908,7 +907,7 @@ static int vidioc_try_ext_ctrls (struct file *file, void *priv,
        if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
                return -EINVAL;
        p = dev->params;
-       err = cx2341x_ext_ctrls(&p, f, VIDIOC_TRY_EXT_CTRLS);
+       err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
 
        return err;
 }
@@ -990,7 +989,7 @@ static int vidioc_g_frequency (struct file *file, void *priv,
        struct cx8802_fh  *fh   = priv;
        struct cx88_core  *core = fh->dev->core;
 
-       if (unlikely(UNSET == core->tuner_type))
+       if (unlikely(UNSET == core->board.tuner_type))
                return -EINVAL;
 
        f->type = V4L2_TUNER_ANALOG_TV;
@@ -1028,7 +1027,7 @@ static int vidioc_g_tuner (struct file *file, void *priv,
        struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;
        u32 reg;
 
-       if (unlikely(UNSET == core->tuner_type))
+       if (unlikely(UNSET == core->board.tuner_type))
                return -EINVAL;
        if (0 != t->index)
                return -EINVAL;
@@ -1049,7 +1048,7 @@ static int vidioc_s_tuner (struct file *file, void *priv,
 {
        struct cx88_core  *core = ((struct cx8802_fh *)priv)->dev->core;
 
-       if (UNSET == core->tuner_type)
+       if (UNSET == core->board.tuner_type)
                return -EINVAL;
        if (0 != t->index)
                return -EINVAL;
@@ -1078,7 +1077,7 @@ static int mpeg_open(struct inode *inode, struct file *file)
        struct cx8802_driver *drv = NULL;
        int err;
 
-       dev = cx8802_get_device(inode);
+       dev = cx8802_get_device(inode);
 
        dprintk( 1, "%s\n", __FUNCTION__);
 
@@ -1112,7 +1111,7 @@ static int mpeg_open(struct inode *inode, struct file *file)
        file->private_data = fh;
        fh->dev      = dev;
 
-       videobuf_queue_init(&fh->mpegq, &blackbird_qops,
+       videobuf_queue_pci_init(&fh->mpegq, &blackbird_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_INTERLACED,
@@ -1235,7 +1234,7 @@ static struct video_device cx8802_mpeg_template =
        .vidioc_s_tuner       = vidioc_s_tuner,
        .vidioc_s_std         = vidioc_s_std,
        .tvnorms              = CX88_NORMS,
-       .current_norm         = V4L2_STD_NTSC_M,
+       .current_norm         = V4L2_STD_NTSC_M,
 };
 
 /* ------------------------------------------------------------------ */
@@ -1246,7 +1245,7 @@ static int cx8802_blackbird_advise_acquire(struct cx8802_driver *drv)
        struct cx88_core *core = drv->core;
        int err = 0;
 
-       switch (core->board) {
+       switch (core->boardnr) {
        case CX88_BOARD_HAUPPAUGE_HVR1300:
                /* By default, core setup will leave the cx22702 out of reset, on the bus.
                 * We left the hardware on power up with the cx22702 active.
@@ -1268,7 +1267,7 @@ static int cx8802_blackbird_advise_release(struct cx8802_driver *drv)
        struct cx88_core *core = drv->core;
        int err = 0;
 
-       switch (core->board) {
+       switch (core->boardnr) {
        case CX88_BOARD_HAUPPAUGE_HVR1300:
                /* Exit leaving the cx23416 on the bus */
                break;
@@ -1316,13 +1315,13 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
 
        dprintk( 1, "%s\n", __FUNCTION__);
        dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
-               core->board,
+               core->boardnr,
                core->name,
                core->pci_bus,
                core->pci_slot);
 
        err = -ENODEV;
-       if (!(cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD))
+       if (!(core->board.mpeg & CX88_MPEG_BLACKBIRD))
                goto fail_core;
 
        dev->width = 720;
index 6a136ddbccf852c8bb02a762a08778f36e43aed1..a4eb6a87a761ded2d022726c117429d3ff07eee8 100644 (file)
 
 #include "cx88.h"
 
+static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
+static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
+static unsigned int card[]  = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
+
+module_param_array(tuner, int, NULL, 0444);
+module_param_array(radio, int, NULL, 0444);
+module_param_array(card,  int, NULL, 0444);
+
+MODULE_PARM_DESC(tuner,"tuner type");
+MODULE_PARM_DESC(radio,"radio tuner type");
+MODULE_PARM_DESC(card,"card type");
+
+static unsigned int latency = UNSET;
+module_param(latency,int,0444);
+MODULE_PARM_DESC(latency,"pci latency timer");
+
 /* ------------------------------------------------------------------ */
 /* board config info                                                  */
 
-struct cx88_board cx88_boards[] = {
+static const struct cx88_board cx88_boards[] = {
        [CX88_BOARD_UNKNOWN] = {
                .name           = "UNKNOWN/GENERIC",
                .tuner_type     = UNSET,
@@ -575,35 +591,34 @@ struct cx88_board cx88_boards[] = {
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
                .tda9887_conf   = TDA9887_PRESENT,
+               /* GPIO[2] = audio source for analog audio out connector
+                *  0 = analog audio input connector
+                *  1 = CX88 audio DACs
+                *
+                * GPIO[7] = input to CX88's audio/chroma ADC
+                *  0 = FM 10.7 MHz IF
+                *  1 = Sound 4.5 MHz IF
+                *
+                * GPIO[1,5,6] = Oren 51132 pins 27,35,28 respectively
+                *
+                * GPIO[16] = Remote control input
+                */
                .input          = {{
                        .type   = CX88_VMUX_TELEVISION,
                        .vmux   = 0,
                        .gpio0  = 0x00008484,
-                       .gpio1  = 0x00000000,
-                       .gpio2  = 0x00000000,
-                       .gpio3  = 0x00000000,
                },{
                        .type   = CX88_VMUX_COMPOSITE1,
                        .vmux   = 1,
                        .gpio0  = 0x00008400,
-                       .gpio1  = 0x00000000,
-                       .gpio2  = 0x00000000,
-                       .gpio3  = 0x00000000,
                },{
                        .type   = CX88_VMUX_SVIDEO,
                        .vmux   = 2,
                        .gpio0  = 0x00008400,
-                       .gpio1  = 0x00000000,
-                       .gpio2  = 0x00000000,
-                       .gpio3  = 0x00000000,
                }},
                .radio = {
                        .type   = CX88_RADIO,
-                       .vmux   = 2,
-                       .gpio0  = 0x00008400,
-                       .gpio1  = 0x00000000,
-                       .gpio2  = 0x00000000,
-                       .gpio3  = 0x00000000,
+                       .gpio0  = 0x00008404,
                },
                .mpeg           = CX88_MPEG_DVB,
        },
@@ -1356,12 +1371,11 @@ struct cx88_board cx88_boards[] = {
                }},
        },
 };
-const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
 
 /* ------------------------------------------------------------------ */
 /* PCI subsystem IDs                                                  */
 
-struct cx88_subid cx88_subids[] = {
+static const struct cx88_subid cx88_subids[] = {
        {
                .subvendor = 0x0070,
                .subdevice = 0x3400,
@@ -1667,7 +1681,6 @@ struct cx88_subid cx88_subids[] = {
                .card      = CX88_BOARD_ADSTECH_PTV_390,
        },
 };
-const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
 
 /* ----------------------------------------------------------------------- */
 /* some leadtek specific stuff                                             */
@@ -1688,12 +1701,12 @@ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
                return;
        }
 
-       core->has_radio  = 1;
-       core->tuner_type = (eeprom_data[6] == 0x13) ? 43 : 38;
+       core->board.tuner_type = (eeprom_data[6] == 0x13) ?
+               TUNER_PHILIPS_FM1236_MK3 : TUNER_PHILIPS_FM1216ME_MK3;
 
        printk(KERN_INFO "%s: Leadtek Winfast 2000XP Expert config: "
               "tuner=%d, eeprom[0]=0x%02x\n",
-              core->name, core->tuner_type, eeprom_data[0]);
+              core->name, core->board.tuner_type, eeprom_data[0]);
 }
 
 static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
@@ -1701,9 +1714,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
        struct tveeprom tv;
 
        tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data);
-       core->tuner_type = tv.tuner_type;
+       core->board.tuner_type = tv.tuner_type;
        core->tuner_formats = tv.tuner_formats;
-       core->has_radio  = tv.has_radio;
+       core->board.radio.type = tv.has_radio ? CX88_RADIO : 0;
 
        /* Make sure we support the board model */
        switch (tv.model)
@@ -1793,8 +1806,9 @@ static void gdi_eeprom(struct cx88_core *core, u8 *eeprom_data)
               name ? name : "unknown");
        if (NULL == name)
                return;
-       core->tuner_type = gdi_tuner[eeprom_data[0x0d]].id;
-       core->has_radio  = gdi_tuner[eeprom_data[0x0d]].fm;
+       core->board.tuner_type = gdi_tuner[eeprom_data[0x0d]].id;
+       core->board.radio.type = gdi_tuner[eeprom_data[0x0d]].fm ?
+               CX88_RADIO : 0;
 }
 
 /* ----------------------------------------------------------------------- */
@@ -1833,7 +1847,7 @@ static void dvico_fusionhdtv_hybrid_init(struct cx88_core *core)
 
 /* ----------------------------------------------------------------------- */
 
-void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
+static void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
 {
        int i;
 
@@ -1854,14 +1868,14 @@ void cx88_card_list(struct cx88_core *core, struct pci_dev *pci)
        }
        printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
               core->name);
-       for (i = 0; i < cx88_bcount; i++)
+       for (i = 0; i < ARRAY_SIZE(cx88_boards); i++)
                printk("%s:    card=%d -> %s\n",
                       core->name, i, cx88_boards[i].name);
 }
 
-void cx88_card_setup_pre_i2c(struct cx88_core *core)
+static void cx88_card_setup_pre_i2c(struct cx88_core *core)
 {
-       switch (core->board) {
+       switch (core->boardnr) {
        case CX88_BOARD_HAUPPAUGE_HVR1300:
                /* Bring the 702 demod up before i2c scanning/attach or devices are hidden */
                /* We leave here with the 702 on the bus */
@@ -1875,7 +1889,7 @@ void cx88_card_setup_pre_i2c(struct cx88_core *core)
        }
 }
 
-void cx88_card_setup(struct cx88_core *core)
+static void cx88_card_setup(struct cx88_core *core)
 {
        static u8 eeprom[256];
 
@@ -1884,7 +1898,7 @@ void cx88_card_setup(struct cx88_core *core)
                tveeprom_read(&core->i2c_client,eeprom,sizeof(eeprom));
        }
 
-       switch (core->board) {
+       switch (core->boardnr) {
        case CX88_BOARD_HAUPPAUGE:
        case CX88_BOARD_HAUPPAUGE_ROSLYN:
                if (0 == core->i2c_rc)
@@ -1928,7 +1942,7 @@ void cx88_card_setup(struct cx88_core *core)
                msleep(1);
                cx_set(MO_GP0_IO, 0x00000101);
                if (0 == core->i2c_rc &&
-                   core->board == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID)
+                   core->boardnr == CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID)
                        dvico_fusionhdtv_hybrid_init(core);
                break;
        case CX88_BOARD_KWORLD_DVB_T:
@@ -1966,13 +1980,148 @@ void cx88_card_setup(struct cx88_core *core)
                }
                break;
        }
-       if (cx88_boards[core->board].radio.type == CX88_RADIO)
-               core->has_radio = 1;
 }
 
 /* ------------------------------------------------------------------ */
 
-EXPORT_SYMBOL(cx88_boards);
+static int cx88_pci_quirks(const char *name, struct pci_dev *pci)
+{
+       unsigned int lat = UNSET;
+       u8 ctrl = 0;
+       u8 value;
+
+       /* check pci quirks */
+       if (pci_pci_problems & PCIPCI_TRITON) {
+               printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n",
+                      name);
+               ctrl |= CX88X_EN_TBFX;
+       }
+       if (pci_pci_problems & PCIPCI_NATOMA) {
+               printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n",
+                      name);
+               ctrl |= CX88X_EN_TBFX;
+       }
+       if (pci_pci_problems & PCIPCI_VIAETBF) {
+               printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n",
+                      name);
+               ctrl |= CX88X_EN_TBFX;
+       }
+       if (pci_pci_problems & PCIPCI_VSFX) {
+               printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n",
+                      name);
+               ctrl |= CX88X_EN_VSFX;
+       }
+#ifdef PCIPCI_ALIMAGIK
+       if (pci_pci_problems & PCIPCI_ALIMAGIK) {
+               printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
+                      name);
+               lat = 0x0A;
+       }
+#endif
+
+       /* check insmod options */
+       if (UNSET != latency)
+               lat = latency;
+
+       /* apply stuff */
+       if (ctrl) {
+               pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
+               value |= ctrl;
+               pci_write_config_byte(pci, CX88X_DEVCTRL, value);
+       }
+       if (UNSET != lat) {
+               printk(KERN_INFO "%s: setting pci latency timer to %d\n",
+                      name, latency);
+               pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
+       }
+       return 0;
+}
+
+int cx88_get_resources(const struct cx88_core *core, struct pci_dev *pci)
+{
+       if (request_mem_region(pci_resource_start(pci,0),
+                              pci_resource_len(pci,0),
+                              core->name))
+               return 0;
+       printk(KERN_ERR
+              "%s/%d: Can't get MMIO memory @ 0x%llx, subsystem: %04x:%04x\n",
+              core->name, PCI_FUNC(pci->devfn),
+              (unsigned long long)pci_resource_start(pci, 0),
+              pci->subsystem_vendor, pci->subsystem_device);
+       return -EBUSY;
+}
+
+/* Allocate and initialize the cx88 core struct.  One should hold the
+ * devlist mutex before calling this.  */
+struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
+{
+       struct cx88_core *core;
+       int i;
+
+       core = kzalloc(sizeof(*core), GFP_KERNEL);
+
+       atomic_inc(&core->refcount);
+       core->pci_bus  = pci->bus->number;
+       core->pci_slot = PCI_SLOT(pci->devfn);
+       core->pci_irqmask = PCI_INT_RISC_RD_BERRINT | PCI_INT_RISC_WR_BERRINT |
+                           PCI_INT_BRDG_BERRINT | PCI_INT_SRC_DMA_BERRINT |
+                           PCI_INT_DST_DMA_BERRINT | PCI_INT_IPB_DMA_BERRINT;
+       mutex_init(&core->lock);
+
+       core->nr = nr;
+       sprintf(core->name, "cx88[%d]", core->nr);
+       if (0 != cx88_get_resources(core, pci)) {
+               kfree(core);
+               return NULL;
+       }
+
+       /* PCI stuff */
+       cx88_pci_quirks(core->name, pci);
+       core->lmmio = ioremap(pci_resource_start(pci, 0),
+                             pci_resource_len(pci, 0));
+       core->bmmio = (u8 __iomem *)core->lmmio;
+
+       /* board config */
+       core->boardnr = UNSET;
+       if (card[core->nr] < ARRAY_SIZE(cx88_boards))
+               core->boardnr = card[core->nr];
+       for (i = 0; UNSET == core->boardnr && i < ARRAY_SIZE(cx88_subids); i++)
+               if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
+                   pci->subsystem_device == cx88_subids[i].subdevice)
+                       core->boardnr = cx88_subids[i].card;
+       if (UNSET == core->boardnr) {
+               core->boardnr = CX88_BOARD_UNKNOWN;
+               cx88_card_list(core, pci);
+       }
+
+       memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board));
+
+       printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+               core->name,pci->subsystem_vendor,
+               pci->subsystem_device, core->board.name,
+               core->boardnr, card[core->nr] == core->boardnr ?
+               "insmod option" : "autodetected");
+
+       if (tuner[core->nr] != UNSET)
+               core->board.tuner_type = tuner[core->nr];
+       if (radio[core->nr] != UNSET)
+               core->board.radio_type = radio[core->nr];
+
+       printk(KERN_INFO "%s: TV tuner type %d, Radio tuner type %d\n",
+              core->name, core->board.tuner_type, core->board.radio_type);
+
+       /* init hardware */
+       cx88_reset(core);
+       cx88_card_setup_pre_i2c(core);
+       cx88_i2c_init(core, pci);
+       cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
+       cx88_card_setup(core);
+       cx88_ir_init(core, pci);
+
+       return core;
+}
+
+/* ------------------------------------------------------------------ */
 
 /*
  * Local variables:
index f31ec96924b9e6a8273c2e208dbe052b0d282115..62e8dd24c5f5413b978f6019a1d8b01c955aa4ed 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
@@ -52,22 +51,6 @@ static unsigned int core_debug = 0;
 module_param(core_debug,int,0644);
 MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
 
-static unsigned int latency = UNSET;
-module_param(latency,int,0444);
-MODULE_PARM_DESC(latency,"pci latency timer");
-
-static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
-static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
-static unsigned int card[]  = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
-
-module_param_array(tuner, int, NULL, 0444);
-module_param_array(radio, int, NULL, 0444);
-module_param_array(card,  int, NULL, 0444);
-
-MODULE_PARM_DESC(tuner,"tuner type");
-MODULE_PARM_DESC(radio,"radio tuner type");
-MODULE_PARM_DESC(card,"card type");
-
 static unsigned int nicam = 0;
 module_param(nicam,int,0644);
 MODULE_PARM_DESC(nicam,"tv audio is nicam");
@@ -85,13 +68,15 @@ static DEFINE_MUTEX(devlist);
 
 #define NO_SYNC_LINE (-1U)
 
+/* @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be
+        generated _after_ lpi lines are transferred. */
 static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
                            unsigned int offset, u32 sync_line,
                            unsigned int bpl, unsigned int padding,
-                           unsigned int lines)
+                           unsigned int lines, unsigned int lpi)
 {
        struct scatterlist *sg;
-       unsigned int line,todo;
+       unsigned int line,todo,sol;
 
        /* sync instruction */
        if (sync_line != NO_SYNC_LINE)
@@ -104,15 +89,19 @@ static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
                        offset -= sg_dma_len(sg);
                        sg++;
                }
+               if (lpi && line>0 && !(line % lpi))
+                       sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
+               else
+                       sol = RISC_SOL;
                if (bpl <= sg_dma_len(sg)-offset) {
                        /* fits into current chunk */
-                       *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
+                       *(rp++)=cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl);
                        *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
                        offset+=bpl;
                } else {
                        /* scanline needs to be split */
                        todo = bpl;
-                       *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
+                       *(rp++)=cpu_to_le32(RISC_WRITE|sol|
                                            (sg_dma_len(sg)-offset));
                        *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
                        todo -= (sg_dma_len(sg)-offset);
@@ -163,10 +152,10 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
        rp = risc->cpu;
        if (UNSET != top_offset)
                rp = cx88_risc_field(rp, sglist, top_offset, 0,
-                                    bpl, padding, lines);
+                                    bpl, padding, lines, 0);
        if (UNSET != bottom_offset)
                rp = cx88_risc_field(rp, sglist, bottom_offset, 0x200,
-                                    bpl, padding, lines);
+                                    bpl, padding, lines, 0);
 
        /* save pointer to jmp instruction address */
        risc->jmp = rp;
@@ -176,7 +165,7 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 
 int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
                         struct scatterlist *sglist, unsigned int bpl,
-                        unsigned int lines)
+                        unsigned int lines, unsigned int lpi)
 {
        u32 instructions;
        u32 *rp;
@@ -193,7 +182,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 
        /* write risc instructions */
        rp = risc->cpu;
-       rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines);
+       rp = cx88_risc_field(rp, sglist, 0, NO_SYNC_LINE, bpl, 0, lines, lpi);
 
        /* save pointer to jmp instruction address */
        risc->jmp = rp;
@@ -224,10 +213,12 @@ int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
 void
 cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
 {
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
+
        BUG_ON(in_interrupt());
        videobuf_waiton(&buf->vb,0,0);
-       videobuf_dma_unmap(q, &buf->vb.dma);
-       videobuf_dma_free(&buf->vb.dma);
+       videobuf_dma_unmap(q, dma);
+       videobuf_dma_free(dma);
        btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
        buf->vb.state = STATE_NEEDS_INIT;
 }
@@ -451,10 +442,13 @@ void cx88_sram_channel_dump(struct cx88_core *core,
                printk("%s:   cmds: %-12s: 0x%08x\n",
                       core->name,name[i],
                       cx_read(ch->cmds_start + 4*i));
-       for (i = 0; i < 4; i++) {
+       for (n = 1, i = 0; i < 4; i++) {
                risc = cx_read(ch->cmds_start + 4 * (i+11));
                printk("%s:   risc%d: ", core->name, i);
-               cx88_risc_decode(risc);
+               if (--n)
+                       printk("0x%08x [ arg #%d ]\n", risc, n);
+               else
+                       n = cx88_risc_decode(risc);
        }
        for (i = 0; i < 16; i += n) {
                risc = cx_read(ch->ctrl_start + 4 * i);
@@ -514,7 +508,7 @@ int cx88_core_irq(struct cx88_core *core, u32 status)
 {
        int handled = 0;
 
-       if (status & (1<<18)) {
+       if (status & PCI_INT_IR_SMPINT) {
                cx88_ir_irq(core);
                handled++;
        }
@@ -738,7 +732,7 @@ int cx88_set_scale(struct cx88_core *core, unsigned int width, unsigned int heig
                value |= (1 << 15);
                value |= (1 << 16);
        }
-       if (INPUT(core->input)->type == CX88_VMUX_SVIDEO)
+       if (INPUT(core->input).type == CX88_VMUX_SVIDEO)
                value |= (1 << 13) | (1 << 5);
        if (V4L2_FIELD_INTERLACED == field)
                value |= (1 << 3); // VINT (interlaced vertical scaling)
@@ -833,7 +827,7 @@ static int set_tvaudio(struct cx88_core *core)
 {
        v4l2_std_id norm = core->tvnorm;
 
-       if (CX88_VMUX_TELEVISION != INPUT(core->input)->type)
+       if (CX88_VMUX_TELEVISION != INPUT(core->input).type)
                return 0;
 
        if (V4L2_STD_PAL_BG & norm) {
@@ -997,61 +991,6 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
 
 /* ------------------------------------------------------------------ */
 
-static int cx88_pci_quirks(char *name, struct pci_dev *pci)
-{
-       unsigned int lat = UNSET;
-       u8 ctrl = 0;
-       u8 value;
-
-       /* check pci quirks */
-       if (pci_pci_problems & PCIPCI_TRITON) {
-               printk(KERN_INFO "%s: quirk: PCIPCI_TRITON -- set TBFX\n",
-                      name);
-               ctrl |= CX88X_EN_TBFX;
-       }
-       if (pci_pci_problems & PCIPCI_NATOMA) {
-               printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA -- set TBFX\n",
-                      name);
-               ctrl |= CX88X_EN_TBFX;
-       }
-       if (pci_pci_problems & PCIPCI_VIAETBF) {
-               printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF -- set TBFX\n",
-                      name);
-               ctrl |= CX88X_EN_TBFX;
-       }
-       if (pci_pci_problems & PCIPCI_VSFX) {
-               printk(KERN_INFO "%s: quirk: PCIPCI_VSFX -- set VSFX\n",
-                      name);
-               ctrl |= CX88X_EN_VSFX;
-       }
-#ifdef PCIPCI_ALIMAGIK
-       if (pci_pci_problems & PCIPCI_ALIMAGIK) {
-               printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK -- latency fixup\n",
-                      name);
-               lat = 0x0A;
-       }
-#endif
-
-       /* check insmod options */
-       if (UNSET != latency)
-               lat = latency;
-
-       /* apply stuff */
-       if (ctrl) {
-               pci_read_config_byte(pci, CX88X_DEVCTRL, &value);
-               value |= ctrl;
-               pci_write_config_byte(pci, CX88X_DEVCTRL, value);
-       }
-       if (UNSET != lat) {
-               printk(KERN_INFO "%s: setting pci latency timer to %d\n",
-                      name, latency);
-               pci_write_config_byte(pci, PCI_LATENCY_TIMER, latency);
-       }
-       return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
 struct video_device *cx88_vdev_init(struct cx88_core *core,
                                    struct pci_dev *pci,
                                    struct video_device *template,
@@ -1067,122 +1006,38 @@ struct video_device *cx88_vdev_init(struct cx88_core *core,
        vfd->dev     = &pci->dev;
        vfd->release = video_device_release;
        snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
-                core->name, type, cx88_boards[core->board].name);
+                core->name, type, core->board.name);
        return vfd;
 }
 
-static int get_ressources(struct cx88_core *core, struct pci_dev *pci)
-{
-       if (request_mem_region(pci_resource_start(pci,0),
-                              pci_resource_len(pci,0),
-                              core->name))
-               return 0;
-       printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
-              core->name,(unsigned long long)pci_resource_start(pci,0));
-       return -EBUSY;
-}
-
 struct cx88_core* cx88_core_get(struct pci_dev *pci)
 {
        struct cx88_core *core;
-       struct list_head *item;
-       int i;
 
        mutex_lock(&devlist);
-       list_for_each(item,&cx88_devlist) {
-               core = list_entry(item, struct cx88_core, devlist);
+       list_for_each_entry(core, &cx88_devlist, devlist) {
                if (pci->bus->number != core->pci_bus)
                        continue;
                if (PCI_SLOT(pci->devfn) != core->pci_slot)
                        continue;
 
-               if (0 != get_ressources(core,pci))
-                       goto fail_unlock;
+               if (0 != cx88_get_resources(core, pci)) {
+                       mutex_unlock(&devlist);
+                       return NULL;
+               }
                atomic_inc(&core->refcount);
                mutex_unlock(&devlist);
                return core;
        }
-       core = kzalloc(sizeof(*core),GFP_KERNEL);
-       if (NULL == core)
-               goto fail_unlock;
-
-       atomic_inc(&core->refcount);
-       core->pci_bus  = pci->bus->number;
-       core->pci_slot = PCI_SLOT(pci->devfn);
-       core->pci_irqmask = 0x00fc00;
-       mutex_init(&core->lock);
-
-       core->nr = cx88_devcount++;
-       sprintf(core->name,"cx88[%d]",core->nr);
-       if (0 != get_ressources(core,pci)) {
-               printk(KERN_ERR "CORE %s No more PCI ressources for "
-                       "subsystem: %04x:%04x, board: %s\n",
-                       core->name,pci->subsystem_vendor,
-                       pci->subsystem_device,
-                       cx88_boards[core->board].name);
-
-               cx88_devcount--;
-               goto fail_free;
-       }
-       list_add_tail(&core->devlist,&cx88_devlist);
-
-       /* PCI stuff */
-       cx88_pci_quirks(core->name, pci);
-       core->lmmio = ioremap(pci_resource_start(pci,0),
-                             pci_resource_len(pci,0));
-       core->bmmio = (u8 __iomem *)core->lmmio;
-
-       /* board config */
-       core->board = UNSET;
-       if (card[core->nr] < cx88_bcount)
-               core->board = card[core->nr];
-       for (i = 0; UNSET == core->board  &&  i < cx88_idcount; i++)
-               if (pci->subsystem_vendor == cx88_subids[i].subvendor &&
-                   pci->subsystem_device == cx88_subids[i].subdevice)
-                       core->board = cx88_subids[i].card;
-       if (UNSET == core->board) {
-               core->board = CX88_BOARD_UNKNOWN;
-               cx88_card_list(core,pci);
+
+       core = cx88_core_create(pci, cx88_devcount);
+       if (NULL != core) {
+               cx88_devcount++;
+               list_add_tail(&core->devlist, &cx88_devlist);
        }
-       printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
-               core->name,pci->subsystem_vendor,
-               pci->subsystem_device,cx88_boards[core->board].name,
-               core->board, card[core->nr] == core->board ?
-               "insmod option" : "autodetected");
-
-       core->tuner_type = tuner[core->nr];
-       core->radio_type = radio[core->nr];
-       if (UNSET == core->tuner_type)
-               core->tuner_type = cx88_boards[core->board].tuner_type;
-       if (UNSET == core->radio_type)
-               core->radio_type = cx88_boards[core->board].radio_type;
-       if (!core->tuner_addr)
-               core->tuner_addr = cx88_boards[core->board].tuner_addr;
-       if (!core->radio_addr)
-               core->radio_addr = cx88_boards[core->board].radio_addr;
-
-       printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
-               core->tuner_type, core->tuner_addr<<1,
-               core->radio_type, core->radio_addr<<1);
-
-       core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
-
-       /* init hardware */
-       cx88_reset(core);
-       cx88_card_setup_pre_i2c(core);
-       cx88_i2c_init(core,pci);
-       cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
-       cx88_card_setup(core);
-       cx88_ir_init(core,pci);
 
        mutex_unlock(&devlist);
        return core;
-
-fail_free:
-       kfree(core);
-fail_unlock:
-       mutex_unlock(&devlist);
-       return NULL;
 }
 
 void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
@@ -1229,6 +1084,9 @@ EXPORT_SYMBOL(cx88_vdev_init);
 EXPORT_SYMBOL(cx88_core_get);
 EXPORT_SYMBOL(cx88_core_put);
 
+EXPORT_SYMBOL(cx88_ir_start);
+EXPORT_SYMBOL(cx88_ir_stop);
+
 /*
  * Local variables:
  * c-basic-offset: 8
index 1773b40467dc176b808cbc15e8cbc18c803f46a6..d16e5c6d21c07c325b3da0895f0550b5d4723f0f 100644 (file)
@@ -378,7 +378,7 @@ static int dvb_register(struct cx8802_dev *dev)
        dev->ts_gen_cntrl = 0x0c;
 
        /* init frontend */
-       switch (dev->core->board) {
+       switch (dev->core->boardnr) {
        case CX88_BOARD_HAUPPAUGE_DVB_T1:
                dev->dvb.frontend = dvb_attach(cx22702_attach,
                                               &connexant_refboard_config,
@@ -482,7 +482,7 @@ static int dvb_register(struct cx8802_dev *dev)
                                   &dev->core->i2c_adap, DVB_PLL_FMD1216ME);
                }
 #else
-               printk("%s: built without vp3054 support\n", dev->core->name);
+               printk(KERN_ERR "%s/2: built without vp3054 support\n", dev->core->name);
 #endif
                break;
        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
@@ -625,12 +625,12 @@ static int dvb_register(struct cx8802_dev *dev)
                }
                break;
        default:
-               printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
+               printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
                       dev->core->name);
                break;
        }
        if (NULL == dev->dvb.frontend) {
-               printk("%s: frontend initialization failed\n",dev->core->name);
+               printk(KERN_ERR "%s/2: frontend initialization failed\n", dev->core->name);
                return -1;
        }
 
@@ -653,7 +653,7 @@ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
        int err = 0;
        dprintk( 1, "%s\n", __FUNCTION__);
 
-       switch (core->board) {
+       switch (core->boardnr) {
        case CX88_BOARD_HAUPPAUGE_HVR1300:
                /* We arrive here with either the cx23416 or the cx22702
                 * on the bus. Take the bus from the cx23416 and enable the
@@ -676,7 +676,7 @@ static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
        int err = 0;
        dprintk( 1, "%s\n", __FUNCTION__);
 
-       switch (core->board) {
+       switch (core->boardnr) {
        case CX88_BOARD_HAUPPAUGE_HVR1300:
                /* Do Nothing, leave the cx22702 on the bus. */
                break;
@@ -694,13 +694,13 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
 
        dprintk( 1, "%s\n", __FUNCTION__);
        dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
-               core->board,
+               core->boardnr,
                core->name,
                core->pci_bus,
                core->pci_slot);
 
        err = -ENODEV;
-       if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB))
+       if (!(core->board.mpeg & CX88_MPEG_DVB))
                goto fail_core;
 
        /* If vp3054 isn't enabled, a stub will just return 0 */
@@ -709,8 +709,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
                goto fail_core;
 
        /* dvb stuff */
-       printk("%s/2: cx2388x based dvb card\n", core->name);
-       videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
+       printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
+       videobuf_queue_pci_init(&dev->dvb.dvbq, &dvb_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_TOP,
@@ -718,7 +718,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
                            dev);
        err = dvb_register(dev);
        if (err != 0)
-               printk("%s dvb_register failed err = %d\n", __FUNCTION__, err);
+               printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
+                      core->name, err);
 
  fail_core:
        return err;
@@ -747,7 +748,7 @@ static struct cx8802_driver cx8802_dvb_driver = {
 
 static int dvb_init(void)
 {
-       printk(KERN_INFO "cx2388x dvb driver version %d.%d.%d loaded\n",
+       printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n",
               (CX88_VERSION_CODE >> 16) & 0xff,
               (CX88_VERSION_CODE >>  8) & 0xff,
               CX88_VERSION_CODE & 0xff);
index 78bbcfab96700ba9019c20a383db1f5ab5dc5984..c8b1c50625f4701455edd0632f4ad18ef409fabc 100644 (file)
@@ -28,7 +28,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 
 #include <asm/io.h>
@@ -108,28 +107,28 @@ static int attach_inform(struct i2c_client *client)
        if (!client->driver->command)
                return 0;
 
-       if (core->radio_type != UNSET) {
-               if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) {
+       if (core->board.radio_type != UNSET) {
+               if ((core->board.radio_addr==ADDR_UNSET)||(core->board.radio_addr==client->addr)) {
                        tun_setup.mode_mask = T_RADIO;
-                       tun_setup.type = core->radio_type;
-                       tun_setup.addr = core->radio_addr;
+                       tun_setup.type = core->board.radio_type;
+                       tun_setup.addr = core->board.radio_addr;
 
                        client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
                }
        }
-       if (core->tuner_type != UNSET) {
-               if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) {
+       if (core->board.tuner_type != UNSET) {
+               if ((core->board.tuner_addr==ADDR_UNSET)||(core->board.tuner_addr==client->addr)) {
 
                        tun_setup.mode_mask = T_ANALOG_TV;
-                       tun_setup.type = core->tuner_type;
-                       tun_setup.addr = core->tuner_addr;
+                       tun_setup.type = core->board.tuner_type;
+                       tun_setup.addr = core->board.tuner_addr;
 
                        client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
                }
        }
 
-       if (core->tda9887_conf)
-               client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
+       if (core->board.tda9887_conf)
+               client->driver->command(client, TDA9887_SET_CONFIG, &core->board.tda9887_conf);
        return 0;
 }
 
@@ -146,7 +145,7 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
        if (0 != core->i2c_rc)
                return;
 
-#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
+#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
        if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) {
                if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
                        core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
@@ -204,9 +203,9 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
        memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,
               sizeof(core->i2c_algo));
 
-       if (core->tuner_type != TUNER_ABSENT)
+       if (core->board.tuner_type != TUNER_ABSENT)
                core->i2c_adap.class |= I2C_CLASS_TV_ANALOG;
-       if (cx88_boards[core->board].mpeg & CX88_MPEG_DVB)
+       if (core->board.mpeg & CX88_MPEG_DVB)
                core->i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
 
        core->i2c_adap.dev.parent = &pci->dev;
index f5d4a565346e30cb43c2d7d41b5c07b9cee7a9ae..e52de3968c6351d4fa4cd60874ca767db8e87d2b 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/input.h>
 #include <linux/pci.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 
 #include "cx88.h"
 #include <media/ir-common.h>
@@ -74,7 +73,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
 
        /* read gpio value */
        gpio = cx_read(ir->gpio_addr);
-       switch (core->board) {
+       switch (core->boardnr) {
        case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
                /* This board apparently uses a combination of 2 GPIO
                   to represent the keys. Additionally, the second GPIO
@@ -113,7 +112,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
                   (gpio & ir->mask_keydown) ? " down" : "",
                   (gpio & ir->mask_keyup) ? " up" : "");
 
-       if (ir->core->board == CX88_BOARD_NORWOOD_MICRO) {
+       if (ir->core->boardnr == CX88_BOARD_NORWOOD_MICRO) {
                u32 gpio_key = cx_read(MO_GP0_IO);
 
                data = (data << 4) | ((gpio_key & 0xf0) >> 4);
@@ -159,7 +158,7 @@ static void cx88_ir_work(struct work_struct *work)
        mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
 }
 
-static void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
+void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
 {
        if (ir->polling) {
                setup_timer(&ir->timer, ir_timer, (unsigned long)ir);
@@ -167,17 +166,17 @@ static void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
                schedule_work(&ir->work);
        }
        if (ir->sampling) {
-               core->pci_irqmask |= (1 << 18); /* IR_SMP_INT */
+               core->pci_irqmask |= PCI_INT_IR_SMPINT;
                cx_write(MO_DDS_IO, 0xa80a80);  /* 4 kHz sample rate */
                cx_write(MO_DDSCFG_IO, 0x5);    /* enable */
        }
 }
 
-static void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir)
+void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir)
 {
        if (ir->sampling) {
                cx_write(MO_DDSCFG_IO, 0x0);
-               core->pci_irqmask &= ~(1 << 18);
+               core->pci_irqmask &= ~PCI_INT_IR_SMPINT;
        }
 
        if (ir->polling) {
@@ -204,7 +203,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
        ir->input = input_dev;
 
        /* detect & configure */
-       switch (core->board) {
+       switch (core->boardnr) {
        case CX88_BOARD_DNTV_LIVE_DVB_T:
        case CX88_BOARD_KWORLD_DVB_T:
        case CX88_BOARD_KWORLD_DVB_T_CX22702:
@@ -314,8 +313,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
        }
 
        /* init input device */
-       snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)",
-                cx88_boards[core->board].name);
+       snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
        snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
 
        ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
@@ -406,7 +404,7 @@ void cx88_ir_irq(struct cx88_core *core)
                ir_dump_samples(ir->samples, ir->scount);
 
        /* decode it */
-       switch (core->board) {
+       switch (core->boardnr) {
        case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
        case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
                ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
index da7a6b591a674e02187533e1b74f8fa52ba94e18..a652f294d23d8dd8e6a135eab458395ddb8928f6 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
 #include <asm/delay.h>
 
 #include "cx88.h"
@@ -56,9 +54,9 @@ static void request_module_async(struct work_struct *work)
 {
        struct cx8802_dev *dev=container_of(work, struct cx8802_dev, request_module_wk);
 
-       if (cx88_boards[dev->core->board].mpeg & CX88_MPEG_DVB)
+       if (dev->core->board.mpeg & CX88_MPEG_DVB)
                request_module("cx88-dvb");
-       if (cx88_boards[dev->core->board].mpeg & CX88_MPEG_BLACKBIRD)
+       if (dev->core->board.mpeg & CX88_MPEG_BLACKBIRD)
                request_module("cx88-blackbird");
 }
 
@@ -96,7 +94,7 @@ static int cx8802_start_dma(struct cx8802_dev    *dev,
        dprintk( 1, "core->active_type_id = 0x%08x\n", core->active_type_id);
 
        if ( (core->active_type_id == CX88_MPEG_DVB) &&
-               (cx88_boards[core->board].mpeg & CX88_MPEG_DVB) ) {
+               (core->board.mpeg & CX88_MPEG_DVB) ) {
 
                dprintk( 1, "cx8802_start_dma doing .dvb\n");
                /* negedge driven & software reset */
@@ -104,7 +102,7 @@ static int cx8802_start_dma(struct cx8802_dev    *dev,
                udelay(100);
                cx_write(MO_PINMUX_IO, 0x00);
                cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01);
-               switch (core->board) {
+               switch (core->boardnr) {
                case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
                case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
                case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
@@ -125,7 +123,7 @@ static int cx8802_start_dma(struct cx8802_dev    *dev,
                cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
                udelay(100);
        } else if ( (core->active_type_id == CX88_MPEG_BLACKBIRD) &&
-               (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) ) {
+               (core->board.mpeg & CX88_MPEG_BLACKBIRD) ) {
                dprintk( 1, "cx8802_start_dma doing .blackbird\n");
                cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
 
@@ -139,7 +137,7 @@ static int cx8802_start_dma(struct cx8802_dev    *dev,
                udelay(100);
        } else {
                printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __FUNCTION__,
-                       cx88_boards[core->board].mpeg );
+                       core->board.mpeg );
                return -EINVAL;
        }
 
@@ -149,7 +147,7 @@ static int cx8802_start_dma(struct cx8802_dev    *dev,
 
        /* enable irqs */
        dprintk( 1, "setting the interrupt mask\n" );
-       cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
+       cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_TSINT);
        cx_set(MO_TS_INTMSK,  0x1f0011);
 
        /* start dma */
@@ -167,7 +165,7 @@ static int cx8802_stop_dma(struct cx8802_dev *dev)
        cx_clear(MO_TS_DMACNTRL, 0x11);
 
        /* disable irqs */
-       cx_clear(MO_PCI_INTMSK, 0x000004);
+       cx_clear(MO_PCI_INTMSK, PCI_INT_TSINT);
        cx_clear(MO_TS_INTMSK, 0x1f0011);
 
        /* Reset the controller */
@@ -181,43 +179,43 @@ static int cx8802_restart_queue(struct cx8802_dev    *dev,
        struct cx88_buffer *buf;
        struct list_head *item;
 
-       dprintk( 1, "cx8802_restart_queue\n" );
+       dprintk( 1, "cx8802_restart_queue\n" );
        if (list_empty(&q->active))
        {
-              struct cx88_buffer *prev;
-              prev = NULL;
-
-              dprintk(1, "cx8802_restart_queue: queue is empty\n" );
-
-              for (;;) {
-                      if (list_empty(&q->queued))
-                              return 0;
-                      buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
-                      if (NULL == prev) {
-                              list_del(&buf->vb.queue);
-                              list_add_tail(&buf->vb.queue,&q->active);
-                              cx8802_start_dma(dev, q, buf);
-                              buf->vb.state = STATE_ACTIVE;
-                              buf->count    = q->count++;
-                              mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
-                              dprintk(1,"[%p/%d] restart_queue - first active\n",
-                                      buf,buf->vb.i);
-
-                      } else if (prev->vb.width  == buf->vb.width  &&
-                                 prev->vb.height == buf->vb.height &&
-                                 prev->fmt       == buf->fmt) {
-                              list_del(&buf->vb.queue);
-                              list_add_tail(&buf->vb.queue,&q->active);
-                              buf->vb.state = STATE_ACTIVE;
-                              buf->count    = q->count++;
-                              prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-                              dprintk(1,"[%p/%d] restart_queue - move to active\n",
-                                      buf,buf->vb.i);
-                      } else {
-                              return 0;
-                      }
-                      prev = buf;
-              }
+               struct cx88_buffer *prev;
+               prev = NULL;
+
+               dprintk(1, "cx8802_restart_queue: queue is empty\n" );
+
+               for (;;) {
+                       if (list_empty(&q->queued))
+                               return 0;
+                       buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
+                       if (NULL == prev) {
+                               list_del(&buf->vb.queue);
+                               list_add_tail(&buf->vb.queue,&q->active);
+                               cx8802_start_dma(dev, q, buf);
+                               buf->vb.state = STATE_ACTIVE;
+                               buf->count    = q->count++;
+                               mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
+                               dprintk(1,"[%p/%d] restart_queue - first active\n",
+                                       buf,buf->vb.i);
+
+                       } else if (prev->vb.width  == buf->vb.width  &&
+                                  prev->vb.height == buf->vb.height &&
+                                  prev->fmt       == buf->fmt) {
+                               list_del(&buf->vb.queue);
+                               list_add_tail(&buf->vb.queue,&q->active);
+                               buf->vb.state = STATE_ACTIVE;
+                               buf->count    = q->count++;
+                               prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+                               dprintk(1,"[%p/%d] restart_queue - move to active\n",
+                                       buf,buf->vb.i);
+                       } else {
+                               return 0;
+                       }
+                       prev = buf;
+               }
                return 0;
        }
 
@@ -239,6 +237,7 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
                        struct cx88_buffer *buf, enum v4l2_field field)
 {
        int size = dev->ts_packet_size * dev->ts_packet_count;
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
        int rc;
 
        dprintk(1, "%s: %p\n", __FUNCTION__, buf);
@@ -254,8 +253,8 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
                if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
                        goto fail;
                cx88_risc_databuffer(dev->pci, &buf->risc,
-                                    buf->vb.dma.sglist,
-                                    buf->vb.width, buf->vb.height);
+                                    dma->sglist,
+                                    buf->vb.width, buf->vb.height, 0);
        }
        buf->vb.state = STATE_PREPARED;
        return 0;
@@ -414,7 +413,8 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id)
        int loop, handled = 0;
 
        for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
-               status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04);
+               status = cx_read(MO_PCI_INTSTAT) &
+                       (core->pci_irqmask | PCI_INT_TSINT);
                if (0 == status)
                        goto out;
                dprintk( 1, "cx8802_irq\n" );
@@ -425,7 +425,7 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id)
 
                if (status & core->pci_irqmask)
                        cx88_core_irq(core,status);
-               if (status & 0x04)
+               if (status & PCI_INT_TSINT)
                        cx8802_mpeg_irq(dev);
        };
        if (MAX_IRQ_LOOP == loop) {
@@ -676,22 +676,24 @@ int cx8802_register_driver(struct cx8802_driver *drv)
        struct list_head *list;
        int err = 0, i = 0;
 
-       printk(KERN_INFO "%s() ->registering driver type=%s access=%s\n", __FUNCTION__ ,
-               drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
-               drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
+       printk(KERN_INFO
+              "cx88/2: registering cx8802 driver, type: %s access: %s\n",
+              drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
+              drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
 
        if ((err = cx8802_check_driver(drv)) != 0) {
-               printk(KERN_INFO "%s() cx8802_driver is invalid\n", __FUNCTION__ );
+               printk(KERN_ERR "cx88/2: cx8802_driver is invalid\n");
                return err;
        }
 
        list_for_each(list,&cx8802_devlist) {
                h = list_entry(list, struct cx8802_dev, devlist);
 
-               printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n",
-                       h->core->name,h->pci->subsystem_vendor,
-                       h->pci->subsystem_device,cx88_boards[h->core->board].name,
-                       h->core->board);
+               printk(KERN_INFO
+                      "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
+                      h->core->name, h->pci->subsystem_vendor,
+                      h->pci->subsystem_device, h->core->board.name,
+                      h->core->boardnr);
 
                /* Bring up a new struct for each driver instance */
                driver = kzalloc(sizeof(*drv),GFP_KERNEL);
@@ -713,7 +715,9 @@ int cx8802_register_driver(struct cx8802_driver *drv)
                        list_add_tail(&driver->devlist,&h->drvlist.devlist);
                        mutex_unlock(&drv->core->lock);
                } else {
-                       printk(KERN_ERR "%s() ->probe failed err = %d\n", __FUNCTION__, err);
+                       printk(KERN_ERR
+                              "%s/2: cx8802 probe failed, err = %d\n",
+                              h->core->name, err);
                }
 
        }
@@ -733,17 +737,20 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
        struct list_head *list2, *q;
        int err = 0, i = 0;
 
-       printk(KERN_INFO "%s() ->unregistering driver type=%s\n", __FUNCTION__ ,
-               drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird");
+       printk(KERN_INFO
+              "cx88/2: unregistering cx8802 driver, type: %s access: %s\n",
+              drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
+              drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
 
        list_for_each(list,&cx8802_devlist) {
                i++;
                h = list_entry(list, struct cx8802_dev, devlist);
 
-               printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n",
-                       h->core->name,h->pci->subsystem_vendor,
-                       h->pci->subsystem_device,cx88_boards[h->core->board].name,
-                       h->core->board);
+               printk(KERN_INFO
+                      "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
+                      h->core->name, h->pci->subsystem_vendor,
+                      h->pci->subsystem_device, h->core->board.name,
+                      h->core->boardnr);
 
                list_for_each_safe(list2, q, &h->drvlist.devlist) {
                        d = list_entry(list2, struct cx8802_driver, devlist);
@@ -758,7 +765,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
                                list_del(list2);
                                mutex_unlock(&drv->core->lock);
                        } else
-                               printk(KERN_ERR "%s() ->remove failed err = %d\n", __FUNCTION__, err);
+                               printk(KERN_ERR "%s/2: cx8802 driver remove "
+                                      "failed (%d)\n", h->core->name, err);
 
                }
 
@@ -783,7 +791,7 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
        printk("%s/2: cx2388x 8802 Driver Manager\n", core->name);
 
        err = -ENODEV;
-       if (!cx88_boards[core->board].mpeg)
+       if (!core->board.mpeg)
                goto fail_core;
 
        err = -ENOMEM;
@@ -866,7 +874,7 @@ static struct pci_driver cx8802_pci_driver = {
 
 static int cx8802_init(void)
 {
-       printk(KERN_INFO "cx2388x cx88-mpeg Driver Manager version %d.%d.%d loaded\n",
+       printk(KERN_INFO "cx88/2: cx2388x MPEG-TS Driver Manager version %d.%d.%d loaded\n",
               (CX88_VERSION_CODE >> 16) & 0xff,
               (CX88_VERSION_CODE >>  8) & 0xff,
               CX88_VERSION_CODE & 0xff);
index d3bf5b17b1d40dde2a2b1f2d28b4c80bfbfd7966..2ec52d1cdea0306097b8edceaacb0053794f3916 100644 (file)
 /* ---------------------------------------------------------------------- */
 /* various constants                                                      */
 
+// DMA
+/* Interrupt mask/status */
+#define PCI_INT_VIDINT         (1 <<  0)
+#define PCI_INT_AUDINT         (1 <<  1)
+#define PCI_INT_TSINT          (1 <<  2)
+#define PCI_INT_VIPINT         (1 <<  3)
+#define PCI_INT_HSTINT         (1 <<  4)
+#define PCI_INT_TM1INT         (1 <<  5)
+#define PCI_INT_SRCDMAINT      (1 <<  6)
+#define PCI_INT_DSTDMAINT      (1 <<  7)
+#define PCI_INT_RISC_RD_BERRINT        (1 << 10)
+#define PCI_INT_RISC_WR_BERRINT        (1 << 11)
+#define PCI_INT_BRDG_BERRINT   (1 << 12)
+#define PCI_INT_SRC_DMA_BERRINT        (1 << 13)
+#define PCI_INT_DST_DMA_BERRINT        (1 << 14)
+#define PCI_INT_IPB_DMA_BERRINT        (1 << 15)
+#define PCI_INT_I2CDONE                (1 << 16)
+#define PCI_INT_I2CRACK                (1 << 17)
+#define PCI_INT_IR_SMPINT      (1 << 18)
+#define PCI_INT_GPIO_INT0      (1 << 19)
+#define PCI_INT_GPIO_INT1      (1 << 20)
+
 #define SEL_BTSC     0x01
 #define SEL_EIAJ     0x02
 #define SEL_A2       0x04
 #define SEL_FMRADIO  0x20
 
 // AUD_CTL
+#define AUD_INT_DN_RISCI1      (1 <<  0)
+#define AUD_INT_UP_RISCI1      (1 <<  1)
+#define AUD_INT_RDS_DN_RISCI1  (1 <<  2)
+#define AUD_INT_DN_RISCI2      (1 <<  4) /* yes, 3 is skipped */
+#define AUD_INT_UP_RISCI2      (1 <<  5)
+#define AUD_INT_RDS_DN_RISCI2  (1 <<  6)
+#define AUD_INT_DN_SYNC                (1 << 12)
+#define AUD_INT_UP_SYNC                (1 << 13)
+#define AUD_INT_RDS_DN_SYNC    (1 << 14)
+#define AUD_INT_OPC_ERR                (1 << 16)
+#define AUD_INT_BER_IRQ                (1 << 20)
+#define AUD_INT_MCHG_IRQ       (1 << 21)
+
 #define EN_BTSC_FORCE_MONO      0
 #define EN_BTSC_FORCE_STEREO    1
 #define EN_BTSC_FORCE_SAP       2
index 1cc2d286a1cbe2e04ef7dfdc701b63cc2cb33e58..76e5c78d8ae44c8698af8611db3fabdf30830fd6 100644 (file)
@@ -36,7 +36,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/errno.h>
 #include <linux/freezer.h>
 #include <linux/kernel.h>
@@ -62,6 +61,10 @@ static unsigned int always_analog = 0;
 module_param(always_analog,int,0644);
 MODULE_PARM_DESC(always_analog,"force analog audio out");
 
+static unsigned int radio_deemphasis = 0;
+module_param(radio_deemphasis,int,0644);
+MODULE_PARM_DESC(radio_deemphasis, "Radio deemphasis time constant, "
+                "0=None, 1=50us (elsewhere), 2=75us (USA)");
 
 #define dprintk(fmt, arg...)   if (audio_debug) \
        printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
@@ -140,7 +143,7 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
        cx_write(AUD_RATE_THRES_DMD, 0x000000C0);
        cx88_start_audio_dma(core);
 
-       if (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) {
+       if (core->board.mpeg & CX88_MPEG_BLACKBIRD) {
                cx_write(AUD_I2SINPUTCNTL, 4);
                cx_write(AUD_BAUDRATE, 1);
                /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */
@@ -149,7 +152,7 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
                cx_write(AUD_I2SCNTL, 0);
                /* cx_write(AUD_APB_IN_RATE_ADJ, 0); */
        }
-       if ((always_analog) || (!(cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD))) {
+       if ((always_analog) || (!(core->board.mpeg & CX88_MPEG_BLACKBIRD))) {
                ctl |= EN_DAC_ENABLE;
                cx_write(AUD_CTL, ctl);
        }
@@ -678,6 +681,10 @@ static void set_audio_standard_FM(struct cx88_core *core,
        };
 
        /* It is enough to leave default values? */
+       /* No, it's not!  The deemphasis registers are reset to the 75us
+        * values by default.  Analyzing the spectrum of the decoded audio
+        * reveals that "no deemphasis" is the same as 75 us, while the 50 us
+        * setting results in less deemphasis.  */
        static const struct rlist fm_no_deemph[] = {
 
                {AUD_POLYPH80SCALEFAC, 0x0003},
@@ -688,6 +695,7 @@ static void set_audio_standard_FM(struct cx88_core *core,
        set_audio_start(core, SEL_FMRADIO);
 
        switch (deemph) {
+       default:
        case FM_NO_DEEMPH:
                set_audio_registers(core, fm_no_deemph);
                break;
@@ -757,7 +765,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
                set_audio_standard_EIAJ(core);
                break;
        case WW_FM:
-               set_audio_standard_FM(core, FM_NO_DEEMPH);
+               set_audio_standard_FM(core, radio_deemphasis);
                break;
        case WW_NONE:
        default:
@@ -790,9 +798,9 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
        core->astat = reg;
 
 /* TODO
-       Reading from AUD_STATUS is not enough
-       for auto-detecting sap/dual-fm/nicam.
-       Add some code here later.
+       Reading from AUD_STATUS is not enough
+       for auto-detecting sap/dual-fm/nicam.
+       Add some code here later.
 */
 
        return;
index 86c1cf8334bc144a41c49ed81ea1f8d4fe215ceb..babb085564067715548bd580bc510a0a6670c939 100644 (file)
@@ -2,7 +2,6 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 
@@ -67,7 +66,7 @@ static int cx8800_start_vbi_dma(struct cx8800_dev    *dev,
        q->count = 1;
 
        /* enable irqs */
-       cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01);
+       cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_VIDINT);
        cx_set(MO_VID_INTMSK, 0x0f0088);
 
        /* enable capture */
@@ -91,7 +90,7 @@ int cx8800_stop_vbi_dma(struct cx8800_dev *dev)
        cx_clear(VID_CAPTURE_CONTROL,0x18);
 
        /* disable irqs */
-       cx_clear(MO_PCI_INTMSK, 0x000001);
+       cx_clear(MO_PCI_INTMSK, PCI_INT_VIDINT);
        cx_clear(MO_VID_INTMSK, 0x0f0088);
        return 0;
 }
@@ -100,7 +99,6 @@ int cx8800_restart_vbi_queue(struct cx8800_dev    *dev,
                             struct cx88_dmaqueue *q)
 {
        struct cx88_buffer *buf;
-       struct list_head *item;
 
        if (list_empty(&q->active))
                return 0;
@@ -109,10 +107,8 @@ int cx8800_restart_vbi_queue(struct cx8800_dev    *dev,
        dprintk(2,"restart_queue [%p/%d]: restart dma\n",
                buf, buf->vb.i);
        cx8800_start_vbi_dma(dev, q, buf);
-       list_for_each(item,&q->active) {
-               buf = list_entry(item, struct cx88_buffer, vb.queue);
+       list_for_each_entry(buf, &q->active, vb.queue)
                buf->count = q->count++;
-       }
        mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
        return 0;
 }
@@ -173,6 +169,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
                return -EINVAL;
 
        if (STATE_NEEDS_INIT == buf->vb.state) {
+               struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
                buf->vb.width  = VBI_LINE_LENGTH;
                buf->vb.height = VBI_LINE_COUNT;
                buf->vb.size   = size;
@@ -181,7 +178,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
                if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
                        goto fail;
                cx88_risc_buffer(dev->pci, &buf->risc,
-                                buf->vb.dma.sglist,
+                                dma->sglist,
                                 0, buf->vb.width * buf->vb.height,
                                 buf->vb.width, 0,
                                 buf->vb.height);
index 06b233a7b20bfc3dce4860f6c6d9392ac8759ca0..231ae6c4dd229f5327dffba44f5379db71b2c77e 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kmod.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -36,7 +35,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
-#include <linux/dma-mapping.h>
 #include <asm/div64.h>
 
 #include "cx88.h"
@@ -369,17 +367,17 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
        /* struct cx88_core *core = dev->core; */
 
        dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n",
-               input, INPUT(input)->vmux,
-               INPUT(input)->gpio0,INPUT(input)->gpio1,
-               INPUT(input)->gpio2,INPUT(input)->gpio3);
+               input, INPUT(input).vmux,
+               INPUT(input).gpio0,INPUT(input).gpio1,
+               INPUT(input).gpio2,INPUT(input).gpio3);
        core->input = input;
-       cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input)->vmux << 14);
-       cx_write(MO_GP3_IO, INPUT(input)->gpio3);
-       cx_write(MO_GP0_IO, INPUT(input)->gpio0);
-       cx_write(MO_GP1_IO, INPUT(input)->gpio1);
-       cx_write(MO_GP2_IO, INPUT(input)->gpio2);
+       cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input).vmux << 14);
+       cx_write(MO_GP3_IO, INPUT(input).gpio3);
+       cx_write(MO_GP0_IO, INPUT(input).gpio0);
+       cx_write(MO_GP1_IO, INPUT(input).gpio1);
+       cx_write(MO_GP2_IO, INPUT(input).gpio2);
 
-       switch (INPUT(input)->type) {
+       switch (INPUT(input).type) {
        case CX88_VMUX_SVIDEO:
                cx_set(MO_AFECFG_IO,    0x00000001);
                cx_set(MO_INPUT_FORMAT, 0x00010010);
@@ -394,9 +392,9 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
                break;
        }
 
-       if (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) {
+       if (core->board.mpeg & CX88_MPEG_BLACKBIRD) {
                /* sets sound input from external adc */
-               if (INPUT(input)->extadc)
+               if (INPUT(input).extadc)
                        cx_set(AUD_CTL, EN_I2SIN_ENABLE);
                else
                        cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
@@ -424,7 +422,7 @@ static int start_video_dma(struct cx8800_dev    *dev,
        q->count = 1;
 
        /* enable irqs */
-       cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01);
+       cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_VIDINT);
 
        /* Enables corresponding bits at PCI_INT_STAT:
                bits 0 to 4: video, audio, transport stream, VIP, Host
@@ -457,7 +455,7 @@ static int stop_video_dma(struct cx8800_dev    *dev)
        cx_clear(VID_CAPTURE_CONTROL,0x06);
 
        /* disable irqs */
-       cx_clear(MO_PCI_INTMSK, 0x000001);
+       cx_clear(MO_PCI_INTMSK, PCI_INT_VIDINT);
        cx_clear(MO_VID_INTMSK, 0x0f0011);
        return 0;
 }
@@ -468,17 +466,14 @@ static int restart_video_queue(struct cx8800_dev    *dev,
 {
        struct cx88_core *core = dev->core;
        struct cx88_buffer *buf, *prev;
-       struct list_head *item;
 
        if (!list_empty(&q->active)) {
                buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
                dprintk(2,"restart_queue [%p/%d]: restart dma\n",
                        buf, buf->vb.i);
                start_video_dma(dev, q, buf);
-               list_for_each(item,&q->active) {
-                       buf = list_entry(item, struct cx88_buffer, vb.queue);
-                       buf->count    = q->count++;
-               }
+               list_for_each_entry(buf, &q->active, vb.queue)
+                       buf->count = q->count++;
                mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
                return 0;
        }
@@ -536,6 +531,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
        struct cx8800_dev  *dev = fh->dev;
        struct cx88_core *core = dev->core;
        struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
        int rc, init_buffer = 0;
 
        BUG_ON(NULL == fh->fmt);
@@ -568,30 +564,30 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
                switch (buf->vb.field) {
                case V4L2_FIELD_TOP:
                        cx88_risc_buffer(dev->pci, &buf->risc,
-                                        buf->vb.dma.sglist, 0, UNSET,
+                                        dma->sglist, 0, UNSET,
                                         buf->bpl, 0, buf->vb.height);
                        break;
                case V4L2_FIELD_BOTTOM:
                        cx88_risc_buffer(dev->pci, &buf->risc,
-                                        buf->vb.dma.sglist, UNSET, 0,
+                                        dma->sglist, UNSET, 0,
                                         buf->bpl, 0, buf->vb.height);
                        break;
                case V4L2_FIELD_INTERLACED:
                        cx88_risc_buffer(dev->pci, &buf->risc,
-                                        buf->vb.dma.sglist, 0, buf->bpl,
+                                        dma->sglist, 0, buf->bpl,
                                         buf->bpl, buf->bpl,
                                         buf->vb.height >> 1);
                        break;
                case V4L2_FIELD_SEQ_TB:
                        cx88_risc_buffer(dev->pci, &buf->risc,
-                                        buf->vb.dma.sglist,
+                                        dma->sglist,
                                         0, buf->bpl * (buf->vb.height >> 1),
                                         buf->bpl, 0,
                                         buf->vb.height >> 1);
                        break;
                case V4L2_FIELD_SEQ_BT:
                        cx88_risc_buffer(dev->pci, &buf->risc,
-                                        buf->vb.dma.sglist,
+                                        dma->sglist,
                                         buf->bpl * (buf->vb.height >> 1), 0,
                                         buf->bpl, 0,
                                         buf->vb.height >> 1);
@@ -714,12 +710,10 @@ static int video_open(struct inode *inode, struct file *file)
        struct cx8800_dev *h,*dev = NULL;
        struct cx88_core *core;
        struct cx8800_fh *fh;
-       struct list_head *list;
        enum v4l2_buf_type type = 0;
        int radio = 0;
 
-       list_for_each(list,&cx8800_devlist) {
-               h = list_entry(list, struct cx8800_dev, devlist);
+       list_for_each_entry(h, &cx8800_devlist, devlist) {
                if (h->video_dev->minor == minor) {
                        dev  = h;
                        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -754,13 +748,13 @@ static int video_open(struct inode *inode, struct file *file)
        fh->height   = 240;
        fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);
 
-       videobuf_queue_init(&fh->vidq, &cx8800_video_qops,
+       videobuf_queue_pci_init(&fh->vidq, &cx8800_video_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_INTERLACED,
                            sizeof(struct cx88_buffer),
                            fh);
-       videobuf_queue_init(&fh->vbiq, &cx8800_vbi_qops,
+       videobuf_queue_pci_init(&fh->vbiq, &cx8800_vbi_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VBI_CAPTURE,
                            V4L2_FIELD_SEQ_TB,
@@ -768,12 +762,11 @@ static int video_open(struct inode *inode, struct file *file)
                            fh);
 
        if (fh->radio) {
-               int board = core->board;
                dprintk(1,"video_open: setting radio device\n");
-               cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3);
-               cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0);
-               cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1);
-               cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2);
+               cx_write(MO_GP3_IO, core->board.radio.gpio3);
+               cx_write(MO_GP0_IO, core->board.radio.gpio0);
+               cx_write(MO_GP1_IO, core->board.radio.gpio1);
+               cx_write(MO_GP2_IO, core->board.radio.gpio2);
                core->tvaudio = WW_FM;
                cx88_set_tvaudio(core);
                cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
@@ -1079,8 +1072,7 @@ static int vidioc_querycap (struct file *file, void  *priv,
        struct cx88_core  *core = dev->core;
 
        strcpy(cap->driver, "cx8800");
-       strlcpy(cap->card, cx88_boards[core->board].name,
-               sizeof(cap->card));
+       strlcpy(cap->card, core->board.name, sizeof(cap->card));
        sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
        cap->version = CX88_VERSION_CODE;
        cap->capabilities =
@@ -1088,7 +1080,7 @@ static int vidioc_querycap (struct file *file, void  *priv,
                V4L2_CAP_READWRITE     |
                V4L2_CAP_STREAMING     |
                V4L2_CAP_VBI_CAPTURE;
-       if (UNSET != core->tuner_type)
+       if (UNSET != core->board.tuner_type)
                cap->capabilities |= V4L2_CAP_TUNER;
        return 0;
 }
@@ -1108,28 +1100,9 @@ static int vidioc_enum_fmt_cap (struct file *file, void  *priv,
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf)
 {
-       struct cx8800_fh           *fh   = priv;
-       struct videobuf_queue      *q;
-       struct v4l2_requestbuffers req;
-       unsigned int i;
-       int err;
+       struct cx8800_fh           *fh  = priv;
 
-       q = get_queue(fh);
-       memset(&req,0,sizeof(req));
-       req.type   = q->type;
-       req.count  = 8;
-       req.memory = V4L2_MEMORY_MMAP;
-       err = videobuf_reqbufs(q,&req);
-       if (err < 0)
-               return err;
-
-       mbuf->frames = req.count;
-       mbuf->size   = 0;
-       for (i = 0; i < mbuf->frames; i++) {
-               mbuf->offsets[i]  = q->bufs[i]->boff;
-               mbuf->size       += q->bufs[i]->bsize;
-       }
-       return 0;
+       return videobuf_cgmbuf (get_queue(fh), mbuf, 8);
 }
 #endif
 
@@ -1222,14 +1195,14 @@ int cx88_enum_input (struct cx88_core  *core,struct v4l2_input *i)
        n = i->index;
        if (n >= 4)
                return -EINVAL;
-       if (0 == INPUT(n)->type)
+       if (0 == INPUT(n).type)
                return -EINVAL;
        memset(i,0,sizeof(*i));
        i->index = n;
        i->type  = V4L2_INPUT_TYPE_CAMERA;
-       strcpy(i->name,iname[INPUT(n)->type]);
-       if ((CX88_VMUX_TELEVISION == INPUT(n)->type) ||
-               (CX88_VMUX_CABLE      == INPUT(n)->type))
+       strcpy(i->name,iname[INPUT(n).type]);
+       if ((CX88_VMUX_TELEVISION == INPUT(n).type) ||
+           (CX88_VMUX_CABLE      == INPUT(n).type))
                i->type = V4L2_INPUT_TYPE_TUNER;
                i->std = CX88_NORMS;
        return 0;
@@ -1298,7 +1271,7 @@ static int vidioc_g_tuner (struct file *file, void *priv,
        struct cx88_core  *core = ((struct cx8800_fh *)priv)->dev->core;
        u32 reg;
 
-       if (unlikely(UNSET == core->tuner_type))
+       if (unlikely(UNSET == core->board.tuner_type))
                return -EINVAL;
        if (0 != t->index)
                return -EINVAL;
@@ -1319,7 +1292,7 @@ static int vidioc_s_tuner (struct file *file, void *priv,
 {
        struct cx88_core  *core = ((struct cx8800_fh *)priv)->dev->core;
 
-       if (UNSET == core->tuner_type)
+       if (UNSET == core->board.tuner_type)
                return -EINVAL;
        if (0 != t->index)
                return -EINVAL;
@@ -1334,7 +1307,7 @@ static int vidioc_g_frequency (struct file *file, void *priv,
        struct cx8800_fh  *fh   = priv;
        struct cx88_core  *core = fh->dev->core;
 
-       if (unlikely(UNSET == core->tuner_type))
+       if (unlikely(UNSET == core->board.tuner_type))
                return -EINVAL;
 
        /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */
@@ -1349,7 +1322,7 @@ static int vidioc_g_frequency (struct file *file, void *priv,
 int cx88_set_freq (struct cx88_core  *core,
                                struct v4l2_frequency *f)
 {
-       if (unlikely(UNSET == core->tuner_type))
+       if (unlikely(UNSET == core->board.tuner_type))
                return -EINVAL;
        if (unlikely(f->tuner != 0))
                return -EINVAL;
@@ -1420,8 +1393,7 @@ static int radio_querycap (struct file *file, void  *priv,
        struct cx88_core  *core = dev->core;
 
        strcpy(cap->driver, "cx8800");
-       strlcpy(cap->card, cx88_boards[core->board].name,
-               sizeof(cap->card));
+       strlcpy(cap->card, core->board.name, sizeof(cap->card));
        sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
        cap->version = CX88_VERSION_CODE;
        cap->capabilities = V4L2_CAP_TUNER;
@@ -1608,7 +1580,8 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id)
        int loop, handled = 0;
 
        for (loop = 0; loop < 10; loop++) {
-               status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x01);
+               status = cx_read(MO_PCI_INTSTAT) &
+                       (core->pci_irqmask | PCI_INT_VIDINT);
                if (0 == status)
                        goto out;
                cx_write(MO_PCI_INTSTAT, status);
@@ -1616,7 +1589,7 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id)
 
                if (status & core->pci_irqmask)
                        cx88_core_irq(core,status);
-               if (status & 0x01)
+               if (status & PCI_INT_VIDINT)
                        cx8800_vid_irq(dev);
        };
        if (10 == loop) {
@@ -1717,6 +1690,10 @@ static struct video_device cx8800_radio_template =
        .vidioc_s_ctrl        = vidioc_s_ctrl,
        .vidioc_g_frequency   = vidioc_g_frequency,
        .vidioc_s_frequency   = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .vidioc_g_register    = vidioc_g_register,
+       .vidioc_s_register    = vidioc_s_register,
+#endif
 };
 
 /* ----------------------------------------------------------- */
@@ -1818,26 +1795,32 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
        err = request_irq(pci_dev->irq, cx8800_irq,
                          IRQF_SHARED | IRQF_DISABLED, core->name, dev);
        if (err < 0) {
-               printk(KERN_ERR "%s: can't get IRQ %d\n",
+               printk(KERN_ERR "%s/0: can't get IRQ %d\n",
                       core->name,pci_dev->irq);
                goto fail_core;
        }
        cx_set(MO_PCI_INTMSK, core->pci_irqmask);
 
        /* load and configure helper modules */
-       if (TUNER_ABSENT != core->tuner_type)
+       if (TUNER_ABSENT != core->board.tuner_type)
                request_module("tuner");
 
-       if (cx88_boards[ core->board ].audio_chip == AUDIO_CHIP_WM8775)
+       if (core->board.audio_chip == AUDIO_CHIP_WM8775)
                request_module("wm8775");
 
+       switch (core->boardnr) {
+       case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
+               request_module("ir-kbd-i2c");
+               request_module("rtc-isl1208");
+       }
+
        /* register v4l devices */
        dev->video_dev = cx88_vdev_init(core,dev->pci,
                                        &cx8800_video_template,"video");
        err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER,
                                    video_nr[core->nr]);
        if (err < 0) {
-               printk(KERN_INFO "%s: can't register video device\n",
+               printk(KERN_ERR "%s/0: can't register video device\n",
                       core->name);
                goto fail_unreg;
        }
@@ -1848,20 +1831,20 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
        err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI,
                                    vbi_nr[core->nr]);
        if (err < 0) {
-               printk(KERN_INFO "%s/0: can't register vbi device\n",
+               printk(KERN_ERR "%s/0: can't register vbi device\n",
                       core->name);
                goto fail_unreg;
        }
        printk(KERN_INFO "%s/0: registered device vbi%d\n",
               core->name,dev->vbi_dev->minor & 0x1f);
 
-       if (core->has_radio) {
+       if (core->board.radio.type == CX88_RADIO) {
                dev->radio_dev = cx88_vdev_init(core,dev->pci,
                                                &cx8800_radio_template,"radio");
                err = video_register_device(dev->radio_dev,VFL_TYPE_RADIO,
                                            radio_nr[core->nr]);
                if (err < 0) {
-                       printk(KERN_INFO "%s/0: can't register radio device\n",
+                       printk(KERN_ERR "%s/0: can't register radio device\n",
                               core->name);
                        goto fail_unreg;
                }
@@ -1881,12 +1864,12 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
        mutex_unlock(&core->lock);
 
        /* start tvaudio thread */
-       if (core->tuner_type != TUNER_ABSENT) {
+       if (core->board.tuner_type != TUNER_ABSENT) {
                core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio");
                if (IS_ERR(core->kthread)) {
                        err = PTR_ERR(core->kthread);
-                       printk(KERN_ERR "Failed to create cx88 audio thread, err=%d\n",
-                              err);
+                       printk(KERN_ERR "%s/0: failed to create cx88 audio thread, err=%d\n",
+                              core->name, err);
                }
        }
        return 0;
@@ -1937,17 +1920,19 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
        /* stop video+vbi capture */
        spin_lock(&dev->slock);
        if (!list_empty(&dev->vidq.active)) {
-               printk("%s: suspend video\n", core->name);
+               printk("%s/0: suspend video\n", core->name);
                stop_video_dma(dev);
                del_timer(&dev->vidq.timeout);
        }
        if (!list_empty(&dev->vbiq.active)) {
-               printk("%s: suspend vbi\n", core->name);
+               printk("%s/0: suspend vbi\n", core->name);
                cx8800_stop_vbi_dma(dev);
                del_timer(&dev->vbiq.timeout);
        }
        spin_unlock(&dev->slock);
 
+       if (core->ir)
+               cx88_ir_stop(core, core->ir);
        /* FIXME -- shutdown device */
        cx88_shutdown(core);
 
@@ -1968,8 +1953,8 @@ static int cx8800_resume(struct pci_dev *pci_dev)
        if (dev->state.disabled) {
                err=pci_enable_device(pci_dev);
                if (err) {
-                       printk(KERN_ERR "%s: can't enable device\n",
-                                                      core->name);
+                       printk(KERN_ERR "%s/0: can't enable device\n",
+                              core->name);
                        return err;
                }
 
@@ -1977,9 +1962,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)
        }
        err= pci_set_power_state(pci_dev, PCI_D0);
        if (err) {
-               printk(KERN_ERR "%s: can't enable device\n",
-                                      core->name);
-
+               printk(KERN_ERR "%s/0: can't set power state\n", core->name);
                pci_disable_device(pci_dev);
                dev->state.disabled = 1;
 
@@ -1989,15 +1972,19 @@ static int cx8800_resume(struct pci_dev *pci_dev)
 
        /* FIXME: re-initialize hardware */
        cx88_reset(core);
+       if (core->ir)
+               cx88_ir_start(core, core->ir);
+
+       cx_set(MO_PCI_INTMSK, core->pci_irqmask);
 
        /* restart video+vbi capture */
        spin_lock(&dev->slock);
        if (!list_empty(&dev->vidq.active)) {
-               printk("%s: resume video\n", core->name);
+               printk("%s/0: resume video\n", core->name);
                restart_video_queue(dev,&dev->vidq);
        }
        if (!list_empty(&dev->vbiq.active)) {
-               printk("%s: resume vbi\n", core->name);
+               printk("%s/0: resume vbi\n", core->name);
                cx8800_restart_vbi_queue(dev,&dev->vbiq);
        }
        spin_unlock(&dev->slock);
@@ -2033,7 +2020,7 @@ static struct pci_driver cx8800_pci_driver = {
 
 static int cx8800_init(void)
 {
-       printk(KERN_INFO "cx2388x v4l2 driver version %d.%d.%d loaded\n",
+       printk(KERN_INFO "cx88/0: cx2388x v4l2 driver version %d.%d.%d loaded\n",
               (CX88_VERSION_CODE >> 16) & 0xff,
               (CX88_VERSION_CODE >>  8) & 0xff,
               CX88_VERSION_CODE & 0xff);
index cd0877636a322faaedf9446e4deeffb9485681e8..77c37889232b3f4816dd2ffb4d1fc86c108cac3f 100644 (file)
@@ -23,7 +23,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 
 #include <asm/io.h>
@@ -111,7 +110,7 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
        struct vp3054_i2c_state *vp3054_i2c;
        int rc;
 
-       if (core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
+       if (core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
                return 0;
 
        dev->card_priv = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL);
@@ -152,7 +151,7 @@ void vp3054_i2c_remove(struct cx8802_dev *dev)
        struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
 
        if (vp3054_i2c == NULL ||
-           dev->core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
+           dev->core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
                return;
 
        i2c_del_adapter(&vp3054_i2c->adap);
index 809126866a3e7dedae36de969c3543b9e448e18f..42e0a9b8c55006f4770a3de97e41f86eb3d1a882 100644 (file)
 #include <media/v4l2-common.h>
 #include <media/tuner.h>
 #include <media/tveeprom.h>
-#include <media/video-buf.h>
+#include <media/videobuf-dma-sg.h>
 #include <media/cx2341x.h>
 #include <media/audiochip.h>
-#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
-#include <media/video-buf-dvb.h>
+#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
+#include <media/videobuf-dvb.h>
 #endif
 
 #include "btcx-risc.h"
@@ -226,8 +226,8 @@ enum cx88_itype {
 
 struct cx88_input {
        enum cx88_itype type;
-       unsigned int    vmux;
        u32             gpio0, gpio1, gpio2, gpio3;
+       unsigned int    vmux:2;
        unsigned int    extadc:1;
 };
 
@@ -250,7 +250,7 @@ struct cx88_subid {
        u32     card;
 };
 
-#define INPUT(nr) (&cx88_boards[core->board].input[nr])
+#define INPUT(nr) (core->board.input[nr])
 
 /* ----------------------------------------------------------- */
 /* device / file handle status                                 */
@@ -304,19 +304,14 @@ struct cx88_core {
        u32                        i2c_state, i2c_rc;
 
        /* config info -- analog */
-       unsigned int               board;
-       unsigned int               tuner_type;
-       unsigned int               radio_type;
-       unsigned char              tuner_addr;
-       unsigned char              radio_addr;
-       unsigned int               tda9887_conf;
-       unsigned int               has_radio;
+       unsigned int               boardnr;
+       struct cx88_board          board;
 
        /* Supported V4L _STD_ tuner formats */
        unsigned int               tuner_formats;
 
        /* config info -- dvb */
-#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
+#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
        int                        (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
 #endif
 
@@ -463,7 +458,7 @@ struct cx8802_dev {
        int                        width;
        int                        height;
 
-#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
+#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
        /* for dvb only */
        struct videobuf_dvb        dvb;
 
@@ -524,7 +519,7 @@ cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
 extern int
 cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
                     struct scatterlist *sglist, unsigned int bpl,
-                    unsigned int lines);
+                    unsigned int lines, unsigned int lpi);
 extern int
 cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
                  u32 reg, u32 mask, u32 value);
@@ -585,15 +580,9 @@ extern void cx88_call_i2c_clients(struct cx88_core *core,
 /* ----------------------------------------------------------- */
 /* cx88-cards.c                                                */
 
-extern struct cx88_board cx88_boards[];
-extern const unsigned int cx88_bcount;
-
-extern struct cx88_subid cx88_subids[];
-extern const unsigned int cx88_idcount;
-
-extern void cx88_card_list(struct cx88_core *core, struct pci_dev *pci);
-extern void cx88_card_setup(struct cx88_core *core);
-extern void cx88_card_setup_pre_i2c(struct cx88_core *core);
+extern int cx88_get_resources(const struct cx88_core *core,
+                             struct pci_dev *pci);
+extern struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr);
 
 /* ----------------------------------------------------------- */
 /* cx88-tvaudio.c                                              */
@@ -625,6 +614,8 @@ struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board
 int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci);
 int cx88_ir_fini(struct cx88_core *core);
 void cx88_ir_irq(struct cx88_core *core);
+void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir);
+void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir);
 
 /* ----------------------------------------------------------- */
 /* cx88-mpeg.c                                                 */
index 0fcc935828f8e8a23e4f90523e3a54abfc3727a9..255dae303708d3b98142f33e850e48a8b8f1209f 100644 (file)
@@ -92,7 +92,6 @@ static int dpc_probe(struct saa7146_dev* dev)
 {
        struct dpc* dpc = NULL;
        struct i2c_client *client;
-       struct list_head *item;
 
        dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL);
        if( NULL == dpc ) {
@@ -116,11 +115,9 @@ static int dpc_probe(struct saa7146_dev* dev)
        }
 
        /* loop through all i2c-devices on the bus and look who is there */
-       list_for_each(item,&dpc->i2c_adapter.clients) {
-               client = list_entry(item, struct i2c_client, list);
+       list_for_each_entry(client, &dpc->i2c_adapter.clients, list)
                if( I2C_SAA7111A == client->addr )
                        dpc->saa7111a = client;
-       }
 
        /* check if all devices are present */
        if( 0 == dpc->saa7111a ) {
index 255a47dfb84fcaa76346385ec8f22970a889acc1..d3282ec62c5be2e1382a2bc01dc5f4755bdd2a7e 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/usb.h>
 #include <linux/vmalloc.h>
 
index 55d45b0032cff0cda5a84844aaceeff096547d0f..e3894b68c4ee26b778aebe3945c9f3489e20c609 100644 (file)
@@ -22,7 +22,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index 40307f3f6fe31118be769ecf2103873c86ead2ec..b8d5327c438ded1e879216b485f7d1ac0ea2a82d 100644 (file)
@@ -252,10 +252,8 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
        int minor = iminor(inode);
        int errCode = 0;
        struct em28xx *h,*dev = NULL;
-       struct list_head *list;
 
-       list_for_each(list,&em28xx_devlist) {
-               h = list_entry(list, struct em28xx, devlist);
+       list_for_each_entry(h, &em28xx_devlist, devlist) {
                if (h->vdev->minor == minor) {
                        dev  = h;
                        dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -268,8 +266,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
        if (NULL == dev)
                return -ENODEV;
 
-       filp->private_data=dev;
-
        em28xx_videodbg("open minor=%d type=%s users=%d\n",
                                minor,v4l2_type_names[dev->type],dev->users);
 
index 585bd1fe0765540172114278baad8fd096416492..d5fef4c01c87a9ff0f100a34f9925670245a32eb 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/param.h>
-#include <linux/moduleparam.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/device.h>
@@ -707,7 +706,8 @@ static u8 et61x251_strtou8(const char* buff, size_t len, ssize_t* count)
    NOTE 2: buffers are PAGE_SIZE long
 */
 
-static ssize_t et61x251_show_reg(struct class_device* cd, char* buf)
+static ssize_t et61x251_show_reg(struct device* cd,
+                                struct device_attribute *attr, char* buf)
 {
        struct et61x251_device* cam;
        ssize_t count;
@@ -730,7 +730,8 @@ static ssize_t et61x251_show_reg(struct class_device* cd, char* buf)
 
 
 static ssize_t
-et61x251_store_reg(struct class_device* cd, const char* buf, size_t len)
+et61x251_store_reg(struct device* cd,
+                  struct device_attribute *attr, const char* buf, size_t len)
 {
        struct et61x251_device* cam;
        u8 index;
@@ -762,7 +763,8 @@ et61x251_store_reg(struct class_device* cd, const char* buf, size_t len)
 }
 
 
-static ssize_t et61x251_show_val(struct class_device* cd, char* buf)
+static ssize_t et61x251_show_val(struct device* cd,
+                                struct device_attribute *attr, char* buf)
 {
        struct et61x251_device* cam;
        ssize_t count;
@@ -793,7 +795,8 @@ static ssize_t et61x251_show_val(struct class_device* cd, char* buf)
 
 
 static ssize_t
-et61x251_store_val(struct class_device* cd, const char* buf, size_t len)
+et61x251_store_val(struct device* cd, struct device_attribute *attr,
+                  const char* buf, size_t len)
 {
        struct et61x251_device* cam;
        u8 value;
@@ -831,7 +834,8 @@ et61x251_store_val(struct class_device* cd, const char* buf, size_t len)
 }
 
 
-static ssize_t et61x251_show_i2c_reg(struct class_device* cd, char* buf)
+static ssize_t et61x251_show_i2c_reg(struct device* cd,
+                                    struct device_attribute *attr, char* buf)
 {
        struct et61x251_device* cam;
        ssize_t count;
@@ -856,7 +860,8 @@ static ssize_t et61x251_show_i2c_reg(struct class_device* cd, char* buf)
 
 
 static ssize_t
-et61x251_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
+et61x251_store_i2c_reg(struct device* cd, struct device_attribute *attr,
+                      const char* buf, size_t len)
 {
        struct et61x251_device* cam;
        u8 index;
@@ -888,7 +893,8 @@ et61x251_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
 }
 
 
-static ssize_t et61x251_show_i2c_val(struct class_device* cd, char* buf)
+static ssize_t et61x251_show_i2c_val(struct device* cd,
+                                    struct device_attribute *attr, char* buf)
 {
        struct et61x251_device* cam;
        ssize_t count;
@@ -924,7 +930,8 @@ static ssize_t et61x251_show_i2c_val(struct class_device* cd, char* buf)
 
 
 static ssize_t
-et61x251_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
+et61x251_store_i2c_val(struct device* cd, struct device_attribute *attr,
+                      const char* buf, size_t len)
 {
        struct et61x251_device* cam;
        u8 value;
@@ -967,42 +974,40 @@ et61x251_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
 }
 
 
-static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
-                        et61x251_show_reg, et61x251_store_reg);
-static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
-                        et61x251_show_val, et61x251_store_val);
-static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
-                        et61x251_show_i2c_reg, et61x251_store_i2c_reg);
-static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
-                        et61x251_show_i2c_val, et61x251_store_i2c_val);
+static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
+                  et61x251_show_reg, et61x251_store_reg);
+static DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
+                  et61x251_show_val, et61x251_store_val);
+static DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
+                  et61x251_show_i2c_reg, et61x251_store_i2c_reg);
+static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
+                  et61x251_show_i2c_val, et61x251_store_i2c_val);
 
 
 static int et61x251_create_sysfs(struct et61x251_device* cam)
 {
-       struct class_device *classdev = &(cam->v4ldev->class_dev);
+       struct device *classdev = &(cam->v4ldev->class_dev);
        int err = 0;
 
-       if ((err = class_device_create_file(classdev, &class_device_attr_reg)))
+       if ((err = device_create_file(classdev, &dev_attr_reg)))
                goto err_out;
-       if ((err = class_device_create_file(classdev, &class_device_attr_val)))
+       if ((err = device_create_file(classdev, &dev_attr_val)))
                goto err_reg;
 
        if (cam->sensor.sysfs_ops) {
-               if ((err = class_device_create_file(classdev,
-                                                 &class_device_attr_i2c_reg)))
+               if ((err = device_create_file(classdev, &dev_attr_i2c_reg)))
                        goto err_val;
-               if ((err = class_device_create_file(classdev,
-                                                 &class_device_attr_i2c_val)))
+               if ((err = device_create_file(classdev, &dev_attr_i2c_val)))
                        goto err_i2c_reg;
        }
 
 err_i2c_reg:
        if (cam->sensor.sysfs_ops)
-               class_device_remove_file(classdev, &class_device_attr_i2c_reg);
+               device_remove_file(classdev, &dev_attr_i2c_reg);
 err_val:
-       class_device_remove_file(classdev, &class_device_attr_val);
+       device_remove_file(classdev, &dev_attr_val);
 err_reg:
-       class_device_remove_file(classdev, &class_device_attr_reg);
+       device_remove_file(classdev, &dev_attr_reg);
 err_out:
        return err;
 }
index 2d709e064679249e5567097cfe2515aaec6719a1..d98dd0d1e37301c04644d154d342ca8fde4ca155 100644 (file)
@@ -10,6 +10,8 @@
  *      Ulrich Mueller <ulrich.mueller42@web.de>
  * modified for em2820 based USB TV tuners by
  *      Markus Rechberger <mrechberger@gmail.com>
+ * modified for DViCO Fusion HDTV 5 RT GOLD by
+ *      Chaogui Zhang <czhang1974@gmail.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -28,7 +30,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -142,6 +143,30 @@ static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
        return 1;
 }
 
+static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+       unsigned char buf[4];
+
+       /* poll IR chip */
+       if (4 != i2c_master_recv(&ir->c,buf,4)) {
+               dprintk(1,"read error\n");
+               return -EIO;
+       }
+
+       if(buf[0] !=0 || buf[1] !=0 || buf[2] !=0 || buf[3] != 0)
+               dprintk(2, "%s: 0x%2x 0x%2x 0x%2x 0x%2x\n", __FUNCTION__,
+                       buf[0], buf[1], buf[2], buf[3]);
+
+       /* no key pressed or signal from other ir remote */
+       if(buf[0] != 0x1 ||  buf[1] != 0xfe)
+               return 0;
+
+       *ir_key = buf[2];
+       *ir_raw = (buf[2] << 8) | buf[3];
+
+       return 1;
+}
+
 static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 {
        unsigned char b;
@@ -364,6 +389,12 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
                ir_type     = IR_TYPE_OTHER;
                ir_codes    = ir_codes_empty;
                break;
+       case 0x6b:
+               name        = "FusionHDTV";
+               ir->get_key = get_key_fusionhdtv;
+               ir_type     = IR_TYPE_RC5;
+               ir_codes    = ir_codes_fusionhdtv_mce;
+               break;
        case 0x7a:
        case 0x47:
        case 0x71:
@@ -475,7 +506,8 @@ static int ir_probe(struct i2c_adapter *adap)
        static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
        static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, -1 };
        static const int probe_em28XX[] = { 0x30, 0x47, -1 };
-       static const int probe_cx88[] = { 0x18, 0x71, -1 };
+       static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 };
+       static const int probe_cx23885[] = { 0x6b, -1 };
        const int *probe = NULL;
        struct i2c_client c;
        unsigned char buf;
@@ -496,6 +528,8 @@ static int ir_probe(struct i2c_adapter *adap)
                break;
        case I2C_HW_B_CX2388x:
                probe = probe_cx88;
+       case I2C_HW_B_CX23885:
+               probe = probe_cx23885;
                break;
        }
        if (NULL == probe)
index e43beb2c9cbfd345081758185cb6c544dcda35f3..854cc9c30ca92bb3548aa9f5d5b77571ad7a9f52 100644 (file)
@@ -14,6 +14,7 @@ config VIDEO_IVTV
        select VIDEO_CS53L32A
        select VIDEO_WM8775
        select VIDEO_WM8739
+       select VIDEO_VP27SMPX
        select VIDEO_UPD64031A
        select VIDEO_UPD64083
        ---help---
@@ -25,3 +26,19 @@ config VIDEO_IVTV
 
          To compile this driver as a module, choose M here: the
          module will be called ivtv.
+
+config VIDEO_FB_IVTV
+       tristate "Conexant cx23415 framebuffer support"
+       depends on VIDEO_IVTV && FB && EXPERIMENTAL
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       ---help---
+         This is a framebuffer driver for the Conexant cx23415 MPEG
+         encoder/decoder.
+
+         This is used in the Hauppauge PVR-350 card. There is a driver
+         homepage at <http://www.ivtvdriver.org>.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ivtvfb.
index 7e95148fbf4fc44c0c114c5c07d592d018e3d66e..e8eefd96d8976f7eaa6e12a55e7a8d03417908fb 100644 (file)
@@ -1,7 +1,8 @@
-ivtv-objs      := ivtv-audio.o ivtv-cards.o ivtv-controls.o \
+ivtv-objs      := ivtv-routing.o ivtv-cards.o ivtv-controls.o \
                   ivtv-driver.o ivtv-fileops.o ivtv-firmware.o \
                   ivtv-gpio.o ivtv-i2c.o ivtv-ioctl.o ivtv-irq.o \
                   ivtv-mailbox.o ivtv-queue.o ivtv-streams.o ivtv-udma.o \
-                  ivtv-vbi.o ivtv-video.o ivtv-yuv.o
+                  ivtv-vbi.o ivtv-yuv.o
 
 obj-$(CONFIG_VIDEO_IVTV) += ivtv.o
+obj-$(CONFIG_VIDEO_FB_IVTV) += ivtvfb.o
diff --git a/drivers/media/video/ivtv/ivtv-audio.c b/drivers/media/video/ivtv/ivtv-audio.c
deleted file mode 100644 (file)
index d702b8b..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-    Audio-related ivtv functions.
-    Copyright (C) 2003-2004  Kevin Thayer <nufan_wfk at yahoo.com>
-    Copyright (C) 2005-2007  Hans Verkuil <hverkuil@xs4all.nl>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "ivtv-driver.h"
-#include "ivtv-mailbox.h"
-#include "ivtv-i2c.h"
-#include "ivtv-gpio.h"
-#include "ivtv-cards.h"
-#include "ivtv-audio.h"
-#include <media/msp3400.h>
-#include <linux/videodev.h>
-
-/* Selects the audio input and output according to the current
-   settings. */
-int ivtv_audio_set_io(struct ivtv *itv)
-{
-       struct v4l2_routing route;
-       u32 audio_input;
-       int mux_input;
-
-       /* Determine which input to use */
-       if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
-               audio_input = itv->card->radio_input.audio_input;
-               mux_input = itv->card->radio_input.muxer_input;
-       } else {
-               audio_input = itv->card->audio_inputs[itv->audio_input].audio_input;
-               mux_input = itv->card->audio_inputs[itv->audio_input].muxer_input;
-       }
-
-       /* handle muxer chips */
-       route.input = mux_input;
-       route.output = 0;
-       ivtv_i2c_hw(itv, itv->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
-
-       route.input = audio_input;
-       if (itv->card->hw_audio & IVTV_HW_MSP34XX) {
-               route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
-       }
-       return ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, &route);
-}
-
-void ivtv_audio_set_route(struct ivtv *itv, struct v4l2_routing *route)
-{
-       ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route);
-}
-
-void ivtv_audio_set_audio_clock_freq(struct ivtv *itv, u8 freq)
-{
-       static u32 freqs[3] = { 44100, 48000, 32000 };
-
-       /* The audio clock of the digitizer must match the codec sample
-          rate otherwise you get some very strange effects. */
-       if (freq > 2)
-               return;
-       ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[freq]);
-}
-
index 8eab02083887034240101053a6ab23850b81dd18..b6a8be622d3ccfdb0db39c51b369ff55792ff918 100644 (file)
@@ -616,7 +616,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx = {
        .hw_video = IVTV_HW_SAA7115 | IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
        .hw_audio = IVTV_HW_GPIO,
        .hw_audio_ctrl = IVTV_HW_WM8739,
-       .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TVAUDIO |
+       .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_VP27SMPX |
                  IVTV_HW_TUNER | IVTV_HW_WM8739 |
                  IVTV_HW_UPD64031A | IVTV_HW_UPD6408X,
        .video_inputs = {
@@ -654,7 +654,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx2e = {
        .hw_audio = IVTV_HW_GPIO,
        .hw_audio_ctrl = IVTV_HW_WM8739,
        .hw_all = IVTV_HW_GPIO | IVTV_HW_SAA7115 | IVTV_HW_TUNER |
-                 IVTV_HW_TVAUDIO | IVTV_HW_WM8739,
+                 IVTV_HW_VP27SMPX | IVTV_HW_WM8739,
        .video_inputs = {
                { IVTV_CARD_INPUT_VID_TUNER,  0, IVTV_SAA71XX_COMPOSITE4 },
                { IVTV_CARD_INPUT_SVIDEO1,    1, IVTV_SAA71XX_SVIDEO0    },
@@ -823,9 +823,7 @@ static const struct ivtv_card ivtv_card_dctmvtvp1 = {
 
 /* ------------------------------------------------------------------------- */
 
-#ifdef HAVE_XC3028
-
-/* Yuan PG600-2/GotView PCI DVD Lite/Club3D ZAP-TV1x01 cards */
+/* Yuan PG600-2/GotView PCI DVD Lite cards */
 
 static const struct ivtv_card_pci_info ivtv_pci_pg600v2[] = {
        { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3,     0x0600 },
@@ -835,29 +833,87 @@ static const struct ivtv_card_pci_info ivtv_pci_pg600v2[] = {
 
 static const struct ivtv_card ivtv_card_pg600v2 = {
        .type = IVTV_CARD_PG600V2,
-       .name = "Yuan PG600-2, GotView PCI DVD Lite, Club3D ZAP-TV1x01",
+       .name = "Yuan PG600-2, GotView PCI DVD Lite",
        .v4l2_capabilities = IVTV_CAP_ENCODER,
        .hw_video = IVTV_HW_CX25840,
        .hw_audio = IVTV_HW_CX25840,
        .hw_audio_ctrl = IVTV_HW_CX25840,
        .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
        .video_inputs = {
-               { IVTV_CARD_INPUT_VID_TUNER,  0, CX25840_COMPOSITE2 },
-               { IVTV_CARD_INPUT_SVIDEO1,    1,
+               { IVTV_CARD_INPUT_SVIDEO1,    0,
                  CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
+               { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 },
        },
        .audio_inputs = {
-               { IVTV_CARD_INPUT_AUD_TUNER,  CX25840_AUDIO5       },
                { IVTV_CARD_INPUT_LINE_IN1,   CX25840_AUDIO_SERIAL },
        },
-       .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
        .tuners = {
                { .std = V4L2_STD_ALL, .tuner = TUNER_XCEIVE_XC3028 },
        },
-       .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, /* tuner reset */
        .pci_list = ivtv_pci_pg600v2,
 };
-#endif
+
+/* ------------------------------------------------------------------------- */
+
+/* Club3D ZAP-TV1x01 cards */
+
+static const struct ivtv_card_pci_info ivtv_pci_club3d[] = {
+       { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_YUAN3,     0x0600 },
+       { 0, 0, 0 }
+};
+
+static const struct ivtv_card ivtv_card_club3d = {
+       .type = IVTV_CARD_CLUB3D,
+       .name = "Club3D ZAP-TV1x01",
+       .v4l2_capabilities = IVTV_CAP_ENCODER,
+       .hw_video = IVTV_HW_CX25840,
+       .hw_audio = IVTV_HW_CX25840,
+       .hw_audio_ctrl = IVTV_HW_CX25840,
+       .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
+       .video_inputs = {
+               { IVTV_CARD_INPUT_SVIDEO1,    0,
+                 CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
+               { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE3 },
+       },
+       .audio_inputs = {
+               { IVTV_CARD_INPUT_LINE_IN1,   CX25840_AUDIO_SERIAL },
+       },
+       .tuners = {
+               { .std = V4L2_STD_ALL, .tuner = TUNER_XCEIVE_XC3028 },
+       },
+       .pci_list = ivtv_pci_club3d,
+};
+
+/* ------------------------------------------------------------------------- */
+
+/* AVerTV MCE 116 Plus (M116) card */
+
+static const struct ivtv_card_pci_info ivtv_pci_avertv_mce116[] = {
+       { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc439 },
+       { 0, 0, 0 }
+};
+
+static const struct ivtv_card ivtv_card_avertv_mce116 = {
+       .type = IVTV_CARD_AVERTV_MCE116,
+       .name = "AVerTV MCE 116 Plus",
+       .v4l2_capabilities = IVTV_CAP_ENCODER,
+       .hw_video = IVTV_HW_CX25840,
+       .hw_audio = IVTV_HW_CX25840,
+       .hw_audio_ctrl = IVTV_HW_CX25840,
+       .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739,
+       .video_inputs = {
+               { IVTV_CARD_INPUT_SVIDEO1,    0, CX25840_SVIDEO3    },
+               { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 },
+       },
+       .audio_inputs = {
+               { IVTV_CARD_INPUT_LINE_IN1,   CX25840_AUDIO_SERIAL, 1 },
+       },
+       .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, /* enable line-in */
+       .tuners = {
+               { .std = V4L2_STD_ALL, .tuner = TUNER_XCEIVE_XC3028 },
+       },
+       .pci_list = ivtv_pci_avertv_mce116,
+};
 
 static const struct ivtv_card *ivtv_card_list[] = {
        &ivtv_card_pvr250,
@@ -878,9 +934,9 @@ static const struct ivtv_card *ivtv_card_list[] = {
        &ivtv_card_gotview_pci_dvd2,
        &ivtv_card_yuan_mpc622,
        &ivtv_card_dctmvtvp1,
-#ifdef HAVE_XC3028
        &ivtv_card_pg600v2,
-#endif
+       &ivtv_card_club3d,
+       &ivtv_card_avertv_mce116,
 
        /* Variations of standard cards but with the same PCI IDs.
           These cards must come last in this list. */
index 91e9e90c14a5eaebe90677f3aa165ced92d0c956..ff46e5ae8653717d978940ccf562dc58f4b2659f 100644 (file)
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_CARDS_H
+#define IVTV_CARDS_H
+
+/* Supported cards */
+#define IVTV_CARD_PVR_250            0 /* WinTV PVR 250 */
+#define IVTV_CARD_PVR_350            1 /* encoder, decoder, tv-out */
+#define IVTV_CARD_PVR_150            2 /* WinTV PVR 150 and PVR 500 (really just two
+                                          PVR150s on one PCI board) */
+#define IVTV_CARD_M179               3 /* AVerMedia M179 (encoder only) */
+#define IVTV_CARD_MPG600             4 /* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */
+#define IVTV_CARD_MPG160             5 /* Kuroutoshikou ITVC15-STVLP/YUAN MPG160
+                                          cx23415 based, but does not have tv-out */
+#define IVTV_CARD_PG600              6 /* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */
+#define IVTV_CARD_AVC2410            7 /* Adaptec AVC-2410 */
+#define IVTV_CARD_AVC2010            8 /* Adaptec AVD-2010 (No Tuner) */
+#define IVTV_CARD_TG5000TV           9 /* NAGASE TRANSGEAR 5000TV, encoder only */
+#define IVTV_CARD_VA2000MAX_SNT6     10 /* VA2000MAX-STN6 */
+#define IVTV_CARD_CX23416GYC        11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
+#define IVTV_CARD_GV_MVPRX          12 /* I/O Data GV-MVP/RX, RX2, RX2W */
+#define IVTV_CARD_GV_MVPRX2E        13 /* I/O Data GV-MVP/RX2E */
+#define IVTV_CARD_GOTVIEW_PCI_DVD    14        /* GotView PCI DVD */
+#define IVTV_CARD_GOTVIEW_PCI_DVD2   15        /* GotView PCI DVD2 */
+#define IVTV_CARD_YUAN_MPC622        16        /* Yuan MPC622 miniPCI */
+#define IVTV_CARD_DCTMTVP1          17 /* DIGITAL COWBOY DCT-MTVP1 */
+#define IVTV_CARD_PG600V2           18 /* Yuan PG600V2/GotView PCI DVD Lite */
+#define IVTV_CARD_CLUB3D            19 /* Club3D ZAP-TV1x01 */
+#define IVTV_CARD_AVERTV_MCE116             20 /* AVerTV MCE 116 Plus */
+#define IVTV_CARD_LAST                      20
+
+/* Variants of existing cards but with the same PCI IDs. The driver
+   detects these based on other device information.
+   These cards must always come last.
+   New cards must be inserted above, and the indices of the cards below
+   must be adjusted accordingly. */
+
+/* PVR-350 V1 (uses saa7114) */
+#define IVTV_CARD_PVR_350_V1        (IVTV_CARD_LAST+1)
+/* 2 variants of Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
+#define IVTV_CARD_CX23416GYC_NOGR    (IVTV_CARD_LAST+2)
+#define IVTV_CARD_CX23416GYC_NOGRYCS (IVTV_CARD_LAST+3)
+
+/* system vendor and device IDs */
+#define PCI_VENDOR_ID_ICOMP  0x4444
+#define PCI_DEVICE_ID_IVTV15 0x0803
+#define PCI_DEVICE_ID_IVTV16 0x0016
+
+/* subsystem vendor ID */
+#define IVTV_PCI_ID_HAUPPAUGE          0x0070
+#define IVTV_PCI_ID_HAUPPAUGE_ALT1     0x0270
+#define IVTV_PCI_ID_HAUPPAUGE_ALT2     0x4070
+#define IVTV_PCI_ID_ADAPTEC            0x9005
+#define IVTV_PCI_ID_AVERMEDIA          0x1461
+#define IVTV_PCI_ID_YUAN1              0x12ab
+#define IVTV_PCI_ID_YUAN2              0xff01
+#define IVTV_PCI_ID_YUAN3              0xffab
+#define IVTV_PCI_ID_YUAN4              0xfbab
+#define IVTV_PCI_ID_DIAMONDMM          0xff92
+#define IVTV_PCI_ID_IODATA             0x10fc
+#define IVTV_PCI_ID_MELCO              0x1154
+#define IVTV_PCI_ID_GOTVIEW1           0xffac
+#define IVTV_PCI_ID_GOTVIEW2           0xffad
+
 /* hardware flags */
 #define IVTV_HW_CX25840   (1 << 0)
 #define IVTV_HW_SAA7115   (1 << 1)
@@ -33,7 +95,8 @@
 #define IVTV_HW_UPD6408X  (1 << 11)
 #define IVTV_HW_SAA717X   (1 << 12)
 #define IVTV_HW_WM8739    (1 << 13)
-#define IVTV_HW_GPIO      (1 << 14)
+#define IVTV_HW_VP27SMPX  (1 << 14)
+#define IVTV_HW_GPIO      (1 << 15)
 
 #define IVTV_HW_SAA711X   (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
 
@@ -205,3 +268,5 @@ int ivtv_get_output(struct ivtv *itv, u16 index, struct v4l2_output *output);
 int ivtv_get_audio_input(struct ivtv *itv, u16 index, struct v4l2_audio *input);
 int ivtv_get_audio_output(struct ivtv *itv, u16 index, struct v4l2_audioout *output);
 const struct ivtv_card *ivtv_get_card(u16 index);
+
+#endif
index 7a876c3e5b19e836b955ccf9948cec413dabe8f9..8c02fa661591fd063611795c1dd5236aedede43e 100644 (file)
@@ -21,7 +21,7 @@
 #include "ivtv-driver.h"
 #include "ivtv-cards.h"
 #include "ivtv-ioctl.h"
-#include "ivtv-audio.h"
+#include "ivtv-routing.h"
 #include "ivtv-i2c.h"
 #include "ivtv-mailbox.h"
 #include "ivtv-controls.h"
@@ -231,8 +231,10 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
                }
                IVTV_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
                if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+                       static u32 freqs[3] = { 44100, 48000, 32000 };
                        struct cx2341x_mpeg_params p = itv->params;
-                       int err = cx2341x_ext_ctrls(&p, arg, cmd);
+                       int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), arg, cmd);
+                       unsigned idx;
 
                        if (err)
                                return err;
@@ -254,7 +256,11 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
                        }
                        itv->params = p;
                        itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
-                       ivtv_audio_set_audio_clock_freq(itv, p.audio_properties & 0x03);
+                       idx = p.audio_properties & 0x03;
+                       /* The audio clock of the digitizer must match the codec sample
+                          rate otherwise you get some very strange effects. */
+                       if (idx < sizeof(freqs))
+                           ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]);
                        return err;
                }
                return -EINVAL;
@@ -282,7 +288,7 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
                }
                IVTV_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n");
                if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
-                       return cx2341x_ext_ctrls(&itv->params, arg, cmd);
+                       return cx2341x_ext_ctrls(&itv->params, 0, arg, cmd);
                return -EINVAL;
        }
 
@@ -292,7 +298,7 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
 
                IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
                if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
-                       return cx2341x_ext_ctrls(&itv->params, arg, cmd);
+                       return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), arg, cmd);
                return -EINVAL;
        }
 
index 5a11149725ad96e6441a3e4c688fd61dd6f7e7b5..bb8a6a5ed2bc48d2ff503c756e06666b043223fe 100644 (file)
@@ -18,4 +18,9 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_CONTROLS_H
+#define IVTV_CONTROLS_H
+
 int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg);
+
+#endif
index d73d433a4ff6ff59dbd0c4679295855aa5b08870..511a66252413842527b288a0fc229164601fe5bf 100644 (file)
 #include "ivtv-ioctl.h"
 #include "ivtv-cards.h"
 #include "ivtv-vbi.h"
-#include "ivtv-audio.h"
+#include "ivtv-routing.h"
 #include "ivtv-gpio.h"
 #include "ivtv-yuv.h"
 
 #include <media/tveeprom.h>
+#include <media/saa7115.h>
 #include <media/v4l2-chip-ident.h>
 
 /* var to keep track of the number of array elements in use */
@@ -86,17 +87,16 @@ static struct pci_device_id ivtv_pci_tbl[] __devinitdata = {
 
 MODULE_DEVICE_TABLE(pci,ivtv_pci_tbl);
 
-const u32 yuv_offset[4] = {
-       IVTV_YUV_BUFFER_OFFSET,
-       IVTV_YUV_BUFFER_OFFSET_1,
-       IVTV_YUV_BUFFER_OFFSET_2,
-       IVTV_YUV_BUFFER_OFFSET_3
-};
-
 /* Parameter declarations */
 static int cardtype[IVTV_MAX_CARDS];
-static int tuner[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
-static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
+static int tuner[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -1, -1, -1, -1, -1, -1, -1, -1 };
+static int radio[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -1, -1, -1, -1, -1, -1, -1, -1,
+                                    -1, -1, -1, -1, -1, -1, -1, -1 };
 
 static int cardtype_c = 1;
 static int tuner_c = 1;
@@ -106,6 +106,18 @@ static char secam[] = "--";
 static char ntsc[] = "-";
 
 /* Buffers */
+
+/* DMA Buffers, Default size in MB allocated */
+#define IVTV_DEFAULT_ENC_MPG_BUFFERS 4
+#define IVTV_DEFAULT_ENC_YUV_BUFFERS 2
+#define IVTV_DEFAULT_ENC_VBI_BUFFERS 1
+/* Exception: size in kB for this stream (MB is overkill) */
+#define IVTV_DEFAULT_ENC_PCM_BUFFERS 320
+#define IVTV_DEFAULT_DEC_MPG_BUFFERS 1
+#define IVTV_DEFAULT_DEC_YUV_BUFFERS 1
+/* Exception: size in kB for this stream (MB is way overkill) */
+#define IVTV_DEFAULT_DEC_VBI_BUFFERS 64
+
 static int enc_mpg_buffers = IVTV_DEFAULT_ENC_MPG_BUFFERS;
 static int enc_yuv_buffers = IVTV_DEFAULT_ENC_YUV_BUFFERS;
 static int enc_vbi_buffers = IVTV_DEFAULT_ENC_VBI_BUFFERS;
@@ -170,17 +182,27 @@ MODULE_PARM_DESC(cardtype,
                 "\t\t\t16 = GOTVIEW PCI DVD2 Deluxe\n"
                 "\t\t\t17 = Yuan MPC622\n"
                 "\t\t\t18 = Digital Cowboy DCT-MTVP1\n"
-#ifdef HAVE_XC3028
-                "\t\t\t19 = Yuan PG600V2/GotView PCI DVD Lite/Club3D ZAP-TV1x01\n"
-#endif
+                "\t\t\t19 = Yuan PG600V2/GotView PCI DVD Lite\n"
+                "\t\t\t20 = Club3D ZAP-TV1x01\n"
+                "\t\t\t21 = AverTV MCE 116 Plus\n"
                 "\t\t\t 0 = Autodetect (default)\n"
                 "\t\t\t-1 = Ignore this card\n\t\t");
 MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
 MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC");
 MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K");
 MODULE_PARM_DESC(debug,
-                "Debug level (bitmask). Default: errors only\n"
-                "\t\t\t(debug = 1023 gives full debugging)");
+                "Debug level (bitmask). Default: 0\n"
+                "\t\t\t   1/0x0001: warning\n"
+                "\t\t\t   2/0x0002: info\n"
+                "\t\t\t   4/0x0004: mailbox\n"
+                "\t\t\t   8/0x0008: ioctl\n"
+                "\t\t\t  16/0x0010: file\n"
+                "\t\t\t  32/0x0020: dma\n"
+                "\t\t\t  64/0x0040: irq\n"
+                "\t\t\t 128/0x0080: decoder\n"
+                "\t\t\t 256/0x0100: yuv\n"
+                "\t\t\t 512/0x0200: i2c\n"
+                "\t\t\t1024/0x0400: high volume\n");
 MODULE_PARM_DESC(ivtv_pci_latency,
                 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
                 "\t\t\tDefault: Yes");
@@ -201,7 +223,7 @@ MODULE_PARM_DESC(enc_vbi_buffers,
                 "Encoder VBI Buffers (in MB)\n"
                 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_VBI_BUFFERS));
 MODULE_PARM_DESC(enc_pcm_buffers,
-                "Encoder PCM buffers (in MB)\n"
+                "Encoder PCM buffers (in kB)\n"
                 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_PCM_BUFFERS));
 MODULE_PARM_DESC(dec_mpg_buffers,
                 "Decoder MPG buffers (in MB)\n"
@@ -210,7 +232,7 @@ MODULE_PARM_DESC(dec_yuv_buffers,
                 "Decoder YUV buffers (in MB)\n"
                 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_YUV_BUFFERS));
 MODULE_PARM_DESC(dec_vbi_buffers,
-                "Decoder VBI buffers (in MB)\n"
+                "Decoder VBI buffers (in kB)\n"
                 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_DEC_VBI_BUFFERS));
 MODULE_PARM_DESC(newi2c,
                 "Use new I2C implementation\n"
@@ -540,13 +562,13 @@ static void ivtv_process_options(struct ivtv *itv)
        const char *chipname;
        int i, j;
 
-       itv->options.megabytes[IVTV_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers;
-       itv->options.megabytes[IVTV_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers;
-       itv->options.megabytes[IVTV_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers;
-       itv->options.megabytes[IVTV_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
-       itv->options.megabytes[IVTV_DEC_STREAM_TYPE_MPG] = dec_mpg_buffers;
-       itv->options.megabytes[IVTV_DEC_STREAM_TYPE_YUV] = dec_yuv_buffers;
-       itv->options.megabytes[IVTV_DEC_STREAM_TYPE_VBI] = dec_vbi_buffers;
+       itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers * 1024;
+       itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers * 1024;
+       itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers * 1024;
+       itv->options.kilobytes[IVTV_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers;
+       itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_MPG] = dec_mpg_buffers * 1024;
+       itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_YUV] = dec_yuv_buffers * 1024;
+       itv->options.kilobytes[IVTV_DEC_STREAM_TYPE_VBI] = dec_vbi_buffers;
        itv->options.cardtype = cardtype[itv->num];
        itv->options.tuner = tuner[itv->num];
        itv->options.radio = radio[itv->num];
@@ -645,7 +667,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
        cx2341x_fill_defaults(&itv->params);
        itv->params.port = CX2341X_PORT_MEMORY;
        itv->params.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
-       init_waitqueue_head(&itv->cap_w);
+       init_waitqueue_head(&itv->eos_waitq);
        init_waitqueue_head(&itv->event_waitq);
        init_waitqueue_head(&itv->vsync_waitq);
        init_waitqueue_head(&itv->dma_waitq);
@@ -691,14 +713,6 @@ static void __devinit ivtv_init_struct2(struct ivtv *itv)
                        break;
        itv->nof_audio_inputs = i;
 
-       /* 0x00EF = saa7114(239) 0x00F0 = saa7115(240) 0x0106 = micro */
-       if (itv->card->hw_all & (IVTV_HW_SAA7115 | IVTV_HW_SAA717X))
-               itv->digitizer = 0xF1;
-       else if (itv->card->hw_all & IVTV_HW_SAA7114)
-               itv->digitizer = 0xEF;
-       else /* cx25840 */
-               itv->digitizer = 0x140;
-
        if (itv->card->hw_all & IVTV_HW_CX25840) {
                itv->vbi.sliced_size = 288;  /* multiple of 16, real size = 284 */
        } else {
@@ -727,6 +741,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
                          const struct pci_device_id *pci_id)
 {
        u16 cmd;
+       u8 card_rev;
        unsigned char pci_latency;
 
        IVTV_DEBUG_INFO("Enabling pci device\n");
@@ -773,7 +788,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
        }
        IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
 
-       pci_read_config_byte(dev, PCI_CLASS_REVISION, &itv->card_rev);
+       pci_read_config_byte(dev, PCI_CLASS_REVISION, &card_rev);
        pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
 
        if (pci_latency < 64 && ivtv_pci_latency) {
@@ -790,7 +805,7 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
 
        IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
                   "irq: %d, latency: %d, memory: 0x%lx\n",
-                  itv->dev->device, itv->card_rev, dev->bus->number,
+                  itv->dev->device, card_rev, dev->bus->number,
                   PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
                   itv->dev->irq, pci_latency, (unsigned long)itv->base_addr);
 
@@ -808,18 +823,19 @@ static void ivtv_request_module(struct ivtv *itv, const char *name)
 
 static void ivtv_load_and_init_modules(struct ivtv *itv)
 {
-       struct v4l2_control ctrl;
        u32 hw = itv->card->hw_all;
        int i;
 
        /* load modules */
 #ifndef CONFIG_VIDEO_TUNER
        if (hw & IVTV_HW_TUNER) {
-               ivtv_request_module(itv, "tuner");
-#ifdef HAVE_XC3028
-               if (itv->options.tuner == TUNER_XCEIVE_XC3028)
-                       ivtv_request_module(itv, "xc3028-tuner");
-#endif
+               if (itv->options.tuner == TUNER_XCEIVE_XC3028) {
+                       IVTV_INFO("Xceive tuner not yet supported, only composite and S-Video inputs will be available\n");
+                       itv->tunerid = 1;
+               }
+               else {
+                       ivtv_request_module(itv, "tuner");
+               }
        }
 #endif
 #ifndef CONFIG_VIDEO_CX25840
@@ -847,6 +863,10 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
 #ifndef CONFIG_VIDEO_MSP3400
        if (hw & IVTV_HW_MSP34XX)
                ivtv_request_module(itv, "msp3400");
+#endif
+#ifndef CONFIG_VIDEO_VP27SMPX
+       if (hw & IVTV_HW_VP27SMPX)
+               ivtv_request_module(itv, "vp27smpx");
 #endif
        if (hw & IVTV_HW_TVAUDIO)
                ivtv_request_module(itv, "tvaudio");
@@ -888,13 +908,17 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
                else if ((hw & IVTV_HW_UPD64031A) == 0)
                        itv->card = ivtv_get_card(IVTV_CARD_CX23416GYC_NOGR);
        }
+       else if (itv->card->type == IVTV_CARD_GV_MVPRX ||
+                itv->card->type == IVTV_CARD_GV_MVPRX2E) {
+               struct v4l2_crystal_freq crystal_freq;
+
+               /* The crystal frequency of GVMVPRX is 24.576MHz */
+               crystal_freq.freq = SAA7115_FREQ_24_576_MHZ;
+               crystal_freq.flags = SAA7115_FREQ_FL_UCGC;
+               itv->video_dec_func(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
+       }
 
        if (hw & IVTV_HW_CX25840) {
-               /* CX25840_CID_ENABLE_PVR150_WORKAROUND */
-               ctrl.id = V4L2_CID_PRIVATE_BASE;
-               ctrl.value = itv->pvr150_workaround;
-               itv->video_dec_func(itv, VIDIOC_S_CTRL, &ctrl);
-
                itv->vbi.raw_decoder_line_size = 1444;
                itv->vbi.raw_decoder_sav_odd_field = 0x20;
                itv->vbi.raw_decoder_sav_even_field = 0x60;
@@ -940,12 +964,9 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                                const struct pci_device_id *pci_id)
 {
        int retval = 0;
-       int video_input;
        int yuv_buf_size;
        int vbi_buf_size;
-       int fw_retry_count = 3;
        struct ivtv *itv;
-       struct v4l2_frequency vf;
 
        spin_lock(&ivtv_cards_lock);
 
@@ -982,6 +1003,8 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
 
        IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
 
+       mutex_lock(&itv->serialize_lock);
+
        /* PCI Device Setup */
        if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
                if (retval == -EIO)
@@ -1032,22 +1055,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                goto free_io;
        }
 
-       while (--fw_retry_count > 0) {
-               /* load firmware */
-               if (ivtv_firmware_init(itv) == 0)
-                       break;
-               if (fw_retry_count > 1)
-                       IVTV_WARN("Retry loading firmware\n");
-       }
-       if (fw_retry_count == 0) {
-               IVTV_ERR("Error initializing firmware\n");
-               goto free_i2c;
-       }
-
-       /* Try and get firmware versions */
-       IVTV_DEBUG_INFO("Getting firmware version..\n");
-       ivtv_firmware_versions(itv);
-
        /* Check yuv output filter table */
        if (itv->has_cx23415) ivtv_yuv_filter_check(itv);
 
@@ -1135,43 +1142,22 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
        if (itv->options.radio > 0)
                itv->v4l2_cap |= V4L2_CAP_RADIO;
 
-       if (itv->options.tuner > -1) {
+       if (itv->options.tuner > -1 && itv->tunerid == 0) {
                struct tuner_setup setup;
 
                setup.addr = ADDR_UNSET;
                setup.type = itv->options.tuner;
                setup.mode_mask = T_ANALOG_TV;  /* matches TV tuners */
-#ifdef HAVE_XC3028
-               setup.initmode = V4L2_TUNER_ANALOG_TV;
-               if (itv->options.tuner == TUNER_XCEIVE_XC3028) {
-                       setup.gpio_write = ivtv_reset_tuner_gpio;
-                       setup.gpio_priv = itv;
-               }
-#endif
                ivtv_call_i2c_clients(itv, TUNER_SET_TYPE_ADDR, &setup);
        }
 
-       vf.tuner = 0;
-       vf.type = V4L2_TUNER_ANALOG_TV;
-       vf.frequency = 6400; /* the tuner 'baseline' frequency */
-       if (itv->std & V4L2_STD_NTSC_M) {
-               /* Why on earth? */
-               vf.frequency = 1076;    /* ch. 4 67250*16/1000 */
-       }
-
        /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
           are not. */
        itv->tuner_std = itv->std;
 
-       video_input = itv->active_input;
-       itv->active_input++;    /* Force update of input */
-       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input);
-
-       /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
-          in one place. */
-       itv->std++;             /* Force full standard initialization */
-       itv->std_out = itv->std;
-       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf);
+       if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
+               ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std);
+       }
 
        retval = ivtv_streams_setup(itv);
        if (retval) {
@@ -1179,11 +1165,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                goto free_i2c;
        }
 
-       if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
-               ivtv_init_mpeg_decoder(itv);
-       }
-       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std);
-
        IVTV_DEBUG_IRQ("Masking interrupts\n");
        /* clear interrupt mask, effectively disabling interrupts */
        ivtv_set_irq_mask(itv, 0xffffffff);
@@ -1195,26 +1176,8 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                IVTV_ERR("Failed to register irq %d\n", retval);
                goto free_streams;
        }
-
-       /* On a cx23416 this seems to be able to enable DMA to the chip? */
-       if (!itv->has_cx23415)
-               write_reg_sync(0x03, IVTV_REG_DMACONTROL);
-
-       /* Default interrupts enabled. For the PVR350 this includes the
-          decoder VSYNC interrupt, which is always on. It is not only used
-          during decoding but also by the OSD.
-          Some old PVR250 cards had a cx23415, so testing for that is too
-          general. Instead test if the card has video output capability. */
-       if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
-               ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
-       else
-               ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
-
-       if (itv->has_cx23415)
-               ivtv_set_osd_alpha(itv);
-
+       mutex_unlock(&itv->serialize_lock);
        IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
-
        return 0;
 
       free_irq:
@@ -1232,65 +1195,146 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
       free_workqueue:
        destroy_workqueue(itv->irq_work_queues);
+       mutex_unlock(&itv->serialize_lock);
       err:
        if (retval == 0)
                retval = -ENODEV;
        IVTV_ERR("Error %d on initialization\n", retval);
 
+       spin_lock(&ivtv_cards_lock);
        kfree(ivtv_cards[ivtv_cards_active]);
        ivtv_cards[ivtv_cards_active] = NULL;
+       spin_unlock(&ivtv_cards_lock);
        return retval;
 }
 
+int ivtv_init_on_first_open(struct ivtv *itv)
+{
+       struct v4l2_frequency vf;
+       int fw_retry_count = 3;
+       int video_input;
+
+       if (test_bit(IVTV_F_I_FAILED, &itv->i_flags))
+               return -ENXIO;
+
+       if (test_and_set_bit(IVTV_F_I_INITED, &itv->i_flags))
+               return 0;
+
+       while (--fw_retry_count > 0) {
+               /* load firmware */
+               if (ivtv_firmware_init(itv) == 0)
+                       break;
+               if (fw_retry_count > 1)
+                       IVTV_WARN("Retry loading firmware\n");
+       }
+
+       if (fw_retry_count == 0) {
+               set_bit(IVTV_F_I_FAILED, &itv->i_flags);
+               return -ENXIO;
+       }
+
+       /* Try and get firmware versions */
+       IVTV_DEBUG_INFO("Getting firmware version..\n");
+       ivtv_firmware_versions(itv);
+
+       if (itv->card->hw_all & IVTV_HW_CX25840) {
+               struct v4l2_control ctrl;
+
+               /* CX25840_CID_ENABLE_PVR150_WORKAROUND */
+               ctrl.id = V4L2_CID_PRIVATE_BASE;
+               ctrl.value = itv->pvr150_workaround;
+               itv->video_dec_func(itv, VIDIOC_S_CTRL, &ctrl);
+       }
+
+       vf.tuner = 0;
+       vf.type = V4L2_TUNER_ANALOG_TV;
+       vf.frequency = 6400; /* the tuner 'baseline' frequency */
+
+       /* Set initial frequency. For PAL/SECAM broadcasts no
+          'default' channel exists AFAIK. */
+       if (itv->std == V4L2_STD_NTSC_M_JP) {
+               vf.frequency = 1460;    /* ch. 1 91250*16/1000 */
+       }
+       else if (itv->std & V4L2_STD_NTSC_M) {
+               vf.frequency = 1076;    /* ch. 4 67250*16/1000 */
+       }
+
+       video_input = itv->active_input;
+       itv->active_input++;    /* Force update of input */
+       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input);
+
+       /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
+          in one place. */
+       itv->std++;             /* Force full standard initialization */
+       itv->std_out = itv->std;
+       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf);
+
+       if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
+               ivtv_init_mpeg_decoder(itv);
+       }
+       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std);
+
+       /* On a cx23416 this seems to be able to enable DMA to the chip? */
+       if (!itv->has_cx23415)
+               write_reg_sync(0x03, IVTV_REG_DMACONTROL);
+
+       /* Default interrupts enabled. For the PVR350 this includes the
+          decoder VSYNC interrupt, which is always on. It is not only used
+          during decoding but also by the OSD.
+          Some old PVR250 cards had a cx23415, so testing for that is too
+          general. Instead test if the card has video output capability. */
+       if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
+               ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
+               ivtv_set_osd_alpha(itv);
+       }
+       else
+               ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
+       return 0;
+}
+
 static void ivtv_remove(struct pci_dev *pci_dev)
 {
        struct ivtv *itv = pci_get_drvdata(pci_dev);
 
        IVTV_DEBUG_INFO("Removing Card #%d\n", itv->num);
 
-       /* Stop all captures */
-       IVTV_DEBUG_INFO("Stopping all streams\n");
-       if (atomic_read(&itv->capturing) > 0)
-               ivtv_stop_all_captures(itv);
-
-       /* Stop all decoding */
-       IVTV_DEBUG_INFO("Stopping decoding\n");
-       if (atomic_read(&itv->decoding) > 0) {
-               int type;
-
-               if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
-                       type = IVTV_DEC_STREAM_TYPE_YUV;
-               else
-                       type = IVTV_DEC_STREAM_TYPE_MPG;
-               ivtv_stop_v4l2_decode_stream(&itv->streams[type],
-                       VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
+       if (test_bit(IVTV_F_I_INITED, &itv->i_flags)) {
+               /* Stop all captures */
+               IVTV_DEBUG_INFO("Stopping all streams\n");
+               if (atomic_read(&itv->capturing) > 0)
+                       ivtv_stop_all_captures(itv);
+
+               /* Stop all decoding */
+               IVTV_DEBUG_INFO("Stopping decoding\n");
+               if (atomic_read(&itv->decoding) > 0) {
+                       int type;
+
+                       if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
+                               type = IVTV_DEC_STREAM_TYPE_YUV;
+                       else
+                               type = IVTV_DEC_STREAM_TYPE_MPG;
+                       ivtv_stop_v4l2_decode_stream(&itv->streams[type],
+                               VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
+               }
+               ivtv_halt_firmware(itv);
        }
 
        /* Interrupts */
-       IVTV_DEBUG_INFO("Disabling interrupts\n");
        ivtv_set_irq_mask(itv, 0xffffffff);
        del_timer_sync(&itv->dma_timer);
 
        /* Stop all Work Queues */
-       IVTV_DEBUG_INFO("Stop Work Queues\n");
        flush_workqueue(itv->irq_work_queues);
        destroy_workqueue(itv->irq_work_queues);
 
-       IVTV_DEBUG_INFO("Stopping Firmware\n");
-       ivtv_halt_firmware(itv);
-
-       IVTV_DEBUG_INFO("Unregistering v4l devices\n");
        ivtv_streams_cleanup(itv);
-       IVTV_DEBUG_INFO("Freeing dma resources\n");
        ivtv_udma_free(itv);
 
        exit_ivtv_i2c(itv);
 
-       IVTV_DEBUG_INFO(" Releasing irq\n");
        free_irq(itv->dev->irq, (void *)itv);
        ivtv_iounmap(itv);
 
-       IVTV_DEBUG_INFO(" Releasing mem\n");
        release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
        release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
        if (itv->has_cx23415)
@@ -1322,9 +1366,9 @@ static int module_start(void)
                return -1;
        }
 
-       if (ivtv_debug < 0 || ivtv_debug > 1023) {
+       if (ivtv_debug < 0 || ivtv_debug > 2047) {
                ivtv_debug = 0;
-               printk(KERN_INFO "ivtv:  Debug value must be >= 0 and <= 1023\n");
+               printk(KERN_INFO "ivtv:  Debug value must be >= 0 and <= 2047\n");
        }
 
        if (pci_register_driver(&ivtv_pci_driver)) {
@@ -1341,6 +1385,7 @@ static void module_cleanup(void)
 
        pci_unregister_driver(&ivtv_pci_driver);
 
+       spin_lock(&ivtv_cards_lock);
        for (i = 0; i < ivtv_cards_active; i++) {
                if (ivtv_cards[i] == NULL)
                        continue;
@@ -1349,13 +1394,15 @@ static void module_cleanup(void)
                }
                kfree(ivtv_cards[i]);
        }
+       spin_unlock(&ivtv_cards_lock);
 }
 
-/* Note: These symbols are exported because they are used by the ivtv-fb
+/* Note: These symbols are exported because they are used by the ivtvfb
    framebuffer module and an infrared module for the IR-blaster. */
 EXPORT_SYMBOL(ivtv_set_irq_mask);
 EXPORT_SYMBOL(ivtv_cards_active);
 EXPORT_SYMBOL(ivtv_cards);
+EXPORT_SYMBOL(ivtv_cards_lock);
 EXPORT_SYMBOL(ivtv_api);
 EXPORT_SYMBOL(ivtv_vapi);
 EXPORT_SYMBOL(ivtv_vapi_result);
@@ -1366,6 +1413,7 @@ EXPORT_SYMBOL(ivtv_udma_setup);
 EXPORT_SYMBOL(ivtv_udma_unmap);
 EXPORT_SYMBOL(ivtv_udma_alloc);
 EXPORT_SYMBOL(ivtv_udma_prepare);
+EXPORT_SYMBOL(ivtv_init_on_first_open);
 
 module_init(module_start);
 module_exit(module_cleanup);
index 8abb34a35816917c5af6392beb873020e387dafe..3bda1df63cb62d8c8567bb5690999b60b7f8bfd4 100644 (file)
@@ -38,7 +38,6 @@
 
 #include <linux/version.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <media/tuner.h>
 #include <media/cx2341x.h>
 
-/* #define HAVE_XC3028 1 */
+#include <linux/ivtv.h>
 
-#include <media/ivtv.h>
 
+/* Memory layout */
 #define IVTV_ENCODER_OFFSET    0x00000000
-#define IVTV_ENCODER_SIZE      0x00800000      /* Last half isn't needed 0x01000000 */
-
+#define IVTV_ENCODER_SIZE      0x00800000      /* Total size is 0x01000000, but only first half is used */
 #define IVTV_DECODER_OFFSET    0x01000000
-#define IVTV_DECODER_SIZE      0x00800000      /* Last half isn't needed 0x01000000 */
-
+#define IVTV_DECODER_SIZE      0x00800000      /* Total size is 0x01000000, but only first half is used */
 #define IVTV_REG_OFFSET        0x02000000
 #define IVTV_REG_SIZE          0x00010000
 
-/* Buffers on hardware offsets */
-#define IVTV_YUV_BUFFER_OFFSET    0x001a8600   /* First YUV Buffer */
-#define IVTV_YUV_BUFFER_OFFSET_1  0x00240400   /* Second YUV Buffer */
-#define IVTV_YUV_BUFFER_OFFSET_2  0x002d8200   /* Third YUV Buffer */
-#define IVTV_YUV_BUFFER_OFFSET_3  0x00370000   /* Fourth YUV Buffer */
-#define IVTV_YUV_BUFFER_UV_OFFSET 0x65400      /* Offset to UV Buffer */
-
-/* Offset to filter table in firmware */
-#define IVTV_YUV_HORIZONTAL_FILTER_OFFSET 0x025d8
-#define IVTV_YUV_VERTICAL_FILTER_OFFSET 0x03358
-
-extern const u32 yuv_offset[4];
-
-/* Maximum ivtv driver instances.
-   Based on 6 PVR500s each with two PVR15s...
-   TODO: make this dynamic. I believe it is only a global in order to support
-    ivtv-fb. There must be a better way to do that. */
-#define IVTV_MAX_CARDS 12
-
-/* Supported cards */
-#define IVTV_CARD_PVR_250            0 /* WinTV PVR 250 */
-#define IVTV_CARD_PVR_350            1 /* encoder, decoder, tv-out */
-#define IVTV_CARD_PVR_150            2 /* WinTV PVR 150 and PVR 500 (really just two
-                                          PVR150s on one PCI board) */
-#define IVTV_CARD_M179               3 /* AVerMedia M179 (encoder only) */
-#define IVTV_CARD_MPG600             4 /* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */
-#define IVTV_CARD_MPG160             5 /* Kuroutoshikou ITVC15-STVLP/YUAN MPG160
-                                          cx23415 based, but does not have tv-out */
-#define IVTV_CARD_PG600              6 /* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */
-#define IVTV_CARD_AVC2410            7 /* Adaptec AVC-2410 */
-#define IVTV_CARD_AVC2010            8 /* Adaptec AVD-2010 (No Tuner) */
-#define IVTV_CARD_TG5000TV           9 /* NAGASE TRANSGEAR 5000TV, encoder only */
-#define IVTV_CARD_VA2000MAX_SNT6     10 /* VA2000MAX-STN6 */
-#define IVTV_CARD_CX23416GYC        11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
-#define IVTV_CARD_GV_MVPRX          12 /* I/O Data GV-MVP/RX, RX2, RX2W */
-#define IVTV_CARD_GV_MVPRX2E        13 /* I/O Data GV-MVP/RX2E */
-#define IVTV_CARD_GOTVIEW_PCI_DVD    14        /* GotView PCI DVD */
-#define IVTV_CARD_GOTVIEW_PCI_DVD2   15        /* GotView PCI DVD2 */
-#define IVTV_CARD_YUAN_MPC622        16        /* Yuan MPC622 miniPCI */
-#define IVTV_CARD_DCTMTVP1          17 /* DIGITAL COWBOY DCT-MTVP1 */
-#ifdef HAVE_XC3028
-#define IVTV_CARD_PG600V2           18 /* Yuan PG600V2/GotView PCI DVD Lite/Club3D ZAP-TV1x01 */
-#define IVTV_CARD_LAST                      18
-#else
-#define IVTV_CARD_LAST                      17
-#endif
-
-/* Variants of existing cards but with the same PCI IDs. The driver
-   detects these based on other device information.
-   These cards must always come last.
-   New cards must be inserted above, and the indices of the cards below
-   must be adjusted accordingly. */
-
-/* PVR-350 V1 (uses saa7114) */
-#define IVTV_CARD_PVR_350_V1        (IVTV_CARD_LAST+1)
-/* 2 variants of Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
-#define IVTV_CARD_CX23416GYC_NOGR    (IVTV_CARD_LAST+2)
-#define IVTV_CARD_CX23416GYC_NOGRYCS (IVTV_CARD_LAST+3)
+/* Maximum ivtv driver instances. Some people have a huge number of
+   capture cards, so set this to a high value. */
+#define IVTV_MAX_CARDS 32
 
 #define IVTV_ENC_STREAM_TYPE_MPG  0
 #define IVTV_ENC_STREAM_TYPE_YUV  1
@@ -146,70 +88,8 @@ extern const u32 yuv_offset[4];
 #define IVTV_DEC_STREAM_TYPE_YUV  8
 #define IVTV_MAX_STREAMS         9
 
-#define IVTV_V4L2_DEC_MPG_OFFSET  16   /* offset from 0 to register decoder mpg v4l2 minors on */
-#define IVTV_V4L2_ENC_PCM_OFFSET  24   /* offset from 0 to register pcm v4l2 minors on */
-#define IVTV_V4L2_ENC_YUV_OFFSET  32   /* offset from 0 to register yuv v4l2 minors on */
-#define IVTV_V4L2_DEC_YUV_OFFSET  48   /* offset from 0 to register decoder yuv v4l2 minors on */
-#define IVTV_V4L2_DEC_VBI_OFFSET   8   /* offset from 0 to register decoder vbi input v4l2 minors on */
-#define IVTV_V4L2_DEC_VOUT_OFFSET 16   /* offset from 0 to register vbi output v4l2 minors on */
-
-#define IVTV_ENC_MEM_START 0x00000000
-#define IVTV_DEC_MEM_START 0x01000000
-
-/* system vendor and device IDs */
-#define PCI_VENDOR_ID_ICOMP  0x4444
-#define PCI_DEVICE_ID_IVTV15 0x0803
-#define PCI_DEVICE_ID_IVTV16 0x0016
-
-/* subsystem vendor ID */
-#define IVTV_PCI_ID_HAUPPAUGE          0x0070
-#define IVTV_PCI_ID_HAUPPAUGE_ALT1     0x0270
-#define IVTV_PCI_ID_HAUPPAUGE_ALT2     0x4070
-#define IVTV_PCI_ID_ADAPTEC            0x9005
-#define IVTV_PCI_ID_AVERMEDIA          0x1461
-#define IVTV_PCI_ID_YUAN1              0x12ab
-#define IVTV_PCI_ID_YUAN2              0xff01
-#define IVTV_PCI_ID_YUAN3              0xffab
-#define IVTV_PCI_ID_YUAN4              0xfbab
-#define IVTV_PCI_ID_DIAMONDMM          0xff92
-#define IVTV_PCI_ID_IODATA             0x10fc
-#define IVTV_PCI_ID_MELCO              0x1154
-#define IVTV_PCI_ID_GOTVIEW1           0xffac
-#define IVTV_PCI_ID_GOTVIEW2           0xffad
-
-/* Decoder Buffer hardware size on Chip */
-#define IVTV_DEC_MAX_BUF        0x00100000     /* max bytes in decoder buffer */
-#define IVTV_DEC_MIN_BUF        0x00010000     /* min bytes in dec buffer */
-
-/* ======================================================================== */
-/* ========================== START USER SETTABLE DMA VARIABLES =========== */
-/* ======================================================================== */
-
 #define IVTV_DMA_SG_OSD_ENT    (2883584/PAGE_SIZE)     /* sg entities */
 
-/* DMA Buffers, Default size in MB allocated */
-#define IVTV_DEFAULT_ENC_MPG_BUFFERS 4
-#define IVTV_DEFAULT_ENC_YUV_BUFFERS 2
-#define IVTV_DEFAULT_ENC_VBI_BUFFERS 1
-#define IVTV_DEFAULT_ENC_PCM_BUFFERS 1
-#define IVTV_DEFAULT_DEC_MPG_BUFFERS 1
-#define IVTV_DEFAULT_DEC_YUV_BUFFERS 1
-#define IVTV_DEFAULT_DEC_VBI_BUFFERS 1
-
-/* ======================================================================== */
-/* ========================== END USER SETTABLE DMA VARIABLES ============= */
-/* ======================================================================== */
-
-/* Decoder Status Register */
-#define IVTV_DMA_ERR_LIST      0x00000010
-#define IVTV_DMA_ERR_WRITE     0x00000008
-#define IVTV_DMA_ERR_READ      0x00000004
-#define IVTV_DMA_SUCCESS_WRITE         0x00000002
-#define IVTV_DMA_SUCCESS_READ  0x00000001
-#define IVTV_DMA_READ_ERR      (IVTV_DMA_ERR_LIST | IVTV_DMA_ERR_READ)
-#define IVTV_DMA_WRITE_ERR     (IVTV_DMA_ERR_LIST | IVTV_DMA_ERR_WRITE)
-#define IVTV_DMA_ERR           (IVTV_DMA_ERR_LIST | IVTV_DMA_ERR_WRITE | IVTV_DMA_ERR_READ)
-
 /* DMA Registers */
 #define IVTV_REG_DMAXFER       (0x0000)
 #define IVTV_REG_DMASTATUS     (0x0004)
@@ -232,44 +112,24 @@ extern const u32 yuv_offset[4];
 #define IVTV_REG_VPU                   (0x9058)
 #define IVTV_REG_APU                   (0xA064)
 
-#define IVTV_IRQ_ENC_START_CAP         (0x1 << 31)
-#define IVTV_IRQ_ENC_EOS               (0x1 << 30)
-#define IVTV_IRQ_ENC_VBI_CAP           (0x1 << 29)
-#define IVTV_IRQ_ENC_VIM_RST           (0x1 << 28)
-#define IVTV_IRQ_ENC_DMA_COMPLETE      (0x1 << 27)
-#define IVTV_IRQ_ENC_PIO_COMPLETE      (0x1 << 25)
-#define IVTV_IRQ_DEC_AUD_MODE_CHG      (0x1 << 24)
-#define IVTV_IRQ_DEC_DATA_REQ          (0x1 << 22)
-#define IVTV_IRQ_DEC_DMA_COMPLETE      (0x1 << 20)
-#define IVTV_IRQ_DEC_VBI_RE_INSERT     (0x1 << 19)
-#define IVTV_IRQ_DMA_ERR               (0x1 << 18)
-#define IVTV_IRQ_DMA_WRITE             (0x1 << 17)
-#define IVTV_IRQ_DMA_READ              (0x1 << 16)
-#define IVTV_IRQ_DEC_VSYNC             (0x1 << 10)
-
-/* IRQ Masks */
-#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\
-               IVTV_IRQ_DMA_READ|IVTV_IRQ_ENC_PIO_COMPLETE)
-
-#define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS)
-#define IVTV_IRQ_MASK_DECODE  (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG)
-
 /* i2c stuff */
 #define I2C_CLIENTS_MAX 16
 
 /* debugging */
+extern int ivtv_debug;
 
-#define IVTV_DBGFLG_WARN  (1 << 0)
-#define IVTV_DBGFLG_INFO  (1 << 1)
-#define IVTV_DBGFLG_API   (1 << 2)
-#define IVTV_DBGFLG_DMA   (1 << 3)
-#define IVTV_DBGFLG_IOCTL (1 << 4)
-#define IVTV_DBGFLG_I2C   (1 << 5)
-#define IVTV_DBGFLG_IRQ   (1 << 6)
-#define IVTV_DBGFLG_DEC   (1 << 7)
-#define IVTV_DBGFLG_YUV   (1 << 8)
+#define IVTV_DBGFLG_WARN    (1 << 0)
+#define IVTV_DBGFLG_INFO    (1 << 1)
+#define IVTV_DBGFLG_MB      (1 << 2)
+#define IVTV_DBGFLG_IOCTL   (1 << 3)
+#define IVTV_DBGFLG_FILE    (1 << 4)
+#define IVTV_DBGFLG_DMA     (1 << 5)
+#define IVTV_DBGFLG_IRQ     (1 << 6)
+#define IVTV_DBGFLG_DEC     (1 << 7)
+#define IVTV_DBGFLG_YUV     (1 << 8)
+#define IVTV_DBGFLG_I2C     (1 << 9)
 /* Flag to turn on high volume debugging */
-#define IVTV_DBGFLG_HIGHVOL (1 << 9)
+#define IVTV_DBGFLG_HIGHVOL (1 << 10)
 
 /* NOTE: extra space before comma in 'itv->num , ## args' is required for
    gcc-2.95, otherwise it won't compile. */
@@ -278,58 +138,37 @@ extern const u32 yuv_offset[4];
                if ((x) & ivtv_debug) \
                        printk(KERN_INFO "ivtv%d " type ": " fmt, itv->num , ## args); \
        } while (0)
-#define IVTV_DEBUG_WARN(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_WARN, "warning", fmt , ## args)
-#define IVTV_DEBUG_INFO(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_INFO, "info",fmt , ## args)
-#define IVTV_DEBUG_API(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_API, "api", fmt , ## args)
-#define IVTV_DEBUG_DMA(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
+#define IVTV_DEBUG_WARN(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_WARN,  "warn",  fmt , ## args)
+#define IVTV_DEBUG_INFO(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_INFO,  "info",  fmt , ## args)
+#define IVTV_DEBUG_MB(fmt, args...)    IVTV_DEBUG(IVTV_DBGFLG_MB,    "mb",    fmt , ## args)
+#define IVTV_DEBUG_DMA(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_DMA,   "dma",   fmt , ## args)
 #define IVTV_DEBUG_IOCTL(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define IVTV_DEBUG_I2C(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
-#define IVTV_DEBUG_IRQ(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
-#define IVTV_DEBUG_DEC(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
-#define IVTV_DEBUG_YUV(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
+#define IVTV_DEBUG_FILE(fmt, args...)  IVTV_DEBUG(IVTV_DBGFLG_FILE,  "file",  fmt , ## args)
+#define IVTV_DEBUG_I2C(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_I2C,   "i2c",   fmt , ## args)
+#define IVTV_DEBUG_IRQ(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_IRQ,   "irq",   fmt , ## args)
+#define IVTV_DEBUG_DEC(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_DEC,   "dec",   fmt , ## args)
+#define IVTV_DEBUG_YUV(fmt, args...)   IVTV_DEBUG(IVTV_DBGFLG_YUV,   "yuv",   fmt , ## args)
 
 #define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \
        do { \
                if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \
                        printk(KERN_INFO "ivtv%d " type ": " fmt, itv->num , ## args); \
        } while (0)
-#define IVTV_DEBUG_HI_WARN(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warning", fmt , ## args)
-#define IVTV_DEBUG_HI_INFO(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info",fmt , ## args)
-#define IVTV_DEBUG_HI_API(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_API, "api", fmt , ## args)
-#define IVTV_DEBUG_HI_DMA(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
+#define IVTV_DEBUG_HI_WARN(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN,  "warn",  fmt , ## args)
+#define IVTV_DEBUG_HI_INFO(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO,  "info",  fmt , ## args)
+#define IVTV_DEBUG_HI_MB(fmt, args...)    IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_MB,    "mb",    fmt , ## args)
+#define IVTV_DEBUG_HI_DMA(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DMA,   "dma",   fmt , ## args)
 #define IVTV_DEBUG_HI_IOCTL(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define IVTV_DEBUG_HI_I2C(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
-#define IVTV_DEBUG_HI_IRQ(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
-#define IVTV_DEBUG_HI_DEC(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
-#define IVTV_DEBUG_HI_YUV(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
-
-#define IVTV_FB_DEBUG(x, type, fmt, args...) \
-       do { \
-               if ((x) & ivtv_debug) \
-                       printk(KERN_INFO "ivtv%d-fb " type ": " fmt, itv->num , ## args); \
-       } while (0)
-#define IVTV_FB_DEBUG_WARN(fmt, args...)  IVTV_FB_DEBUG(IVTV_DBGFLG_WARN, "warning", fmt , ## args)
-#define IVTV_FB_DEBUG_INFO(fmt, args...)  IVTV_FB_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args)
-#define IVTV_FB_DEBUG_API(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_API, "api", fmt , ## args)
-#define IVTV_FB_DEBUG_DMA(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_DMA, "dma", fmt , ## args)
-#define IVTV_FB_DEBUG_IOCTL(fmt, args...) IVTV_FB_DEBUG(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args)
-#define IVTV_FB_DEBUG_I2C(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_I2C, "i2c", fmt , ## args)
-#define IVTV_FB_DEBUG_IRQ(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_IRQ, "irq", fmt , ## args)
-#define IVTV_FB_DEBUG_DEC(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args)
-#define IVTV_FB_DEBUG_YUV(fmt, args...)   IVTV_FB_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
+#define IVTV_DEBUG_HI_FILE(fmt, args...)  IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_FILE,  "file",  fmt , ## args)
+#define IVTV_DEBUG_HI_I2C(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_I2C,   "i2c",   fmt , ## args)
+#define IVTV_DEBUG_HI_IRQ(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IRQ,   "irq",   fmt , ## args)
+#define IVTV_DEBUG_HI_DEC(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DEC,   "dec",   fmt , ## args)
+#define IVTV_DEBUG_HI_YUV(fmt, args...)   IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV,   "yuv",   fmt , ## args)
 
 /* Standard kernel messages */
 #define IVTV_ERR(fmt, args...)      printk(KERN_ERR  "ivtv%d: " fmt, itv->num , ## args)
 #define IVTV_WARN(fmt, args...)     printk(KERN_WARNING "ivtv%d: " fmt, itv->num , ## args)
 #define IVTV_INFO(fmt, args...)     printk(KERN_INFO "ivtv%d: " fmt, itv->num , ## args)
-#define IVTV_FB_ERR(fmt, args...)   printk(KERN_ERR  "ivtv%d-fb: " fmt, itv->num , ## args)
-#define IVTV_FB_WARN(fmt, args...)  printk(KERN_WARNING  "ivtv%d-fb: " fmt, itv->num , ## args)
-#define IVTV_FB_INFO(fmt, args...)  printk(KERN_INFO "ivtv%d-fb: " fmt, itv->num , ## args)
-
-/* Values for IVTV_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
-#define MPEG_FRAME_TYPE_IFRAME 1
-#define MPEG_FRAME_TYPE_IFRAME_PFRAME 3
-#define MPEG_FRAME_TYPE_ALL 7
 
 /* output modes (cx23415 only) */
 #define OUT_NONE        0
@@ -340,22 +179,14 @@ extern const u32 yuv_offset[4];
 
 #define IVTV_MAX_PGM_INDEX (400)
 
-extern int ivtv_debug;
-
-
 struct ivtv_options {
-       int megabytes[IVTV_MAX_STREAMS]; /* Size in megabytes of each stream */
-       int cardtype;           /* force card type on load */
-       int tuner;              /* set tuner on load */
-       int radio;              /* enable/disable radio */
-       int newi2c;             /* New I2C algorithm */
+       int kilobytes[IVTV_MAX_STREAMS];        /* size in kilobytes of each stream */
+       int cardtype;                           /* force card type on load */
+       int tuner;                              /* set tuner on load */
+       int radio;                              /* enable/disable radio */
+       int newi2c;                             /* new I2C algorithm */
 };
 
-#define IVTV_MBOX_DMA_START 6
-#define IVTV_MBOX_DMA_END 8
-#define IVTV_MBOX_DMA 9
-#define IVTV_MBOX_FIELD_DISPLAYED 8
-
 /* ivtv-specific mailbox template */
 struct ivtv_mailbox {
        u32 flags;
@@ -379,7 +210,7 @@ struct ivtv_mailbox_data {
 };
 
 /* per-buffer bit flags */
-#define IVTV_F_B_NEED_BUF_SWAP  0      /* this buffer should be byte swapped */
+#define IVTV_F_B_NEED_BUF_SWAP  (1 << 0)       /* this buffer should be byte swapped */
 
 /* per-stream, s_flags */
 #define IVTV_F_S_DMA_PENDING   0       /* this stream has pending DMA */
@@ -400,24 +231,25 @@ struct ivtv_mailbox_data {
 #define IVTV_F_I_DMA              0    /* DMA in progress */
 #define IVTV_F_I_UDMA             1    /* UDMA in progress */
 #define IVTV_F_I_UDMA_PENDING     2    /* UDMA pending */
-#define IVTV_F_I_SPEED_CHANGE     3    /* A speed change is in progress */
-#define IVTV_F_I_EOS              4    /* End of encoder stream reached */
-#define IVTV_F_I_RADIO_USER       5    /* The radio tuner is selected */
-#define IVTV_F_I_DIG_RST          6    /* Reset digitizer */
+#define IVTV_F_I_SPEED_CHANGE     3    /* a speed change is in progress */
+#define IVTV_F_I_EOS              4    /* end of encoder stream reached */
+#define IVTV_F_I_RADIO_USER       5    /* the radio tuner is selected */
+#define IVTV_F_I_DIG_RST          6    /* reset digitizer */
 #define IVTV_F_I_DEC_YUV          7    /* YUV instead of MPG is being decoded */
-#define IVTV_F_I_ENC_VBI          8    /* VBI DMA */
 #define IVTV_F_I_UPDATE_CC        9    /* CC should be updated */
 #define IVTV_F_I_UPDATE_WSS       10   /* WSS should be updated */
 #define IVTV_F_I_UPDATE_VPS       11   /* VPS should be updated */
 #define IVTV_F_I_DECODING_YUV     12   /* this stream is YUV frame decoding */
 #define IVTV_F_I_ENC_PAUSED       13   /* the encoder is paused */
 #define IVTV_F_I_VALID_DEC_TIMINGS 14  /* last_dec_timing is valid */
-#define IVTV_F_I_HAVE_WORK        15   /* Used in the interrupt handler: there is work to be done */
+#define IVTV_F_I_HAVE_WORK        15   /* used in the interrupt handler: there is work to be done */
 #define IVTV_F_I_WORK_HANDLER_VBI  16  /* there is work to be done for VBI */
 #define IVTV_F_I_WORK_HANDLER_YUV  17  /* there is work to be done for YUV */
 #define IVTV_F_I_WORK_HANDLER_PIO  18  /* there is work to be done for PIO */
 #define IVTV_F_I_PIO              19   /* PIO in progress */
 #define IVTV_F_I_DEC_PAUSED       20   /* the decoder is paused */
+#define IVTV_F_I_INITED                   21   /* set after first open */
+#define IVTV_F_I_FAILED                   22   /* set if first open failed */
 
 /* Event notifications */
 #define IVTV_F_I_EV_DEC_STOPPED           28   /* decoder stopped event */
@@ -426,7 +258,7 @@ struct ivtv_mailbox_data {
 #define IVTV_F_I_EV_VSYNC_ENABLED  31  /* VSYNC event enabled */
 
 /* Scatter-Gather array element, used in DMA transfers */
-struct ivtv_SG_element {
+struct ivtv_sg_element {
        u32 src;
        u32 dst;
        u32 size;
@@ -436,9 +268,11 @@ struct ivtv_user_dma {
        struct mutex lock;
        int page_count;
        struct page *map[IVTV_DMA_SG_OSD_ENT];
+       /* Needed when dealing with highmem userspace buffers */
+       struct page *bouncemap[IVTV_DMA_SG_OSD_ENT];
 
        /* Base Dev SG Array for cx23415/6 */
-       struct ivtv_SG_element SGarray[IVTV_DMA_SG_OSD_ENT];
+       struct ivtv_sg_element SGarray[IVTV_DMA_SG_OSD_ENT];
        dma_addr_t SG_handle;
        int SG_length;
 
@@ -458,21 +292,21 @@ struct ivtv_dma_page_info {
 struct ivtv_buffer {
        struct list_head list;
        dma_addr_t dma_handle;
-       unsigned long b_flags;
+       unsigned short b_flags;
+       unsigned short dma_xfer_cnt;
        char *buf;
-
        u32 bytesused;
        u32 readpos;
 };
 
 struct ivtv_queue {
-       struct list_head list;
-       u32 buffers;
-       u32 length;
-       u32 bytesused;
+       struct list_head list;          /* the list of buffers in this queue */
+       u32 buffers;                    /* number of buffers in this queue */
+       u32 length;                     /* total number of bytes of available buffer space */
+       u32 bytesused;                  /* total number of bytes used in this queue */
 };
 
-struct ivtv;   /* forward reference */
+struct ivtv;                           /* forward reference */
 
 struct ivtv_stream {
        /* These first four fields are always set, even if the stream
@@ -483,11 +317,13 @@ struct ivtv_stream {
        int type;                       /* stream type */
 
        u32 id;
-       spinlock_t qlock;       /* locks access to the queues */
-       unsigned long s_flags;  /* status flags, see above */
-       int dma;                /* can be PCI_DMA_TODEVICE,
-                                  PCI_DMA_FROMDEVICE or
-                                  PCI_DMA_NONE */
+       spinlock_t qlock;               /* locks access to the queues */
+       unsigned long s_flags;          /* status flags, see above */
+       int dma;                        /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */
+       u32 pending_offset;
+       u32 pending_backup;
+       u64 pending_pts;
+
        u32 dma_offset;
        u32 dma_backup;
        u64 dma_pts;
@@ -508,47 +344,53 @@ struct ivtv_stream {
        struct ivtv_queue q_dma;        /* waiting for DMA */
        struct ivtv_queue q_predma;     /* waiting for DMA */
 
+       /* DMA xfer counter, buffers belonging to the same DMA
+          xfer will have the same dma_xfer_cnt. */
+       u16 dma_xfer_cnt;
+
        /* Base Dev SG Array for cx23415/6 */
-       struct ivtv_SG_element *SGarray;
-       struct ivtv_SG_element *PIOarray;
-       dma_addr_t SG_handle;
-       int SG_length;
+       struct ivtv_sg_element *sg_pending;
+       struct ivtv_sg_element *sg_processing;
+       struct ivtv_sg_element *sg_dma;
+       dma_addr_t sg_handle;
+       int sg_pending_size;
+       int sg_processing_size;
+       int sg_processed;
 
        /* SG List of Buffers */
        struct scatterlist *SGlist;
 };
 
 struct ivtv_open_id {
-       u32 open_id;
-       int type;
-       enum v4l2_priority prio;
+       u32 open_id;                    /* unique ID for this file descriptor */
+       int type;                       /* stream type */
+       int yuv_frames;                 /* 1: started OUT_UDMA_YUV output mode */
+       enum v4l2_priority prio;        /* priority */
        struct ivtv *itv;
 };
 
-#define IVTV_YUV_UPDATE_HORIZONTAL  0x01
-#define IVTV_YUV_UPDATE_VERTICAL    0x02
-
 struct yuv_frame_info
 {
        u32 update;
-       int src_x;
-       int src_y;
-       unsigned int src_w;
-       unsigned int src_h;
-       int dst_x;
-       int dst_y;
-       unsigned int dst_w;
-       unsigned int dst_h;
-       int pan_x;
-       int pan_y;
+       s32 src_x;
+       s32 src_y;
+       u32 src_w;
+       u32 src_h;
+       s32 dst_x;
+       s32 dst_y;
+       u32 dst_w;
+       u32 dst_h;
+       s32 pan_x;
+       s32 pan_y;
        u32 vis_w;
        u32 vis_h;
        u32 interlaced_y;
        u32 interlaced_uv;
-       int tru_x;
+       s32 tru_x;
        u32 tru_w;
        u32 tru_h;
        u32 offset_y;
+       s32 lace_mode;
 };
 
 #define IVTV_YUV_MODE_INTERLACED       0x00
@@ -621,7 +463,6 @@ struct yuv_playback_info
        int decode_height;
 
        int frame_interlaced;
-       int frame_interlaced_last;
 
        int lace_mode;
        int lace_threshold;
@@ -632,6 +473,11 @@ struct yuv_playback_info
 
        u32 yuv_forced_update;
        int update_frame;
+
+       int sync_field[4];  /* Field to sync on */
+       int field_delay[4]; /* Flag to extend duration of previous frame */
+       u8 fields_lapsed;   /* Counter used when delaying a frame */
+
        struct yuv_frame_info new_frame_info[4];
        struct yuv_frame_info old_frame_info;
        struct yuv_frame_info old_frame_info_args;
@@ -643,37 +489,61 @@ struct yuv_playback_info
 #define IVTV_VBI_FRAMES 32
 
 /* VBI data */
+struct vbi_cc {
+       u8 odd[2];      /* two-byte payload of odd field */
+       u8 even[2];     /* two-byte payload of even field */;
+};
+
+struct vbi_vps {
+       u8 data[5];     /* five-byte VPS payload */
+};
+
 struct vbi_info {
-       u32 dec_start;
-       u32 enc_start, enc_size;
-       int fpi;
-       u32 frame;
-       u32 dma_offset;
-       u8 cc_data_odd[256];
-       u8 cc_data_even[256];
-       int cc_pos;
-       u8 cc_no_update;
-       u8 vps[5];
-       u8 vps_found;
-       int wss;
-       u8 wss_found;
-       u8 wss_no_update;
-       u32 raw_decoder_line_size;
-       u8 raw_decoder_sav_odd_field;
-       u8 raw_decoder_sav_even_field;
-       u32 sliced_decoder_line_size;
-       u8 sliced_decoder_sav_odd_field;
-       u8 sliced_decoder_sav_even_field;
-       struct v4l2_format in;
-       /* convenience pointer to sliced struct in vbi_in union */
-       struct v4l2_sliced_vbi_format *sliced_in;
-       u32 service_set_in;
-       int insert_mpeg;
-
-       /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
-          One for /dev/vbi0 and one for /dev/vbi8 */
-       struct v4l2_sliced_vbi_data sliced_data[36];
-       struct v4l2_sliced_vbi_data sliced_dec_data[36];
+       /* VBI general data, does not change during streaming */
+
+       u32 raw_decoder_line_size;              /* raw VBI line size from digitizer */
+       u8 raw_decoder_sav_odd_field;           /* raw VBI Start Active Video digitizer code of odd field */
+       u8 raw_decoder_sav_even_field;          /* raw VBI Start Active Video digitizer code of even field */
+       u32 sliced_decoder_line_size;           /* sliced VBI line size from digitizer */
+       u8 sliced_decoder_sav_odd_field;        /* sliced VBI Start Active Video digitizer code of odd field */
+       u8 sliced_decoder_sav_even_field;       /* sliced VBI Start Active Video digitizer code of even field */
+
+       u32 start[2];                           /* start of first VBI line in the odd/even fields */
+       u32 count;                              /* number of VBI lines per field */
+       u32 raw_size;                           /* size of raw VBI line from the digitizer */
+       u32 sliced_size;                        /* size of sliced VBI line from the digitizer */
+
+       u32 dec_start;                          /* start in decoder memory of VBI re-insertion buffers */
+       u32 enc_start;                          /* start in encoder memory of VBI capture buffers */
+       u32 enc_size;                           /* size of VBI capture area */
+       int fpi;                                /* number of VBI frames per interrupt */
+
+       struct v4l2_format in;                  /* current VBI capture format */
+       struct v4l2_sliced_vbi_format *sliced_in; /* convenience pointer to sliced struct in vbi.in union */
+       int insert_mpeg;                        /* if non-zero, then embed VBI data in MPEG stream */
+
+       /* Raw VBI compatibility hack */
+
+       u32 frame;                              /* frame counter hack needed for backwards compatibility
+                                                  of old VBI software */
+
+       /* Sliced VBI output data */
+
+       struct vbi_cc cc_payload[256];          /* sliced VBI CC payload array: it is an array to
+                                                  prevent dropping CC data if they couldn't be
+                                                  processed fast enough */
+       int cc_payload_idx;                     /* index in cc_payload */
+       u8 cc_missing_cnt;                      /* counts number of frames without CC for passthrough mode */
+       int wss_payload;                        /* sliced VBI WSS payload */
+       u8 wss_missing_cnt;                     /* counts number of frames without WSS for passthrough mode */
+       struct vbi_vps vps_payload;             /* sliced VBI VPS payload */
+
+       /* Sliced VBI capture data */
+
+       struct v4l2_sliced_vbi_data sliced_data[36];    /* sliced VBI storage for VBI encoder stream */
+       struct v4l2_sliced_vbi_data sliced_dec_data[36];/* sliced VBI storage for VBI decoder stream */
+
+       /* VBI Embedding data */
 
        /* Buffer for VBI data inserted into MPEG stream.
           The first byte is a dummy byte that's never used.
@@ -690,12 +560,9 @@ struct vbi_info {
           This pointer array will allocate 2049 bytes to store each VBI frame. */
        u8 *sliced_mpeg_data[IVTV_VBI_FRAMES];
        u32 sliced_mpeg_size[IVTV_VBI_FRAMES];
-       struct ivtv_buffer sliced_mpeg_buf;
-       u32 inserted_frame;
-
-       u32 start[2], count;
-       u32 raw_size;
-       u32 sliced_size;
+       struct ivtv_buffer sliced_mpeg_buf;     /* temporary buffer holding data from sliced_mpeg_data */
+       u32 inserted_frame;                     /* index in sliced_mpeg_size of next sliced data
+                                                  to be inserted in the MPEG stream */
 };
 
 /* forward declaration of struct defined in ivtv-cards.h */
@@ -703,131 +570,132 @@ struct ivtv_card;
 
 /* Struct to hold info about ivtv cards */
 struct ivtv {
-       int num;                /* board number, -1 during init! */
-       char name[8];           /* board name for printk and interrupts (e.g. 'ivtv0') */
-       struct pci_dev *dev;    /* PCI device */
+       /* General fixed card data */
+       int num;                        /* board number, -1 during init! */
+       char name[8];                   /* board name for printk and interrupts (e.g. 'ivtv0') */
+       struct pci_dev *dev;            /* PCI device */
        const struct ivtv_card *card;   /* card information */
-       const char *card_name;  /* full name of the card */
-       u8 has_cx23415;         /* 1 if it is a cx23415 based card, 0 for cx23416 */
-       u8 is_50hz;
-       u8 is_60hz;
-       u8 is_out_50hz;
-       u8 is_out_60hz;
-       u8 pvr150_workaround;   /* 1 if the cx25840 needs to workaround a PVR150 bug */
-       u8 nof_inputs;          /* number of video inputs */
-       u8 nof_audio_inputs;    /* number of audio inputs */
-       u32 v4l2_cap;           /* V4L2 capabilities of card */
-       u32 hw_flags;           /* Hardware description of the board */
-
-       /* controlling Video decoder function */
+       const char *card_name;          /* full name of the card */
+       u8 has_cx23415;                 /* 1 if it is a cx23415 based card, 0 for cx23416 */
+       u8 pvr150_workaround;           /* 1 if the cx25840 needs to workaround a PVR150 bug */
+       u8 nof_inputs;                  /* number of video inputs */
+       u8 nof_audio_inputs;            /* number of audio inputs */
+       u32 v4l2_cap;                   /* V4L2 capabilities of card */
+       u32 hw_flags;                   /* hardware description of the board */
+       int tunerid;                    /* userspace tuner ID for experimental Xceive tuner support */
+       v4l2_std_id tuner_std;          /* the norm of the card's tuner (fixed) */
+                                       /* controlling video decoder function */
        int (*video_dec_func)(struct ivtv *, unsigned int, void *);
+       u32 base_addr;                  /* PCI resource base address */
+       volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */
+       volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */
+       volatile void __iomem *reg_mem; /* pointer to mapped registers */
+       struct ivtv_options options;    /* user options */
+
+
+       /* High-level state info */
+       unsigned long i_flags;          /* global ivtv flags */
+       u8 is_50hz;                     /* 1 if the current capture standard is 50 Hz */
+       u8 is_60hz                      /* 1 if the current capture standard is 60 Hz */;
+       u8 is_out_50hz                  /* 1 if the current TV output standard is 50 Hz */;
+       u8 is_out_60hz                  /* 1 if the current TV output standard is 60 Hz */;
+       int output_mode;                /* decoder output mode: NONE, MPG, YUV, UDMA YUV, passthrough */
+       u32 audio_input;                /* current audio input */
+       u32 active_input;               /* current video input */
+       u32 active_output;              /* current video output */
+       v4l2_std_id std;                /* current capture TV standard */
+       v4l2_std_id std_out;            /* current TV output standard */
+       u8 audio_stereo_mode;           /* decoder setting how to handle stereo MPEG audio */
+       u8 audio_bilingual_mode;        /* decoder setting how to handle bilingual MPEG audio */
+       struct cx2341x_mpeg_params params;              /* current encoder parameters */
+
+
+       /* Locking */
+       spinlock_t lock;                /* lock access to this struct */
+       struct mutex serialize_lock;    /* mutex used to serialize open/close/start/stop/ioctl operations */
+
+
+       /* Streams */
+       int stream_buf_size[IVTV_MAX_STREAMS];          /* stream buffer size */
+       struct ivtv_stream streams[IVTV_MAX_STREAMS];   /* stream data */
+       atomic_t capturing;             /* count number of active capture streams */
+       atomic_t decoding;              /* count number of active decoding streams */
+
+
+       /* Interrupts & DMA */
+       u32 irqmask;                    /* active interrupts */
+       u32 irq_rr_idx;                 /* round-robin stream index */
+       struct workqueue_struct *irq_work_queues;       /* workqueue for PIO/YUV/VBI actions */
+       struct work_struct irq_work_queue;              /* work entry */
+       spinlock_t dma_reg_lock;        /* lock access to DMA engine registers */
+       int cur_dma_stream;             /* index of current stream doing DMA (-1 if none) */
+       int cur_pio_stream;             /* index of current stream doing PIO (-1 if none) */
+       u32 dma_data_req_offset;        /* store offset in decoder memory of current DMA request */
+       u32 dma_data_req_size;          /* store size of current DMA request */
+       int dma_retries;                /* current DMA retry attempt */
+       struct ivtv_user_dma udma;      /* user based DMA for OSD */
+       struct timer_list dma_timer;    /* timer used to catch unfinished DMAs */
+       u32 last_vsync_field;           /* last seen vsync field */
+       wait_queue_head_t dma_waitq;    /* wake up when the current DMA is finished */
+       wait_queue_head_t eos_waitq;    /* wake up when EOS arrives */
+       wait_queue_head_t event_waitq;  /* wake up when the next decoder event arrives */
+       wait_queue_head_t vsync_waitq;  /* wake up when the next decoder vsync arrives */
+
+
+       /* Mailbox */
+       struct ivtv_mailbox_data enc_mbox;              /* encoder mailboxes */
+       struct ivtv_mailbox_data dec_mbox;              /* decoder mailboxes */
+       struct ivtv_api_cache api_cache[256];           /* cached API commands */
+
+
+       /* I2C */
+       struct i2c_adapter i2c_adap;
+       struct i2c_algo_bit_data i2c_algo;
+       struct i2c_client i2c_client;
+       struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];/* pointers to all I2C clients */
+       int i2c_state;                  /* i2c bit state */
+       struct mutex i2c_bus_lock;      /* lock i2c bus */
+
+
+       /* Program Index information */
+       u32 pgm_info_offset;            /* start of pgm info in encoder memory */
+       u32 pgm_info_num;               /* number of elements in the pgm cyclic buffer in encoder memory */
+       u32 pgm_info_write_idx;         /* last index written by the card that was transferred to pgm_info[] */
+       u32 pgm_info_read_idx;          /* last index in pgm_info read by the application */
+       struct v4l2_enc_idx_entry pgm_info[IVTV_MAX_PGM_INDEX]; /* filled from the pgm cyclic buffer on the card */
+
+
+       /* Miscellaneous */
+       u32 open_id;                    /* incremented each time an open occurs, is >= 1 */
+       struct v4l2_prio_state prio;    /* priority state */
+       int search_pack_header;         /* 1 if ivtv_copy_buf_to_user() is scanning for a pack header (0xba) */
+       int speed;                      /* current playback speed setting */
+       u8 speed_mute_audio;            /* 1 if audio should be muted when fast forward */
+       u64 mpg_data_received;          /* number of bytes received from the MPEG stream */
+       u64 vbi_data_inserted;          /* number of VBI bytes inserted into the MPEG stream */
+       u32 last_dec_timing[3];         /* cache last retrieved pts/scr/frame values */
+       unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */
+       u16 dualwatch_stereo_mode;      /* current detected dualwatch stereo mode */
+
+
+       /* VBI state info */
+       struct vbi_info vbi;            /* VBI-specific data */
+
+
+       /* YUV playback */
+       struct yuv_playback_info yuv_info;              /* YUV playback data */
 
-       struct ivtv_options options;    /* User options */
-       int stream_buf_size[IVTV_MAX_STREAMS]; /* Stream buffer size */
-       struct ivtv_stream streams[IVTV_MAX_STREAMS];   /* Stream data */
-       int speed;
-       u8 speed_mute_audio;
-       unsigned long i_flags;  /* global ivtv flags */
-       atomic_t capturing;     /* count number of active capture streams */
-       atomic_t decoding;      /* count number of active decoding streams */
-       u32 irq_rr_idx; /* Round-robin stream index */
-       int cur_dma_stream;     /* index of stream doing DMA */
-       int cur_pio_stream;     /* index of stream doing PIO */
-       u32 dma_data_req_offset;
-       u32 dma_data_req_size;
-       int output_mode;        /* NONE, MPG, YUV, UDMA YUV, passthrough */
-       spinlock_t lock;        /* lock access to this struct */
-       int search_pack_header;
-
-       spinlock_t dma_reg_lock; /* lock access to DMA engine registers */
-       struct mutex serialize_lock;  /* lock used to serialize starting streams */
-
-       /* User based DMA for OSD */
-       struct ivtv_user_dma udma;
-
-       int open_id;            /* incremented each time an open occurs, used as unique ID.
-                                  starts at 1, so 0 can be used as uninitialized value
-                                  in the stream->id. */
-
-       u32 base_addr;
-       u32 irqmask;
-
-       struct v4l2_prio_state prio;
-       struct workqueue_struct *irq_work_queues;
-       struct work_struct irq_work_queue;
-       struct timer_list dma_timer; /* Timer used to catch unfinished DMAs */
-
-       struct vbi_info vbi;
-
-       struct ivtv_mailbox_data enc_mbox;
-       struct ivtv_mailbox_data dec_mbox;
-       struct ivtv_api_cache api_cache[256];   /* Cached API Commands */
-
-       u8 card_rev;
-       volatile void __iomem *enc_mem, *dec_mem, *reg_mem;
-
-       u32 pgm_info_offset;
-       u32 pgm_info_num;
-       u32 pgm_info_write_idx;
-       u32 pgm_info_read_idx;
-       struct v4l2_enc_idx_entry pgm_info[IVTV_MAX_PGM_INDEX];
-
-       u64 mpg_data_received;
-       u64 vbi_data_inserted;
-
-       wait_queue_head_t cap_w;
-       /* when the next decoder event arrives this queue is woken up */
-       wait_queue_head_t event_waitq;
-       /* when the next decoder vsync arrives this queue is woken up */
-       wait_queue_head_t vsync_waitq;
-       /* when the current DMA is finished this queue is woken up */
-       wait_queue_head_t dma_waitq;
 
        /* OSD support */
        unsigned long osd_video_pbase;
-       int osd_global_alpha_state; /* 0=off : 1=on */
-       int osd_local_alpha_state;  /* 0=off : 1=on */
-       int osd_color_key_state;    /* 0=off : 1=on */
-       u8  osd_global_alpha;       /* Current global alpha */
-       u32 osd_color_key;          /* Current color key */
-       u32 osd_pixelformat;        /* Current pixel format */
-       struct v4l2_rect osd_rect;  /* Current OSD position and size */
-       struct v4l2_rect main_rect; /* Current Main window position and size */
-
-       u32 last_dec_timing[3];     /* Store last retrieved pts/scr/frame values */
-
-       /* i2c */
-       struct i2c_adapter i2c_adap;
-       struct i2c_algo_bit_data i2c_algo;
-       struct i2c_client i2c_client;
-       struct mutex i2c_bus_lock;
-       int i2c_state;
-       struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
-
-       /* v4l2 and User settings */
-
-       /* codec settings */
-       struct cx2341x_mpeg_params params;
-       u32 audio_input;
-       u32 active_input;
-       u32 active_output;
-       v4l2_std_id std;
-       v4l2_std_id std_out;
-       v4l2_std_id tuner_std;  /* The norm of the tuner (fixed) */
-       u8 audio_stereo_mode;
-       u8 audio_bilingual_mode;
-
-       /* dualwatch */
-       unsigned long dualwatch_jiffies;
-       u16 dualwatch_stereo_mode;
-
-       /* Digitizer type */
-       int digitizer;          /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */
-
-       u32 lastVsyncFrame;
-
-       struct yuv_playback_info yuv_info;
-       struct osd_info *osd_info;
+       int osd_global_alpha_state;     /* 1 = global alpha is on */
+       int osd_local_alpha_state;      /* 1 = local alpha is on */
+       int osd_chroma_key_state;       /* 1 = chroma-keying is on */
+       u8  osd_global_alpha;           /* current global alpha */
+       u32 osd_chroma_key;             /* current chroma key */
+       struct v4l2_rect osd_rect;      /* current OSD position and size */
+       struct v4l2_rect main_rect;     /* current Main window position and size */
+       struct osd_info *osd_info;      /* ivtvfb private OSD info */
 };
 
 /* Globals */
@@ -858,6 +726,9 @@ int ivtv_waitq(wait_queue_head_t *waitq);
 struct tveeprom; /* forward reference */
 void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv);
 
+/* First-open initialization: load firmware, init cx25840, etc. */
+int ivtv_init_on_first_open(struct ivtv *itv);
+
 /* This is a PCI post thing, where if the pci register is not read, then
    the write doesn't always take effect right away. By reading back the
    register any pending PCI writes will be performed (in order), and so
@@ -885,4 +756,4 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv);
 #define write_dec_sync(val, addr) \
        do { write_dec(val, addr); read_dec(addr); } while (0)
 
-#endif /* IVTV_DRIVER_H */
+#endif
index 66ea3cbc369c209f2ae4cc52d03253479f16052b..da50fa4a72a50411a0cbb3906c070c28d0c55bbf 100644 (file)
 #include "ivtv-irq.h"
 #include "ivtv-vbi.h"
 #include "ivtv-mailbox.h"
-#include "ivtv-audio.h"
+#include "ivtv-routing.h"
 #include "ivtv-streams.h"
 #include "ivtv-yuv.h"
-#include "ivtv-controls.h"
 #include "ivtv-ioctl.h"
 #include "ivtv-cards.h"
 #include <media/saa7115.h>
@@ -247,8 +246,9 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block,
                /* do we have new data? */
                buf = ivtv_dequeue(s, &s->q_full);
                if (buf) {
-                       if (!test_and_clear_bit(IVTV_F_B_NEED_BUF_SWAP, &buf->b_flags))
+                       if ((buf->b_flags & IVTV_F_B_NEED_BUF_SWAP) == 0)
                                return buf;
+                       buf->b_flags &= ~IVTV_F_B_NEED_BUF_SWAP;
                        if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
                                /* byteswap MPG data */
                                ivtv_buf_swap(buf);
@@ -258,19 +258,19 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block,
                        }
                        return buf;
                }
-               /* return if file was opened with O_NONBLOCK */
-               if (non_block) {
-                       *err = -EAGAIN;
-                       return NULL;
-               }
 
                /* return if end of stream */
                if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
-                       clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
                        IVTV_DEBUG_INFO("EOS %s\n", s->name);
                        return NULL;
                }
 
+               /* return if file was opened with O_NONBLOCK */
+               if (non_block) {
+                       *err = -EAGAIN;
+                       return NULL;
+               }
+
                /* wait for more data to arrive */
                prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
                /* New buffers might have become available before we were added to the waitqueue */
@@ -378,10 +378,20 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co
                int rc;
 
                buf = ivtv_get_buffer(s, non_block, &rc);
-               if (buf == NULL && rc == -EAGAIN && tot_written)
-                       break;
-               if (buf == NULL)
+               /* if there is no data available... */
+               if (buf == NULL) {
+                       /* if we got data, then return that regardless */
+                       if (tot_written)
+                               break;
+                       /* EOS condition */
+                       if (rc == 0) {
+                               clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
+                               clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
+                               ivtv_release_stream(s);
+                       }
+                       /* set errno */
                        return rc;
+               }
                rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written);
                if (buf != &itv->vbi.sliced_mpeg_buf) {
                        ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? &s->q_free : &s->q_io);
@@ -408,7 +418,7 @@ static ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t co
        ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0;
        struct ivtv *itv = s->itv;
 
-       IVTV_DEBUG_HI_INFO("read %zd from %s, got %zd\n", count, s->name, rc);
+       IVTV_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc);
        if (rc > 0)
                pos += rc;
        return rc;
@@ -499,9 +509,11 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_
        struct ivtv_stream *s = &itv->streams[id->type];
        int rc;
 
-       IVTV_DEBUG_HI_IOCTL("read %zd bytes from %s\n", count, s->name);
+       IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
 
+       mutex_lock(&itv->serialize_lock);
        rc = ivtv_start_capture(id);
+       mutex_unlock(&itv->serialize_lock);
        if (rc)
                return rc;
        return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
@@ -537,7 +549,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
        int rc;
        DEFINE_WAIT(wait);
 
-       IVTV_DEBUG_HI_IOCTL("write %zd bytes to %s\n", count, s->name);
+       IVTV_DEBUG_HI_FILE("write %zd bytes to %s\n", count, s->name);
 
        if (s->type != IVTV_DEC_STREAM_TYPE_MPG &&
            s->type != IVTV_DEC_STREAM_TYPE_YUV &&
@@ -551,8 +563,11 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
 
        /* This stream does not need to start any decoding */
        if (s->type == IVTV_DEC_STREAM_TYPE_VOUT) {
+               int elems = count / sizeof(struct v4l2_sliced_vbi_data);
+
                set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
-               return ivtv_write_vbi(itv, user_buf, count);
+               ivtv_write_vbi(itv, (const struct v4l2_sliced_vbi_data *)user_buf, elems);
+               return elems * sizeof(struct v4l2_sliced_vbi_data);
        }
 
        mode = s->type == IVTV_DEC_STREAM_TYPE_MPG ? OUT_MPG : OUT_YUV;
@@ -612,7 +627,9 @@ retry:
        }
 
        /* Start decoder (returns 0 if already started) */
+       mutex_lock(&itv->serialize_lock);
        rc = ivtv_start_decoding(id, itv->speed);
+       mutex_unlock(&itv->serialize_lock);
        if (rc) {
                IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
 
@@ -645,7 +662,7 @@ retry:
           to transfer the rest. */
        if (count && !(filp->f_flags & O_NONBLOCK))
                goto retry;
-       IVTV_DEBUG_HI_INFO("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);
+       IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);
        return bytes_written;
 }
 
@@ -657,6 +674,7 @@ unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait)
        int res = 0;
 
        /* add stream's waitq to the poll list */
+       IVTV_DEBUG_HI_FILE("Decoder poll\n");
        poll_wait(filp, &s->waitq, wait);
 
        set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
@@ -679,16 +697,21 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
 
        /* Start a capture if there is none */
        if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
-               int rc = ivtv_start_capture(id);
+               int rc;
 
+               mutex_lock(&itv->serialize_lock);
+               rc = ivtv_start_capture(id);
+               mutex_unlock(&itv->serialize_lock);
                if (rc) {
                        IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n",
                                        s->name, rc);
                        return POLLERR;
                }
+               IVTV_DEBUG_FILE("Encoder poll started capture\n");
        }
 
        /* add stream's waitq to the poll list */
+       IVTV_DEBUG_HI_FILE("Encoder poll\n");
        poll_wait(filp, &s->waitq, wait);
 
        if (eof || s->q_full.length)
@@ -701,7 +724,7 @@ void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)
        struct ivtv *itv = id->itv;
        struct ivtv_stream *s = &itv->streams[id->type];
 
-       IVTV_DEBUG_IOCTL("close() of %s\n", s->name);
+       IVTV_DEBUG_FILE("close() of %s\n", s->name);
 
        /* 'Unclaim' this stream */
 
@@ -728,10 +751,11 @@ void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)
                        ivtv_stop_v4l2_encode_stream(s, gop_end);
                }
        }
-       clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
-       clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
-
-       ivtv_release_stream(s);
+       if (!gop_end) {
+               clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
+               clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
+               ivtv_release_stream(s);
+       }
 }
 
 static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
@@ -739,13 +763,14 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
        struct ivtv *itv = id->itv;
        struct ivtv_stream *s = &itv->streams[id->type];
 
-       IVTV_DEBUG_IOCTL("close() of %s\n", s->name);
+       IVTV_DEBUG_FILE("close() of %s\n", s->name);
 
        /* Stop decoding */
        if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
                IVTV_DEBUG_INFO("close stopping decode\n");
 
                ivtv_stop_v4l2_decode_stream(s, flags, pts);
+               itv->output_mode = OUT_NONE;
        }
        clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
        clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
@@ -753,11 +778,7 @@ static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts)
                /* Restore registers we've changed & clean up any mess we've made */
                ivtv_yuv_close(itv);
        }
-       if (s->type == IVTV_DEC_STREAM_TYPE_YUV && itv->output_mode == OUT_YUV)
-               itv->output_mode = OUT_NONE;
-       else if (s->type == IVTV_DEC_STREAM_TYPE_YUV && itv->output_mode == OUT_UDMA_YUV)
-               itv->output_mode = OUT_NONE;
-       else if (s->type == IVTV_DEC_STREAM_TYPE_MPG && itv->output_mode == OUT_MPG)
+       if (itv->output_mode == OUT_UDMA_YUV && id->yuv_frames)
                itv->output_mode = OUT_NONE;
 
        itv->speed = 0;
@@ -771,7 +792,7 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
        struct ivtv *itv = id->itv;
        struct ivtv_stream *s = &itv->streams[id->type];
 
-       IVTV_DEBUG_IOCTL("close() of %s\n", s->name);
+       IVTV_DEBUG_FILE("close %s\n", s->name);
 
        v4l2_prio_close(&itv->prio, &id->prio);
 
@@ -784,6 +805,7 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
        /* 'Unclaim' this stream */
 
        /* Stop radio */
+       mutex_lock(&itv->serialize_lock);
        if (id->type == IVTV_ENC_STREAM_TYPE_RAD) {
                /* Closing radio device, return to TV mode */
                ivtv_mute(itv);
@@ -809,56 +831,35 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
                ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
 
                /* If all output streams are closed, and if the user doesn't have
-                  IVTV_DEC_STREAM_TYPE_VOUT open, then disable VBI on TV-out. */
+                  IVTV_DEC_STREAM_TYPE_VOUT open, then disable CC on TV-out. */
                if (itv->output_mode == OUT_NONE && !test_bit(IVTV_F_S_APPL_IO, &s_vout->s_flags)) {
-                       /* disable VBI on TV-out */
-                       ivtv_disable_vbi(itv);
+                       /* disable CC on TV-out */
+                       ivtv_disable_cc(itv);
                }
        } else {
                ivtv_stop_capture(id, 0);
        }
        kfree(id);
+       mutex_unlock(&itv->serialize_lock);
        return 0;
 }
 
-int ivtv_v4l2_open(struct inode *inode, struct file *filp)
+static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
 {
-       int x, y = 0;
+       struct ivtv *itv = s->itv;
        struct ivtv_open_id *item;
-       struct ivtv *itv = NULL;
-       struct ivtv_stream *s = NULL;
-       int minor = iminor(inode);
-
-       /* Find which card this open was on */
-       spin_lock(&ivtv_cards_lock);
-       for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
-               /* find out which stream this open was on */
-               for (y = 0; y < IVTV_MAX_STREAMS; y++) {
-                       s = &ivtv_cards[x]->streams[y];
-                       if (s->v4l2dev && s->v4l2dev->minor == minor) {
-                               itv = ivtv_cards[x];
-                               break;
-                       }
-               }
-       }
-       spin_unlock(&ivtv_cards_lock);
 
-       if (itv == NULL) {
-               /* Couldn't find a device registered
-                  on that minor, shouldn't happen! */
-               printk(KERN_WARNING "ivtv:  No ivtv device found on minor %d\n", minor);
-               return -ENXIO;
-       }
+       IVTV_DEBUG_FILE("open %s\n", s->name);
 
-       if (y == IVTV_DEC_STREAM_TYPE_MPG &&
+       if (s->type == IVTV_DEC_STREAM_TYPE_MPG &&
                test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags))
                return -EBUSY;
 
-       if (y == IVTV_DEC_STREAM_TYPE_YUV &&
+       if (s->type == IVTV_DEC_STREAM_TYPE_YUV &&
                test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags))
                return -EBUSY;
 
-       if (y == IVTV_DEC_STREAM_TYPE_YUV) {
+       if (s->type == IVTV_DEC_STREAM_TYPE_YUV) {
                if (read_reg(0x82c) == 0) {
                        IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n");
                        /* return -ENODEV; */
@@ -873,7 +874,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
                return -ENOMEM;
        }
        item->itv = itv;
-       item->type = y;
+       item->type = s->type;
        v4l2_prio_open(&itv->prio, &item->prio);
 
        item->open_id = itv->open_id++;
@@ -887,12 +888,20 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
                        return -EBUSY;
                }
 
+               if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
+                       if (atomic_read(&itv->capturing) > 0) {
+                               /* switching to radio while capture is
+                                  in progress is not polite */
+                               kfree(item);
+                               return -EBUSY;
+                       }
+               }
+               /* Mark that the radio is being used. */
+               set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
                /* We have the radio */
                ivtv_mute(itv);
                /* Switch tuner to radio */
                ivtv_call_i2c_clients(itv, AUDC_SET_RADIO, NULL);
-               /* Mark that the radio is being used. */
-               set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
                /* Select the correct audio input (i.e. radio tuner) */
                ivtv_audio_set_io(itv);
                if (itv->hw_flags & IVTV_HW_SAA711X)
@@ -907,45 +916,65 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
        }
 
        /* YUV or MPG Decoding Mode? */
-       if (y == IVTV_DEC_STREAM_TYPE_MPG)
+       if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
                clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
-       else if (y == IVTV_DEC_STREAM_TYPE_YUV)
-       {
+       else if (s->type == IVTV_DEC_STREAM_TYPE_YUV)
                set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags);
-       }
-
        return 0;
 }
 
-void ivtv_mute(struct ivtv *itv)
+int ivtv_v4l2_open(struct inode *inode, struct file *filp)
 {
-       struct v4l2_control ctrl = { V4L2_CID_AUDIO_MUTE, 1 };
+       int res, x, y = 0;
+       struct ivtv *itv = NULL;
+       struct ivtv_stream *s = NULL;
+       int minor = iminor(inode);
+
+       /* Find which card this open was on */
+       spin_lock(&ivtv_cards_lock);
+       for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
+               /* find out which stream this open was on */
+               for (y = 0; y < IVTV_MAX_STREAMS; y++) {
+                       s = &ivtv_cards[x]->streams[y];
+                       if (s->v4l2dev && s->v4l2dev->minor == minor) {
+                               itv = ivtv_cards[x];
+                               break;
+                       }
+               }
+       }
+       spin_unlock(&ivtv_cards_lock);
+
+       if (itv == NULL) {
+               /* Couldn't find a device registered
+                  on that minor, shouldn't happen! */
+               IVTV_WARN("No ivtv device found on minor %d\n", minor);
+               return -ENXIO;
+       }
 
-       /* Mute sound to avoid pop */
-       ivtv_control_ioctls(itv, VIDIOC_S_CTRL, &ctrl);
+       mutex_lock(&itv->serialize_lock);
+       if (ivtv_init_on_first_open(itv)) {
+               IVTV_ERR("Failed to initialize on minor %d\n", minor);
+               mutex_unlock(&itv->serialize_lock);
+               return -ENXIO;
+       }
+       res = ivtv_serialized_open(s, filp);
+       mutex_unlock(&itv->serialize_lock);
+       return res;
+}
 
+void ivtv_mute(struct ivtv *itv)
+{
        if (atomic_read(&itv->capturing))
                ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 1);
-
        IVTV_DEBUG_INFO("Mute\n");
 }
 
 void ivtv_unmute(struct ivtv *itv)
 {
-       struct v4l2_control ctrl = { V4L2_CID_AUDIO_MUTE, 0 };
-
-       /* initialize or refresh input */
-       if (atomic_read(&itv->capturing) == 0)
-               ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
-
-       ivtv_msleep_timeout(100, 0);
-
        if (atomic_read(&itv->capturing)) {
+               ivtv_msleep_timeout(100, 0);
                ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
                ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0);
        }
-
-       /* Unmute */
-       ivtv_control_ioctls(itv, VIDIOC_S_CTRL, &ctrl);
        IVTV_DEBUG_INFO("Unmute\n");
 }
index 74a1745fabbcaa7acc28431ccdb0c0c69219999c..2c8d5186c9c3cca56f09021a633066f473674cbf 100644 (file)
@@ -18,6 +18,9 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_FILEOPS_H
+#define IVTV_FILEOPS_H
+
 /* Testing/Debugging */
 int ivtv_v4l2_open(struct inode *inode, struct file *filp);
 ssize_t ivtv_v4l2_read(struct file *filp, char __user *buf, size_t count,
@@ -42,3 +45,5 @@ int ivtv_claim_stream(struct ivtv_open_id *id, int type);
 
 /* Release a previously claimed stream. */
 void ivtv_release_stream(struct ivtv_stream *s);
+
+#endif
index 8b2ffe658905beff5205c05fba6156e23895a983..041ba94e65bc46aad55d007f6632ea34444ae85e 100644 (file)
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_FIRMWARE_H
+#define IVTV_FIRMWARE_H
+
 int ivtv_firmware_init(struct ivtv *itv);
 void ivtv_firmware_versions(struct ivtv *itv);
 void ivtv_halt_firmware(struct ivtv *itv);
 void ivtv_init_mpeg_decoder(struct ivtv *itv);
+
+#endif
index 6a5a7aa6697621648bad6d7f019d0062cd385e64..132fb5f713663769df3a99642c91078c5dcfc02b 100644 (file)
@@ -122,30 +122,6 @@ void ivtv_reset_ir_gpio(struct ivtv *itv)
        write_reg(curdir, IVTV_REG_GPIO_DIR);
 }
 
-#ifdef HAVE_XC3028
-int ivtv_reset_tuner_gpio(enum v4l2_tuner_type mode, void *priv, int ptr)
-{
-       int curdir, curout;
-       struct ivtv *itv = (struct ivtv *) priv;
-
-       if (itv->card->type != IVTV_CARD_PG600V2 || itv->options.tuner != TUNER_XCEIVE_XC3028)
-               return -EINVAL;
-       IVTV_INFO("Resetting tuner\n");
-       curout = read_reg(IVTV_REG_GPIO_OUT);
-       curdir = read_reg(IVTV_REG_GPIO_DIR);
-       curdir |= (1 << 12);  /* GPIO bit 12 */
-
-       curout &= ~(1 << 12);
-       write_reg(curout, IVTV_REG_GPIO_OUT);
-       schedule_timeout_interruptible(msecs_to_jiffies(1));
-
-       curout |= (1 << 12);
-       write_reg(curout, IVTV_REG_GPIO_OUT);
-       schedule_timeout_interruptible(msecs_to_jiffies(1));
-
-       return 0;
-}
-#endif
 
 void ivtv_gpio_init(struct ivtv *itv)
 {
index c301d2a393464fd73f5f404535212e768c22360f..964a265d91a9c27c4cf0f54238ec122104210aaa 100644 (file)
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_GPIO_H
+#define IVTV_GPIO_H
+
 /* GPIO stuff */
 void ivtv_gpio_init(struct ivtv *itv);
 void ivtv_reset_ir_gpio(struct ivtv *itv);
-int ivtv_reset_tuner_gpio(enum v4l2_tuner_type mode, void *priv, int ptr);
+int ivtv_reset_tuner_gpio(void *dev, int cmd, int value);
 int ivtv_gpio(struct ivtv *itv, unsigned int command, void *arg);
+
+#endif
index b3557435456db70d0cf170cb942f70c81a72f28a..285fca676a69a7cd77c68da68ca78bea868dbd97 100644 (file)
@@ -109,6 +109,7 @@ static const u8 hw_driverids[] = {
        I2C_DRIVERID_UPD64083,
        I2C_DRIVERID_SAA717X,
        I2C_DRIVERID_WM8739,
+       I2C_DRIVERID_VP27SMPX,
        0               /* IVTV_HW_GPIO dummy driver ID */
 };
 
@@ -128,6 +129,7 @@ static const char * const hw_drivernames[] = {
        "upd64083",
        "saa717x",
        "wm8739",
+       "vp27smpx",
        "gpio",
 };
 
@@ -534,14 +536,13 @@ static struct i2c_adapter ivtv_i2c_adap_template = {
 #endif
 };
 
-static struct i2c_algo_bit_data ivtv_i2c_algo_template = {
-       NULL,                   /* ?? */
-       ivtv_setsda_old,        /* setsda function */
-       ivtv_setscl_old,        /* " */
-       ivtv_getsda_old,        /* " */
-       ivtv_getscl_old,        /* " */
-       10,                     /* udelay */
-       200                     /* timeout */
+static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
+       .setsda         = ivtv_setsda_old,
+       .setscl         = ivtv_setscl_old,
+       .getsda         = ivtv_getsda_old,
+       .getscl         = ivtv_getscl_old,
+       .udelay         = 5,
+       .timeout        = 200,
 };
 
 static struct i2c_client ivtv_i2c_client_template = {
index 5d210adb5c52fe84296aa2b5e34131a4a992d896..677c3292855e7da8edc6a056fe9e005d8397d15f 100644 (file)
@@ -18,6 +18,9 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_I2C_H
+#define IVTV_I2C_H
+
 int ivtv_cx25840(struct ivtv *itv, unsigned int cmd, void *arg);
 int ivtv_saa7115(struct ivtv *itv, unsigned int cmd, void *arg);
 int ivtv_saa7127(struct ivtv *itv, unsigned int cmd, void *arg);
@@ -34,3 +37,5 @@ void ivtv_call_i2c_clients(struct ivtv *itv, unsigned int cmd, void *arg);
 /* init + register i2c algo-bit adapter */
 int __devinit init_ivtv_i2c(struct ivtv *itv);
 void __devexit exit_ivtv_i2c(struct ivtv *itv);
+
+#endif
index dfe0aedc60fd0ba1a8862d966e9674e273ce4b6b..206eee7542db826803db08c73b8778c757f75bca 100644 (file)
@@ -25,8 +25,7 @@
 #include "ivtv-queue.h"
 #include "ivtv-fileops.h"
 #include "ivtv-vbi.h"
-#include "ivtv-audio.h"
-#include "ivtv-video.h"
+#include "ivtv-routing.h"
 #include "ivtv-streams.h"
 #include "ivtv-yuv.h"
 #include "ivtv-ioctl.h"
@@ -164,7 +163,7 @@ void ivtv_set_osd_alpha(struct ivtv *itv)
 {
        ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
                itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
-       ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_color_key_state, itv->osd_color_key);
+       ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_chroma_key_state, itv->osd_chroma_key);
 }
 
 int ivtv_set_speed(struct ivtv *itv, int speed)
@@ -427,7 +426,7 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
                if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
                        return -EINVAL;
-               fmt->fmt.win.chromakey = itv->osd_color_key;
+               fmt->fmt.win.chromakey = itv->osd_chroma_key;
                fmt->fmt.win.global_alpha = itv->osd_global_alpha;
                break;
 
@@ -547,7 +546,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
                if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
                        return -EINVAL;
                if (set_fmt) {
-                       itv->osd_color_key = fmt->fmt.win.chromakey;
+                       itv->osd_chroma_key = fmt->fmt.win.chromakey;
                        itv->osd_global_alpha = fmt->fmt.win.global_alpha;
                        ivtv_set_osd_alpha(itv);
                }
@@ -584,9 +583,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
 
        /* set raw VBI format */
        if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
-               if (set_fmt && streamtype == IVTV_ENC_STREAM_TYPE_VBI &&
-                   itv->vbi.sliced_in->service_set &&
-                   atomic_read(&itv->capturing) > 0) {
+               if (set_fmt && atomic_read(&itv->capturing) > 0) {
                        return -EBUSY;
                }
                if (set_fmt) {
@@ -624,7 +621,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
                return 0;
        if (set == 0)
                return -EINVAL;
-       if (atomic_read(&itv->capturing) > 0 && itv->vbi.sliced_in->service_set == 0) {
+       if (atomic_read(&itv->capturing) > 0) {
                return -EBUSY;
        }
        itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
@@ -677,13 +674,21 @@ static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
        case VIDIOC_INT_S_AUDIO_ROUTING: {
                struct v4l2_routing *route = arg;
 
-               ivtv_audio_set_route(itv, route);
+               ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route);
                break;
        }
 
-       case VIDIOC_INT_RESET:
-               ivtv_reset_ir_gpio(itv);
+       case VIDIOC_INT_RESET: {
+               u32 val = *(u32 *)arg;
+
+               if ((val == 0 && itv->options.newi2c) || (val & 0x01)) {
+                       ivtv_reset_ir_gpio(itv);
+               }
+               if (val & 0x02) {
+                       itv->video_dec_func(itv, cmd, 0);
+               }
                break;
+       }
 
        default:
                return -EINVAL;
@@ -694,6 +699,7 @@ static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
 int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg)
 {
        struct ivtv_open_id *id = NULL;
+       u32 data[CX2341X_MBOX_MAX_DATA];
 
        if (filp) id = (struct ivtv_open_id *)filp->private_data;
 
@@ -898,6 +904,9 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                        IVTV_DEBUG_INFO("Input unchanged\n");
                        break;
                }
+               if (atomic_read(&itv->capturing) > 0) {
+                       return -EBUSY;
+               }
                IVTV_DEBUG_INFO("Changing input from %d to %d\n",
                                itv->active_input, inp);
 
@@ -1127,12 +1136,14 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                memset(&enc->raw, 0, sizeof(enc->raw));
                switch (enc->cmd) {
                case V4L2_ENC_CMD_START:
+                       IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
                        enc->flags = 0;
                        if (try)
                                return 0;
                        return ivtv_start_capture(id);
 
                case V4L2_ENC_CMD_STOP:
+                       IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
                        enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
                        if (try)
                                return 0;
@@ -1140,6 +1151,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                        return 0;
 
                case V4L2_ENC_CMD_PAUSE:
+                       IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
                        enc->flags = 0;
                        if (try)
                                return 0;
@@ -1152,6 +1164,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                        break;
 
                case V4L2_ENC_CMD_RESUME:
+                       IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
                        enc->flags = 0;
                        if (try)
                                return 0;
@@ -1163,6 +1176,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                        ivtv_unmute(itv);
                        break;
                default:
+                       IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
                        return -EINVAL;
                }
                break;
@@ -1170,22 +1184,58 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
 
        case VIDIOC_G_FBUF: {
                struct v4l2_framebuffer *fb = arg;
+               int pixfmt;
+               static u32 pixel_format[16] = {
+                       V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
+                       V4L2_PIX_FMT_RGB565,
+                       V4L2_PIX_FMT_RGB555,
+                       V4L2_PIX_FMT_RGB444,
+                       V4L2_PIX_FMT_RGB32,
+                       0,
+                       0,
+                       0,
+                       V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
+                       V4L2_PIX_FMT_YUV565,
+                       V4L2_PIX_FMT_YUV555,
+                       V4L2_PIX_FMT_YUV444,
+                       V4L2_PIX_FMT_YUV32,
+                       0,
+                       0,
+                       0,
+               };
 
                memset(fb, 0, sizeof(*fb));
                if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
                        return -EINVAL;
                fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
-                       V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA;
-               fb->fmt.pixelformat = itv->osd_pixelformat;
+                       V4L2_FBUF_CAP_GLOBAL_ALPHA;
+               ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
+               data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
+               pixfmt = (data[0] >> 3) & 0xf;
+               fb->fmt.pixelformat = pixel_format[pixfmt];
                fb->fmt.width = itv->osd_rect.width;
                fb->fmt.height = itv->osd_rect.height;
                fb->base = (void *)itv->osd_video_pbase;
+               if (itv->osd_chroma_key_state)
+                       fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
                if (itv->osd_global_alpha_state)
                        fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
-               if (itv->osd_local_alpha_state)
-                       fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
-               if (itv->osd_color_key_state)
-                       fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
+               pixfmt &= 7;
+               /* no local alpha for RGB565 or unknown formats */
+               if (pixfmt == 1 || pixfmt > 4)
+                       break;
+               /* 16-bit formats have inverted local alpha */
+               if (pixfmt == 2 || pixfmt == 3)
+                       fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
+               else
+                       fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
+               if (itv->osd_local_alpha_state) {
+                       /* 16-bit formats have inverted local alpha */
+                       if (pixfmt == 2 || pixfmt == 3)
+                               fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
+                       else
+                               fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
+               }
                break;
        }
 
@@ -1195,12 +1245,22 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
                        return -EINVAL;
                itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
-               itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0;
-               itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
+               itv->osd_local_alpha_state =
+                       (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
+               itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
                ivtv_set_osd_alpha(itv);
                break;
        }
 
+       case VIDIOC_OVERLAY: {
+               int *on = arg;
+
+               if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+                       return -EINVAL;
+               ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0);
+               break;
+       }
+
        case VIDIOC_LOG_STATUS:
        {
                int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
@@ -1209,6 +1269,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                int i;
 
                IVTV_INFO("=================  START STATUS CARD #%d  =================\n", itv->num);
+               IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
                if (itv->hw_flags & IVTV_HW_TVEEPROM) {
                        struct tveeprom tv;
 
@@ -1217,32 +1278,72 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
                ivtv_get_input(itv, itv->active_input, &vidin);
                ivtv_get_audio_input(itv, itv->audio_input, &audin);
-               IVTV_INFO("Video Input: %s\n", vidin.name);
-               IVTV_INFO("Audio Input: %s\n", audin.name);
+               IVTV_INFO("Video Input:  %s\n", vidin.name);
+               IVTV_INFO("Audio Input:  %s%s\n", audin.name,
+                       (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
                if (has_output) {
                        struct v4l2_output vidout;
                        struct v4l2_audioout audout;
                        int mode = itv->output_mode;
-                       static const char * const output_modes[] = {
+                       static const char * const output_modes[5] = {
                                "None",
                                "MPEG Streaming",
                                "YUV Streaming",
                                "YUV Frames",
                                "Passthrough",
                        };
+                       static const char * const audio_modes[5] = {
+                               "Stereo",
+                               "Left",
+                               "Right",
+                               "Mono",
+                               "Swapped"
+                       };
+                       static const char * const alpha_mode[4] = {
+                               "None",
+                               "Global",
+                               "Local",
+                               "Global and Local"
+                       };
+                       static const char * const pixel_format[16] = {
+                               "ARGB Indexed",
+                               "RGB 5:6:5",
+                               "ARGB 1:5:5:5",
+                               "ARGB 1:4:4:4",
+                               "ARGB 8:8:8:8",
+                               "5",
+                               "6",
+                               "7",
+                               "AYUV Indexed",
+                               "YUV 5:6:5",
+                               "AYUV 1:5:5:5",
+                               "AYUV 1:4:4:4",
+                               "AYUV 8:8:8:8",
+                               "13",
+                               "14",
+                               "15",
+                       };
 
                        ivtv_get_output(itv, itv->active_output, &vidout);
                        ivtv_get_audio_output(itv, 0, &audout);
                        IVTV_INFO("Video Output: %s\n", vidout.name);
-                       IVTV_INFO("Audio Output: %s\n", audout.name);
+                       IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
+                               audio_modes[itv->audio_stereo_mode],
+                               audio_modes[itv->audio_bilingual_mode]);
                        if (mode < 0 || mode > OUT_PASSTHROUGH)
                                mode = OUT_NONE;
-                       IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
+                       IVTV_INFO("Output Mode:  %s\n", output_modes[mode]);
+                       ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
+                       data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
+                       IVTV_INFO("Overlay:      %s, Alpha: %s, Pixel Format: %s\n",
+                               data[0] & 1 ? "On" : "Off",
+                               alpha_mode[(data[0] >> 1) & 0x3],
+                               pixel_format[(data[0] >> 3) & 0xf]);
                }
-               IVTV_INFO("Tuner: %s\n",
+               IVTV_INFO("Tuner:  %s\n",
                        test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
                cx2341x_log_status(&itv->params, itv->name);
-               IVTV_INFO("Version: %s Status flags: 0x%08lx\n", IVTV_VERSION, itv->i_flags);
+               IVTV_INFO("Status flags:    0x%08lx\n", itv->i_flags);
                for (i = 0; i < IVTV_MAX_STREAMS; i++) {
                        struct ivtv_stream *s = &itv->streams[i];
 
@@ -1252,7 +1353,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
                                        (s->buffers - s->q_free.buffers) * 100 / s->buffers,
                                        (s->buffers * s->buf_size) / 1024, s->buffers);
                }
-               IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
+               IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
                IVTV_INFO("==================  END STATUS CARD #%d  ==================\n", itv->num);
                break;
        }
@@ -1288,6 +1389,8 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
                        ivtv_release_stream(s);
                        return -EBUSY;
                }
+               /* Mark that this file handle started the UDMA_YUV mode */
+               id->yuv_frames = 1;
                if (args->y_source == NULL)
                        return 0;
                return ivtv_yuv_prep_frame(itv, args);
@@ -1396,9 +1499,9 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
                int try = (cmd == VIDEO_TRY_COMMAND);
 
                if (try)
-                       IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND\n");
+                       IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
                else
-                       IVTV_DEBUG_IOCTL("VIDEO_COMMAND\n");
+                       IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
                return ivtv_video_command(itv, id, vc, try);
        }
 
@@ -1429,11 +1532,15 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
                                return 0;
                        if (nonblocking)
                                return -EAGAIN;
-                       /* wait for event */
+                       /* Wait for event. Note that serialize_lock is locked,
+                          so to allow other processes to access the driver while
+                          we are waiting unlock first and later lock again. */
+                       mutex_unlock(&itv->serialize_lock);
                        prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
                        if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0)
                                schedule();
                        finish_wait(&itv->event_waitq, &wait);
+                       mutex_lock(&itv->serialize_lock);
                        if (signal_pending(current)) {
                                /* return if a signal was received */
                                IVTV_DEBUG_INFO("User stopped wait for event\n");
@@ -1470,6 +1577,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
        case VIDIOC_S_AUDOUT:
        case VIDIOC_S_EXT_CTRLS:
        case VIDIOC_S_FBUF:
+       case VIDIOC_OVERLAY:
                ret = v4l2_prio_check(&itv->prio, &id->prio);
                if (ret)
                        return ret;
@@ -1523,6 +1631,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
        case VIDIOC_TRY_ENCODER_CMD:
        case VIDIOC_G_FBUF:
        case VIDIOC_S_FBUF:
+       case VIDIOC_OVERLAY:
                if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
                        printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
                        v4l_printk_ioctl(cmd);
@@ -1563,12 +1672,9 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
        return 0;
 }
 
-int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg)
+static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,
+               unsigned int cmd, unsigned long arg)
 {
-       struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
-       struct ivtv *itv = id->itv;
-
        /* Filter dvb ioctls that cannot be handled by video_usercopy */
        switch (cmd) {
        case VIDEO_SELECT_SOURCE:
@@ -1603,3 +1709,16 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
        }
        return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl);
 }
+
+int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+                   unsigned long arg)
+{
+       struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
+       struct ivtv *itv = id->itv;
+       int res;
+
+       mutex_lock(&itv->serialize_lock);
+       res = ivtv_serialized_ioctl(itv, inode, filp, cmd, arg);
+       mutex_unlock(&itv->serialize_lock);
+       return res;
+}
index cbccf7a9f65c5a54be44884b819e80aec7fc6d10..a03351b6853d8fe9f8663b1995179e8ad7d26bf8 100644 (file)
@@ -18,6 +18,9 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_IOCTL_H
+#define IVTV_IOCTL_H
+
 u16 service2vbi(int type);
 void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
 u16 get_service_set(struct v4l2_sliced_vbi_format *fmt);
@@ -26,3 +29,5 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg);
 void ivtv_set_osd_alpha(struct ivtv *itv);
 int ivtv_set_speed(struct ivtv *itv, int speed);
+
+#endif
index fcd6e7f5f121b0cb78c471cdfc82e9cb0249a790..fd1688e4757dc1fefa51f4a49461a4af0039a3aa 100644 (file)
  */
 
 #include "ivtv-driver.h"
-#include "ivtv-firmware.h"
-#include "ivtv-fileops.h"
 #include "ivtv-queue.h"
 #include "ivtv-udma.h"
 #include "ivtv-irq.h"
-#include "ivtv-ioctl.h"
 #include "ivtv-mailbox.h"
 #include "ivtv-vbi.h"
 #include "ivtv-yuv.h"
@@ -45,7 +42,6 @@ static void ivtv_pio_work_handler(struct ivtv *itv)
 {
        struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream];
        struct ivtv_buffer *buf;
-       struct list_head *p;
        int i = 0;
 
        IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n");
@@ -57,21 +53,19 @@ static void ivtv_pio_work_handler(struct ivtv *itv)
                return;
        }
        IVTV_DEBUG_HI_DMA("Process PIO %s\n", s->name);
-       buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list);
-       list_for_each(p, &s->q_dma.list) {
-               struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list);
-               u32 size = s->PIOarray[i].size & 0x3ffff;
+       list_for_each_entry(buf, &s->q_dma.list, list) {
+               u32 size = s->sg_processing[i].size & 0x3ffff;
 
                /* Copy the data from the card to the buffer */
                if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
-                       memcpy_fromio(buf->buf, itv->dec_mem + s->PIOarray[i].src - IVTV_DECODER_OFFSET, size);
+                       memcpy_fromio(buf->buf, itv->dec_mem + s->sg_processing[i].src - IVTV_DECODER_OFFSET, size);
                }
                else {
-                       memcpy_fromio(buf->buf, itv->enc_mem + s->PIOarray[i].src, size);
+                       memcpy_fromio(buf->buf, itv->enc_mem + s->sg_processing[i].src, size);
                }
-               if (s->PIOarray[i].size & 0x80000000)
-                       break;
                i++;
+               if (i == s->sg_processing_size)
+                       break;
        }
        write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
 }
@@ -100,12 +94,11 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
 {
        struct ivtv *itv = s->itv;
        struct ivtv_buffer *buf;
-       struct list_head *p;
        u32 bytes_needed = 0;
        u32 offset, size;
        u32 UVoffset = 0, UVsize = 0;
        int skip_bufs = s->q_predma.buffers;
-       int idx = s->SG_length;
+       int idx = s->sg_pending_size;
        int rc;
 
        /* sanity checks */
@@ -123,7 +116,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
                case IVTV_ENC_STREAM_TYPE_MPG:
                        offset = data[1];
                        size = data[2];
-                       s->dma_pts = 0;
+                       s->pending_pts = 0;
                        break;
 
                case IVTV_ENC_STREAM_TYPE_YUV:
@@ -131,13 +124,13 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
                        size = data[2];
                        UVoffset = data[3];
                        UVsize = data[4];
-                       s->dma_pts = ((u64) data[5] << 32) | data[6];
+                       s->pending_pts = ((u64) data[5] << 32) | data[6];
                        break;
 
                case IVTV_ENC_STREAM_TYPE_PCM:
                        offset = data[1] + 12;
                        size = data[2] - 12;
-                       s->dma_pts = read_dec(offset - 8) |
+                       s->pending_pts = read_dec(offset - 8) |
                                ((u64)(read_dec(offset - 12)) << 32);
                        if (itv->has_cx23415)
                                offset += IVTV_DECODER_OFFSET;
@@ -150,13 +143,13 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
                                IVTV_DEBUG_INFO("VBI offset == 0\n");
                                return -1;
                        }
-                       s->dma_pts = read_enc(offset - 4) | ((u64)read_enc(offset - 8) << 32);
+                       s->pending_pts = read_enc(offset - 4) | ((u64)read_enc(offset - 8) << 32);
                        break;
 
                case IVTV_DEC_STREAM_TYPE_VBI:
                        size = read_dec(itv->vbi.dec_start + 4) + 8;
                        offset = read_dec(itv->vbi.dec_start) + itv->vbi.dec_start;
-                       s->dma_pts = 0;
+                       s->pending_pts = 0;
                        offset += IVTV_DECODER_OFFSET;
                        break;
                default:
@@ -165,17 +158,17 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
        }
 
        /* if this is the start of the DMA then fill in the magic cookie */
-       if (s->SG_length == 0) {
+       if (s->sg_pending_size == 0 && ivtv_use_dma(s)) {
                if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
                    s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
-                       s->dma_backup = read_dec(offset - IVTV_DECODER_OFFSET);
+                       s->pending_backup = read_dec(offset - IVTV_DECODER_OFFSET);
                        write_dec_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset - IVTV_DECODER_OFFSET);
                }
                else {
-                       s->dma_backup = read_enc(offset);
+                       s->pending_backup = read_enc(offset);
                        write_enc_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset);
                }
-               s->dma_offset = offset;
+               s->pending_offset = offset;
        }
 
        bytes_needed = size;
@@ -202,18 +195,17 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
        }
        s->buffers_stolen = rc;
 
-       /* got the buffers, now fill in SGarray (DMA) */
+       /* got the buffers, now fill in sg_pending */
        buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
        memset(buf->buf, 0, 128);
-       list_for_each(p, &s->q_predma.list) {
-               struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list);
-
+       list_for_each_entry(buf, &s->q_predma.list, list) {
                if (skip_bufs-- > 0)
                        continue;
-               s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
-               s->SGarray[idx].src = cpu_to_le32(offset);
-               s->SGarray[idx].size = cpu_to_le32(s->buf_size);
+               s->sg_pending[idx].dst = buf->dma_handle;
+               s->sg_pending[idx].src = offset;
+               s->sg_pending[idx].size = s->buf_size;
                buf->bytesused = (size < s->buf_size) ? size : s->buf_size;
+               buf->dma_xfer_cnt = s->dma_xfer_cnt;
 
                s->q_predma.bytesused += buf->bytesused;
                size -= buf->bytesused;
@@ -229,7 +221,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
                }
                idx++;
        }
-       s->SG_length = idx;
+       s->sg_pending_size = idx;
        return 0;
 }
 
@@ -251,7 +243,7 @@ static void dma_post(struct ivtv_stream *s)
                /* Sync Buffer */
                ivtv_buf_sync_for_cpu(s, buf);
 
-               if (x == 0) {
+               if (x == 0 && ivtv_use_dma(s)) {
                        offset = s->dma_last_offset;
                        if (u32buf[offset / 4] != DMA_MAGIC_COOKIE)
                        {
@@ -286,14 +278,12 @@ static void dma_post(struct ivtv_stream *s)
                /* flag byteswap ABCD -> DCBA for MPG & VBI data outside irq */
                if (s->type == IVTV_ENC_STREAM_TYPE_MPG ||
                    s->type == IVTV_ENC_STREAM_TYPE_VBI)
-                       set_bit(IVTV_F_B_NEED_BUF_SWAP, &buf->b_flags);
+                       buf->b_flags |= IVTV_F_B_NEED_BUF_SWAP;
        }
        if (buf)
                buf->bytesused += s->dma_last_offset;
        if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
-               list_for_each(p, &s->q_dma.list) {
-                       buf = list_entry(p, struct ivtv_buffer, list);
-
+               list_for_each_entry(buf, &s->q_dma.list, list) {
                        /* Parse and Groom VBI Data */
                        s->q_dma.bytesused -= buf->bytesused;
                        ivtv_process_vbi_data(itv, buf, 0, s->type);
@@ -313,7 +303,6 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock)
 {
        struct ivtv *itv = s->itv;
        struct ivtv_buffer *buf;
-       struct list_head *p;
        u32 y_size = itv->params.height * itv->params.width;
        u32 uv_offset = offset + IVTV_YUV_BUFFER_UV_OFFSET;
        int y_done = 0;
@@ -322,18 +311,15 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock)
        int idx = 0;
 
        IVTV_DEBUG_HI_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset);
-       buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
-       list_for_each(p, &s->q_predma.list) {
-               struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list);
-
+       list_for_each_entry(buf, &s->q_predma.list, list) {
                /* YUV UV Offset from Y Buffer */
                if (s->type == IVTV_DEC_STREAM_TYPE_YUV && !y_done && bytes_written >= y_size) {
                        offset = uv_offset;
                        y_done = 1;
                }
-               s->SGarray[idx].src = cpu_to_le32(buf->dma_handle);
-               s->SGarray[idx].dst = cpu_to_le32(offset);
-               s->SGarray[idx].size = cpu_to_le32(buf->bytesused);
+               s->sg_pending[idx].src = buf->dma_handle;
+               s->sg_pending[idx].dst = offset;
+               s->sg_pending[idx].size = buf->bytesused;
 
                offset += buf->bytesused;
                bytes_written += buf->bytesused;
@@ -342,10 +328,7 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock)
                ivtv_buf_sync_for_device(s, buf);
                idx++;
        }
-       s->SG_length = idx;
-
-       /* Mark last buffer size for Interrupt flag */
-       s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
+       s->sg_pending_size = idx;
 
        /* Sync Hardware SG List of buffers */
        ivtv_stream_sync_for_device(s);
@@ -361,6 +344,34 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock)
                spin_unlock_irqrestore(&itv->dma_reg_lock, flags);
 }
 
+static void ivtv_dma_enc_start_xfer(struct ivtv_stream *s)
+{
+       struct ivtv *itv = s->itv;
+
+       s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src);
+       s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst);
+       s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000);
+       s->sg_processed++;
+       /* Sync Hardware SG List of buffers */
+       ivtv_stream_sync_for_device(s);
+       write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR);
+       write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
+}
+
+static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s)
+{
+       struct ivtv *itv = s->itv;
+
+       s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src);
+       s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst);
+       s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000);
+       s->sg_processed++;
+       /* Sync Hardware SG List of buffers */
+       ivtv_stream_sync_for_device(s);
+       write_reg(s->sg_handle, IVTV_REG_DECDMAADDR);
+       write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
+}
+
 /* start the encoder DMA */
 static void ivtv_dma_enc_start(struct ivtv_stream *s)
 {
@@ -374,8 +385,7 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
                ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
 
        if (ivtv_use_dma(s))
-               s->SGarray[s->SG_length - 1].size =
-                       cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
+               s->sg_pending[s->sg_pending_size - 1].size += 256;
 
        /* If this is an MPEG stream, and VBI data is also pending, then append the
           VBI DMA to the MPEG DMA and transfer both sets of data at once.
@@ -386,43 +396,39 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
           sure we only use the MPEG DMA to transfer the VBI DMA if both are in
           use. This way no conflicts occur. */
        clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
-       if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->SG_length &&
-                       s->SG_length + s_vbi->SG_length <= s->buffers) {
+       if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->sg_pending_size &&
+                       s->sg_pending_size + s_vbi->sg_pending_size <= s->buffers) {
                ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
                if (ivtv_use_dma(s_vbi))
-                       s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
-               for (i = 0; i < s_vbi->SG_length; i++) {
-                       s->SGarray[s->SG_length++] = s_vbi->SGarray[i];
+                       s_vbi->sg_pending[s_vbi->sg_pending_size - 1].size += 256;
+               for (i = 0; i < s_vbi->sg_pending_size; i++) {
+                       s->sg_pending[s->sg_pending_size++] = s_vbi->sg_pending[i];
                }
-               itv->vbi.dma_offset = s_vbi->dma_offset;
-               s_vbi->SG_length = 0;
+               s_vbi->dma_offset = s_vbi->pending_offset;
+               s_vbi->sg_pending_size = 0;
+               s_vbi->dma_xfer_cnt++;
                set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
                IVTV_DEBUG_HI_DMA("include DMA for %s\n", s->name);
        }
 
-       /* Mark last buffer size for Interrupt flag */
-       s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
-
-       if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
-               set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
-       else
-               clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
+       s->dma_xfer_cnt++;
+       memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_element) * s->sg_pending_size);
+       s->sg_processing_size = s->sg_pending_size;
+       s->sg_pending_size = 0;
+       s->sg_processed = 0;
+       s->dma_offset = s->pending_offset;
+       s->dma_backup = s->pending_backup;
+       s->dma_pts = s->pending_pts;
 
        if (ivtv_use_pio(s)) {
-               for (i = 0; i < s->SG_length; i++) {
-                       s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src);
-                       s->PIOarray[i].size = le32_to_cpu(s->SGarray[i].size);
-               }
                set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags);
                set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
                set_bit(IVTV_F_I_PIO, &itv->i_flags);
                itv->cur_pio_stream = s->type;
        }
        else {
-               /* Sync Hardware SG List of buffers */
-               ivtv_stream_sync_for_device(s);
-               write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
-               write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
+               itv->dma_retries = 0;
+               ivtv_dma_enc_start_xfer(s);
                set_bit(IVTV_F_I_DMA, &itv->i_flags);
                itv->cur_dma_stream = s->type;
                itv->dma_timer.expires = jiffies + msecs_to_jiffies(100);
@@ -436,10 +442,15 @@ static void ivtv_dma_dec_start(struct ivtv_stream *s)
 
        if (s->q_predma.bytesused)
                ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
+       s->dma_xfer_cnt++;
+       memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_element) * s->sg_pending_size);
+       s->sg_processing_size = s->sg_pending_size;
+       s->sg_pending_size = 0;
+       s->sg_processed = 0;
+
        IVTV_DEBUG_HI_DMA("start DMA for %s\n", s->name);
-       /* put SG Handle into register 0x0c */
-       write_reg(s->SG_handle, IVTV_REG_DECDMAADDR);
-       write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
+       itv->dma_retries = 0;
+       ivtv_dma_dec_start_xfer(s);
        set_bit(IVTV_F_I_DMA, &itv->i_flags);
        itv->cur_dma_stream = s->type;
        itv->dma_timer.expires = jiffies + msecs_to_jiffies(100);
@@ -450,27 +461,44 @@ static void ivtv_irq_dma_read(struct ivtv *itv)
 {
        struct ivtv_stream *s = NULL;
        struct ivtv_buffer *buf;
-       int hw_stream_type;
+       int hw_stream_type = 0;
 
        IVTV_DEBUG_HI_IRQ("DEC DMA READ\n");
-       del_timer(&itv->dma_timer);
-       if (read_reg(IVTV_REG_DMASTATUS) & 0x14) {
-               IVTV_DEBUG_WARN("DEC DMA ERROR %x\n", read_reg(IVTV_REG_DMASTATUS));
-               write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
+       if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0) {
+               del_timer(&itv->dma_timer);
+               return;
        }
+
        if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
-               if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) {
-                       s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
-                       hw_stream_type = 2;
+               s = &itv->streams[itv->cur_dma_stream];
+               ivtv_stream_sync_for_cpu(s);
+
+               if (read_reg(IVTV_REG_DMASTATUS) & 0x14) {
+                       IVTV_DEBUG_WARN("DEC DMA ERROR %x (xfer %d of %d, retry %d)\n",
+                                       read_reg(IVTV_REG_DMASTATUS),
+                                       s->sg_processed, s->sg_processing_size, itv->dma_retries);
+                       write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
+                       if (itv->dma_retries == 3) {
+                               /* Too many retries, give up on this frame */
+                               itv->dma_retries = 0;
+                               s->sg_processed = s->sg_processing_size;
+                       }
+                       else {
+                               /* Retry, starting with the first xfer segment.
+                                  Just retrying the current segment is not sufficient. */
+                               s->sg_processed = 0;
+                               itv->dma_retries++;
+                       }
                }
-               else {
-                       s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
-                       hw_stream_type = 0;
+               if (s->sg_processed < s->sg_processing_size) {
+                       /* DMA next buffer */
+                       ivtv_dma_dec_start_xfer(s);
+                       return;
                }
+               if (s->type == IVTV_DEC_STREAM_TYPE_YUV)
+                       hw_stream_type = 2;
                IVTV_DEBUG_HI_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused);
 
-               ivtv_stream_sync_for_cpu(s);
-
                /* For some reason must kick the firmware, like PIO mode,
                   I think this tells the firmware we are done and the size
                   of the xfer so it can calculate what we need next.
@@ -487,6 +515,7 @@ static void ivtv_irq_dma_read(struct ivtv *itv)
                }
                wake_up(&s->waitq);
        }
+       del_timer(&itv->dma_timer);
        clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
        clear_bit(IVTV_F_I_DMA, &itv->i_flags);
        itv->cur_dma_stream = -1;
@@ -498,33 +527,46 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
        u32 data[CX2341X_MBOX_MAX_DATA];
        struct ivtv_stream *s;
 
-       del_timer(&itv->dma_timer);
        ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data);
-       IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d\n", data[0], data[1]);
-       if (test_and_clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags))
-               data[1] = 3;
-       else if (data[1] > 2)
+       IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream);
+       if (itv->cur_dma_stream < 0) {
+               del_timer(&itv->dma_timer);
                return;
-       s = &itv->streams[ivtv_stream_map[data[1]]];
+       }
+       s = &itv->streams[itv->cur_dma_stream];
+       ivtv_stream_sync_for_cpu(s);
+
        if (data[0] & 0x18) {
-               IVTV_DEBUG_WARN("ENC DMA ERROR %x\n", data[0]);
+               IVTV_DEBUG_WARN("ENC DMA ERROR %x (offset %08x, xfer %d of %d, retry %d)\n", data[0],
+                       s->dma_offset, s->sg_processed, s->sg_processing_size, itv->dma_retries);
                write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
-               ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, data[1]);
+               if (itv->dma_retries == 3) {
+                       /* Too many retries, give up on this frame */
+                       itv->dma_retries = 0;
+                       s->sg_processed = s->sg_processing_size;
+               }
+               else {
+                       /* Retry, starting with the first xfer segment.
+                          Just retrying the current segment is not sufficient. */
+                       s->sg_processed = 0;
+                       itv->dma_retries++;
+               }
+       }
+       if (s->sg_processed < s->sg_processing_size) {
+               /* DMA next buffer */
+               ivtv_dma_enc_start_xfer(s);
+               return;
        }
-       s->SG_length = 0;
+       del_timer(&itv->dma_timer);
        clear_bit(IVTV_F_I_DMA, &itv->i_flags);
        itv->cur_dma_stream = -1;
        dma_post(s);
-       ivtv_stream_sync_for_cpu(s);
        if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
-               u32 tmp;
-
                s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
-               tmp = s->dma_offset;
-               s->dma_offset = itv->vbi.dma_offset;
                dma_post(s);
-               s->dma_offset = tmp;
        }
+       s->sg_processing_size = 0;
+       s->sg_processed = 0;
        wake_up(&itv->dma_waitq);
 }
 
@@ -538,8 +580,6 @@ static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
        }
        s = &itv->streams[itv->cur_pio_stream];
        IVTV_DEBUG_HI_IRQ("ENC PIO COMPLETE %s\n", s->name);
-       s->SG_length = 0;
-       clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
        clear_bit(IVTV_F_I_PIO, &itv->i_flags);
        itv->cur_pio_stream = -1;
        dma_post(s);
@@ -551,13 +591,8 @@ static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
                ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2);
        clear_bit(IVTV_F_I_PIO, &itv->i_flags);
        if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
-               u32 tmp;
-
                s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
-               tmp = s->dma_offset;
-               s->dma_offset = itv->vbi.dma_offset;
                dma_post(s);
-               s->dma_offset = tmp;
        }
        wake_up(&itv->dma_waitq);
 }
@@ -569,19 +604,23 @@ static void ivtv_irq_dma_err(struct ivtv *itv)
        del_timer(&itv->dma_timer);
        ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data);
        IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1],
-                                       read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
+                               read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
+       write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
        if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) &&
            itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) {
                struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream];
 
                /* retry */
-               write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
                if (s->type >= IVTV_DEC_STREAM_TYPE_MPG)
                        ivtv_dma_dec_start(s);
                else
                        ivtv_dma_enc_start(s);
                return;
        }
+       if (test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
+               ivtv_udma_start(itv);
+               return;
+       }
        clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
        clear_bit(IVTV_F_I_DMA, &itv->i_flags);
        itv->cur_dma_stream = -1;
@@ -625,14 +664,12 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
           DMA the data. Since at most four VBI DMA buffers are available,
           we just drop the old requests when there are already three
           requests queued. */
-       if (s->SG_length > 2) {
-               struct list_head *p;
-               list_for_each(p, &s->q_predma.list) {
-                       struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list);
+       if (s->sg_pending_size > 2) {
+               struct ivtv_buffer *buf;
+               list_for_each_entry(buf, &s->q_predma.list, list)
                        ivtv_buf_sync_for_cpu(s, buf);
-               }
                ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0);
-               s->SG_length = 0;
+               s->sg_pending_size = 0;
        }
        /* if we can append the data, and the MPEG stream isn't capturing,
           then start a DMA request for just the VBI data. */
@@ -698,23 +735,27 @@ static void ivtv_irq_vsync(struct ivtv *itv)
 
        if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");
 
-       if (((frame ^ itv->yuv_info.lace_sync_field) == 0 && ((itv->lastVsyncFrame & 1) ^ itv->yuv_info.lace_sync_field)) ||
-                       (frame != (itv->lastVsyncFrame & 1) && !itv->yuv_info.frame_interlaced)) {
+       if (((frame ^ itv->yuv_info.sync_field[last_dma_frame]) == 0 &&
+               ((itv->last_vsync_field & 1) ^ itv->yuv_info.sync_field[last_dma_frame])) ||
+                       (frame != (itv->last_vsync_field & 1) && !itv->yuv_info.frame_interlaced)) {
                int next_dma_frame = last_dma_frame;
 
-               if (next_dma_frame >= 0 && next_dma_frame != atomic_read(&itv->yuv_info.next_fill_frame)) {
-                       write_reg(yuv_offset[next_dma_frame] >> 4, 0x82c);
-                       write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x830);
-                       write_reg(yuv_offset[next_dma_frame] >> 4, 0x834);
-                       write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x838);
-                       next_dma_frame = (next_dma_frame + 1) & 0x3;
-                       atomic_set(&itv->yuv_info.next_dma_frame, next_dma_frame);
+               if (!(itv->yuv_info.frame_interlaced && itv->yuv_info.field_delay[next_dma_frame] && itv->yuv_info.fields_lapsed < 1)) {
+                       if (next_dma_frame >= 0 && next_dma_frame != atomic_read(&itv->yuv_info.next_fill_frame)) {
+                               write_reg(yuv_offset[next_dma_frame] >> 4, 0x82c);
+                               write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x830);
+                               write_reg(yuv_offset[next_dma_frame] >> 4, 0x834);
+                               write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x838);
+                               next_dma_frame = (next_dma_frame + 1) & 0x3;
+                               atomic_set(&itv->yuv_info.next_dma_frame, next_dma_frame);
+                               itv->yuv_info.fields_lapsed = -1;
+                       }
                }
        }
-       if (frame != (itv->lastVsyncFrame & 1)) {
+       if (frame != (itv->last_vsync_field & 1)) {
                struct ivtv_stream *s = ivtv_get_output_stream(itv);
 
-               itv->lastVsyncFrame += 1;
+               itv->last_vsync_field += 1;
                if (frame == 0) {
                        clear_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
                        clear_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags);
@@ -731,7 +772,10 @@ static void ivtv_irq_vsync(struct ivtv *itv)
                        wake_up(&s->waitq);
 
                /* Send VBI to saa7127 */
-               if (frame) {
+               if (frame && (itv->output_mode == OUT_PASSTHROUGH ||
+                       test_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags) ||
+                       test_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags) ||
+                       test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags))) {
                        set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
                        set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
                }
@@ -749,10 +793,12 @@ static void ivtv_irq_vsync(struct ivtv *itv)
                                set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
                        }
                }
+
+               itv->yuv_info.fields_lapsed ++;
        }
 }
 
-#define IVTV_IRQ_DMA (IVTV_IRQ_DMA_READ | IVTV_IRQ_ENC_DMA_COMPLETE | IVTV_IRQ_DMA_ERR | IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_VBI_CAP | IVTV_IRQ_DEC_DATA_REQ)
+#define IVTV_IRQ_DMA (IVTV_IRQ_DMA_READ | IVTV_IRQ_ENC_DMA_COMPLETE | IVTV_IRQ_DMA_ERR | IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_VBI_CAP | IVTV_IRQ_DEC_DATA_REQ | IVTV_IRQ_DEC_VBI_RE_INSERT)
 
 irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
 {
@@ -777,7 +823,7 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
                 */
                if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
                        /* vsync is enabled, see if we're in a new field */
-                       if ((itv->lastVsyncFrame & 1) != (read_reg(0x28c0) & 1)) {
+                       if ((itv->last_vsync_field & 1) != (read_reg(0x28c0) & 1)) {
                                /* New field, looks like we missed it */
                                IVTV_DEBUG_YUV("VSync interrupt missed %d\n",read_reg(0x28c0)>>16);
                                vsync_force = 1;
@@ -831,7 +877,7 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
        if (combo & IVTV_IRQ_ENC_EOS) {
                IVTV_DEBUG_IRQ("ENC EOS\n");
                set_bit(IVTV_F_I_EOS, &itv->i_flags);
-               wake_up(&itv->cap_w);
+               wake_up(&itv->eos_waitq);
        }
 
        if (combo & IVTV_IRQ_DEC_DATA_REQ) {
@@ -853,8 +899,9 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
        }
 
        if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
+               itv->irq_rr_idx++;
                for (i = 0; i < IVTV_MAX_STREAMS; i++) {
-                       int idx = (i + itv->irq_rr_idx++) % IVTV_MAX_STREAMS;
+                       int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS;
                        struct ivtv_stream *s = &itv->streams[idx];
 
                        if (!test_and_clear_bit(IVTV_F_S_DMA_PENDING, &s->s_flags))
@@ -871,8 +918,9 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
        }
 
        if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
+               itv->irq_rr_idx++;
                for (i = 0; i < IVTV_MAX_STREAMS; i++) {
-                       int idx = (i + itv->irq_rr_idx++) % IVTV_MAX_STREAMS;
+                       int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS;
                        struct ivtv_stream *s = &itv->streams[idx];
 
                        if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags))
@@ -883,8 +931,9 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
                }
        }
 
-       if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags))
+       if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags)) {
                queue_work(itv->irq_work_queues, &itv->irq_work_queue);
+       }
 
        spin_unlock(&itv->dma_reg_lock);
 
index a43348a30309816a582cdbebd7d819670dd2aec3..f879a5822e7138ae8b374fa2f01ca86d40114951 100644 (file)
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_IRQ_H
+#define IVTV_IRQ_H
+
+#define IVTV_IRQ_ENC_START_CAP         (0x1 << 31)
+#define IVTV_IRQ_ENC_EOS               (0x1 << 30)
+#define IVTV_IRQ_ENC_VBI_CAP           (0x1 << 29)
+#define IVTV_IRQ_ENC_VIM_RST           (0x1 << 28)
+#define IVTV_IRQ_ENC_DMA_COMPLETE      (0x1 << 27)
+#define IVTV_IRQ_ENC_PIO_COMPLETE      (0x1 << 25)
+#define IVTV_IRQ_DEC_AUD_MODE_CHG      (0x1 << 24)
+#define IVTV_IRQ_DEC_DATA_REQ          (0x1 << 22)
+#define IVTV_IRQ_DEC_DMA_COMPLETE      (0x1 << 20)
+#define IVTV_IRQ_DEC_VBI_RE_INSERT     (0x1 << 19)
+#define IVTV_IRQ_DMA_ERR               (0x1 << 18)
+#define IVTV_IRQ_DMA_WRITE             (0x1 << 17)
+#define IVTV_IRQ_DMA_READ              (0x1 << 16)
+#define IVTV_IRQ_DEC_VSYNC             (0x1 << 10)
+
+/* IRQ Masks */
+#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\
+               IVTV_IRQ_DMA_READ|IVTV_IRQ_ENC_PIO_COMPLETE)
+
+#define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS)
+#define IVTV_IRQ_MASK_DECODE  (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG)
+
 irqreturn_t ivtv_irq_handler(int irq, void *dev_id);
 
 void ivtv_irq_work_handler(struct work_struct *work);
 void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock);
 void ivtv_unfinished_dma(unsigned long arg);
+
+#endif
index 5e3b679202ae8a69031f4d118e42d40ae220d3ce..b05436da7136d04ec422e0c7c31d3ebd3abbefa8 100644 (file)
@@ -225,15 +225,15 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[])
        }
        if (args < 0 || args > CX2341X_MBOX_MAX_DATA ||
            cmd < 0 || cmd > 255 || api_info[cmd].name == NULL) {
-               IVTV_ERR("Invalid API call: cmd = 0x%02x, args = %d\n", cmd, args);
+               IVTV_ERR("Invalid MB call: cmd = 0x%02x, args = %d\n", cmd, args);
                return -EINVAL;
        }
 
        if (api_info[cmd].flags & API_HIGH_VOL) {
-           IVTV_DEBUG_HI_API("API Call: %s\n", api_info[cmd].name);
+           IVTV_DEBUG_HI_MB("MB Call: %s\n", api_info[cmd].name);
        }
        else {
-           IVTV_DEBUG_API("API Call: %s\n", api_info[cmd].name);
+           IVTV_DEBUG_MB("MB Call: %s\n", api_info[cmd].name);
        }
 
        /* clear possibly uninitialized part of data array */
index 79b8aec14370d9833df4bac99398fab2de43c90e..71a54eef8fc7ca8814f4ab5c6851b4b8f6e9abd1 100644 (file)
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_MAILBOX_H
+#define IVTV_MAILBOX_H
+
+#define IVTV_MBOX_DMA_END         8
+#define IVTV_MBOX_DMA             9
+
 void ivtv_api_get_data(struct ivtv_mailbox_data *mbox, int mb, u32 data[]);
 int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]);
 int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...);
 int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...);
 int ivtv_api_func(void *priv, int cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]);
+
+#endif
index a04f9387f63df4127668d42dfa9143154ce4e0c1..39a216713244eecd6481d75d307e0ec38f9d74b1 100644 (file)
@@ -20,9 +20,7 @@
  */
 
 #include "ivtv-driver.h"
-#include "ivtv-streams.h"
 #include "ivtv-queue.h"
-#include "ivtv-mailbox.h"
 
 int ivtv_buf_copy_from_user(struct ivtv_stream *s, struct ivtv_buffer *buf, const char __user *src, int copybytes)
 {
@@ -60,6 +58,7 @@ void ivtv_enqueue(struct ivtv_stream *s, struct ivtv_buffer *buf, struct ivtv_qu
                buf->bytesused = 0;
                buf->readpos = 0;
                buf->b_flags = 0;
+               buf->dma_xfer_cnt = 0;
        }
        spin_lock_irqsave(&s->qlock, flags);
        list_add_tail(&buf->list, &q->list);
@@ -87,7 +86,7 @@ struct ivtv_buffer *ivtv_dequeue(struct ivtv_stream *s, struct ivtv_queue *q)
 }
 
 static void ivtv_queue_move_buf(struct ivtv_stream *s, struct ivtv_queue *from,
-               struct ivtv_queue *to, int clear, int full)
+               struct ivtv_queue *to, int clear)
 {
        struct ivtv_buffer *buf = list_entry(from->list.next, struct ivtv_buffer, list);
 
@@ -97,13 +96,7 @@ static void ivtv_queue_move_buf(struct ivtv_stream *s, struct ivtv_queue *from,
        from->bytesused -= buf->bytesused - buf->readpos;
        /* special handling for q_free */
        if (clear)
-               buf->bytesused = buf->readpos = buf->b_flags = 0;
-       else if (full) {
-               /* special handling for stolen buffers, assume
-                  all bytes are used. */
-               buf->bytesused = s->buf_size;
-               buf->readpos = buf->b_flags = 0;
-       }
+               buf->bytesused = buf->readpos = buf->b_flags = buf->dma_xfer_cnt = 0;
        to->buffers++;
        to->length += s->buf_size;
        to->bytesused += buf->bytesused - buf->readpos;
@@ -112,7 +105,7 @@ static void ivtv_queue_move_buf(struct ivtv_stream *s, struct ivtv_queue *from,
 /* Move 'needed_bytes' worth of buffers from queue 'from' into queue 'to'.
    If 'needed_bytes' == 0, then move all buffers from 'from' into 'to'.
    If 'steal' != NULL, then buffers may also taken from that queue if
-   needed.
+   needed, but only if 'from' is the free queue.
 
    The buffer is automatically cleared if it goes to the free queue. It is
    also cleared if buffers need to be taken from the 'steal' queue and
@@ -133,7 +126,7 @@ int ivtv_queue_move(struct ivtv_stream *s, struct ivtv_queue *from, struct ivtv_
        int rc = 0;
        int from_free = from == &s->q_free;
        int to_free = to == &s->q_free;
-       int bytes_available;
+       int bytes_available, bytes_steal;
 
        spin_lock_irqsave(&s->qlock, flags);
        if (needed_bytes == 0) {
@@ -142,32 +135,47 @@ int ivtv_queue_move(struct ivtv_stream *s, struct ivtv_queue *from, struct ivtv_
        }
 
        bytes_available = from_free ? from->length : from->bytesused;
-       bytes_available += steal ? steal->length : 0;
+       bytes_steal = (from_free && steal) ? steal->length : 0;
 
-       if (bytes_available < needed_bytes) {
+       if (bytes_available + bytes_steal < needed_bytes) {
                spin_unlock_irqrestore(&s->qlock, flags);
                return -ENOMEM;
        }
+       while (bytes_available < needed_bytes) {
+               struct ivtv_buffer *buf = list_entry(steal->list.prev, struct ivtv_buffer, list);
+               u16 dma_xfer_cnt = buf->dma_xfer_cnt;
+
+               /* move buffers from the tail of the 'steal' queue to the tail of the
+                  'from' queue. Always copy all the buffers with the same dma_xfer_cnt
+                  value, this ensures that you do not end up with partial frame data
+                  if one frame is stored in multiple buffers. */
+               while (dma_xfer_cnt == buf->dma_xfer_cnt) {
+                       list_move_tail(steal->list.prev, &from->list);
+                       rc++;
+                       steal->buffers--;
+                       steal->length -= s->buf_size;
+                       steal->bytesused -= buf->bytesused - buf->readpos;
+                       buf->bytesused = buf->readpos = buf->b_flags = buf->dma_xfer_cnt = 0;
+                       from->buffers++;
+                       from->length += s->buf_size;
+                       bytes_available += s->buf_size;
+                       if (list_empty(&steal->list))
+                               break;
+                       buf = list_entry(steal->list.prev, struct ivtv_buffer, list);
+               }
+       }
        if (from_free) {
                u32 old_length = to->length;
 
                while (to->length - old_length < needed_bytes) {
-                       if (list_empty(&from->list))
-                               from = steal;
-                       if (from == steal)
-                               rc++;           /* keep track of 'stolen' buffers */
-                       ivtv_queue_move_buf(s, from, to, 1, 0);
+                       ivtv_queue_move_buf(s, from, to, 1);
                }
        }
        else {
                u32 old_bytesused = to->bytesused;
 
                while (to->bytesused - old_bytesused < needed_bytes) {
-                       if (list_empty(&from->list))
-                               from = steal;
-                       if (from == steal)
-                               rc++;           /* keep track of 'stolen' buffers */
-                       ivtv_queue_move_buf(s, from, to, to_free, rc);
+                       ivtv_queue_move_buf(s, from, to, to_free);
                }
        }
        spin_unlock_irqrestore(&s->qlock, flags);
@@ -185,7 +193,7 @@ void ivtv_flush_queues(struct ivtv_stream *s)
 int ivtv_stream_alloc(struct ivtv_stream *s)
 {
        struct ivtv *itv = s->itv;
-       int SGsize = sizeof(struct ivtv_SG_element) * s->buffers;
+       int SGsize = sizeof(struct ivtv_sg_element) * s->buffers;
        int i;
 
        if (s->buffers == 0)
@@ -195,27 +203,33 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
                s->dma != PCI_DMA_NONE ? "DMA " : "",
                s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
 
-       if (ivtv_might_use_pio(s)) {
-               s->PIOarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
-               if (s->PIOarray == NULL) {
-                       IVTV_ERR("Could not allocate PIOarray for %s stream\n", s->name);
-                       return -ENOMEM;
-               }
+       s->sg_pending = kzalloc(SGsize, GFP_KERNEL);
+       if (s->sg_pending == NULL) {
+               IVTV_ERR("Could not allocate sg_pending for %s stream\n", s->name);
+               return -ENOMEM;
        }
+       s->sg_pending_size = 0;
 
-       /* Allocate DMA SG Arrays */
-       s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
-       if (s->SGarray == NULL) {
-               IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
-               if (ivtv_might_use_pio(s)) {
-                       kfree(s->PIOarray);
-                       s->PIOarray = NULL;
-               }
+       s->sg_processing = kzalloc(SGsize, GFP_KERNEL);
+       if (s->sg_processing == NULL) {
+               IVTV_ERR("Could not allocate sg_processing for %s stream\n", s->name);
+               kfree(s->sg_pending);
+               s->sg_pending = NULL;
+               return -ENOMEM;
+       }
+       s->sg_processing_size = 0;
+
+       s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element), GFP_KERNEL);
+       if (s->sg_dma == NULL) {
+               IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name);
+               kfree(s->sg_pending);
+               s->sg_pending = NULL;
+               kfree(s->sg_processing);
+               s->sg_processing = NULL;
                return -ENOMEM;
        }
-       s->SG_length = 0;
        if (ivtv_might_use_dma(s)) {
-               s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, s->dma);
+               s->sg_handle = pci_map_single(itv->dev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma);
                ivtv_stream_sync_for_cpu(s);
        }
 
@@ -262,16 +276,19 @@ void ivtv_stream_free(struct ivtv_stream *s)
        }
 
        /* Free SG Array/Lists */
-       if (s->SGarray != NULL) {
-               if (s->SG_handle != IVTV_DMA_UNMAPPED) {
-                       pci_unmap_single(s->itv->dev, s->SG_handle,
-                                sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
-                       s->SG_handle = IVTV_DMA_UNMAPPED;
+       if (s->sg_dma != NULL) {
+               if (s->sg_handle != IVTV_DMA_UNMAPPED) {
+                       pci_unmap_single(s->itv->dev, s->sg_handle,
+                                sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
+                       s->sg_handle = IVTV_DMA_UNMAPPED;
                }
-               kfree(s->SGarray);
-               kfree(s->PIOarray);
-               s->PIOarray = NULL;
-               s->SGarray = NULL;
-               s->SG_length = 0;
+               kfree(s->sg_pending);
+               kfree(s->sg_processing);
+               kfree(s->sg_dma);
+               s->sg_pending = NULL;
+               s->sg_processing = NULL;
+               s->sg_dma = NULL;
+               s->sg_pending_size = 0;
+               s->sg_processing_size = 0;
        }
 }
index 2ed8d548255d95f58b31bdc38e8db9df63e1cc2b..7cfc0c9ab050ca781386068ea3c1f0fd1d671e25 100644 (file)
@@ -19,6 +19,9 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_QUEUE_H
+#define IVTV_QUEUE_H
+
 #define IVTV_DMA_UNMAPPED      ((u32) -1)
 #define SLICED_VBI_PIO 1
 
@@ -79,13 +82,15 @@ void ivtv_stream_free(struct ivtv_stream *s);
 static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
 {
        if (ivtv_use_dma(s))
-               pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
-                       sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
+               pci_dma_sync_single_for_cpu(s->itv->dev, s->sg_handle,
+                       sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
 }
 
 static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
 {
        if (ivtv_use_dma(s))
-               pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
-                       sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
+               pci_dma_sync_single_for_device(s->itv->dev, s->sg_handle,
+                       sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
 }
+
+#endif
similarity index 59%
rename from drivers/media/video/ivtv/ivtv-video.c
rename to drivers/media/video/ivtv/ivtv-routing.c
index 5858b197d51050181fedc4eca72087e210ad79d9..398bd33033ed6f77ca5291b301f96da8ff4e9211 100644 (file)
@@ -1,6 +1,7 @@
 /*
-    saa7127 interface functions
-    Copyright (C) 2004-2007  Hans Verkuil <hverkuil@xs4all.nl>
+    Audio/video-routing-related ivtv functions.
+    Copyright (C) 2003-2004  Kevin Thayer <nufan_wfk at yahoo.com>
+    Copyright (C) 2005-2007  Hans Verkuil <hverkuil@xs4all.nl>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
  */
 
 #include "ivtv-driver.h"
-#include "ivtv-video.h"
 #include "ivtv-i2c.h"
-#include "ivtv-gpio.h"
 #include "ivtv-cards.h"
+#include "ivtv-gpio.h"
+#include "ivtv-routing.h"
+
+#include <media/msp3400.h>
 #include <media/upd64031a.h>
 #include <media/upd64083.h>
 
-void ivtv_set_vps(struct ivtv *itv, int enabled, u8 vps1, u8 vps2, u8 vps3,
-                 u8 vps4, u8 vps5)
+/* Selects the audio input and output according to the current
+   settings. */
+void ivtv_audio_set_io(struct ivtv *itv)
 {
-       struct v4l2_sliced_vbi_data data;
-
-       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
-               return;
-       data.id = V4L2_SLICED_VPS;
-       data.field = 0;
-       data.line = enabled ? 16 : 0;
-       data.data[4] = vps1;
-       data.data[10] = vps2;
-       data.data[11] = vps3;
-       data.data[12] = vps4;
-       data.data[13] = vps5;
-       ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
-}
+       struct v4l2_routing route;
+       u32 audio_input;
+       int mux_input;
 
-void ivtv_set_cc(struct ivtv *itv, int mode, u8 cc1, u8 cc2, u8 cc3, u8 cc4)
-{
-       struct v4l2_sliced_vbi_data data;
-
-       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
-               return;
-       data.id = V4L2_SLICED_CAPTION_525;
-       data.field = 0;
-       data.line = (mode & 1) ? 21 : 0;
-       data.data[0] = cc1;
-       data.data[1] = cc2;
-       ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
-       data.field = 1;
-       data.line = (mode & 2) ? 21 : 0;
-       data.data[0] = cc3;
-       data.data[1] = cc4;
-       ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
-}
+       /* Determine which input to use */
+       if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
+               audio_input = itv->card->radio_input.audio_input;
+               mux_input = itv->card->radio_input.muxer_input;
+       } else {
+               audio_input = itv->card->audio_inputs[itv->audio_input].audio_input;
+               mux_input = itv->card->audio_inputs[itv->audio_input].muxer_input;
+       }
 
-void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
-{
-       struct v4l2_sliced_vbi_data data;
-
-       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
-               return;
-       /* When using a 50 Hz system, always turn on the
-          wide screen signal with 4x3 ratio as the default.
-          Turning this signal on and off can confuse certain
-          TVs. As far as I can tell there is no reason not to
-          transmit this signal. */
-       if ((itv->std & V4L2_STD_625_50) && !enabled) {
-               enabled = 1;
-               mode = 0x08;  /* 4x3 full format */
+       /* handle muxer chips */
+       route.input = mux_input;
+       route.output = 0;
+       ivtv_i2c_hw(itv, itv->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+
+       route.input = audio_input;
+       if (itv->card->hw_audio & IVTV_HW_MSP34XX) {
+               route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
        }
-       data.id = V4L2_SLICED_WSS_625;
-       data.field = 0;
-       data.line = enabled ? 23 : 0;
-       data.data[0] = mode & 0xff;
-       data.data[1] = (mode >> 8) & 0xff;
-       ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
+       ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, &route);
 }
 
+/* Selects the video input and output according to the current
+   settings. */
 void ivtv_video_set_io(struct ivtv *itv)
 {
        struct v4l2_routing route;
similarity index 80%
rename from drivers/media/video/ivtv/ivtv-audio.h
rename to drivers/media/video/ivtv/ivtv-routing.h
index 9c42846d81245114520d97f029aa77325d8bd51b..c72a9731ca01fd9d66f0a9a8f74c443b2464b98d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Audio-related ivtv functions.
+    Audio/video-routing-related ivtv functions.
     Copyright (C) 2003-2004  Kevin Thayer <nufan_wfk at yahoo.com>
     Copyright (C) 2005-2007  Hans Verkuil <hverkuil@xs4all.nl>
 
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-int ivtv_audio_set_io(struct ivtv *itv);
-void ivtv_audio_set_route(struct ivtv *itv, struct v4l2_routing *route);
-void ivtv_audio_set_audio_clock_freq(struct ivtv *itv, u8 freq);
+#ifndef IVTV_ROUTING_H
+#define IVTV_ROUTING_H
+
+void ivtv_audio_set_io(struct ivtv *itv);
+void ivtv_video_set_io(struct ivtv *itv);
+
+#endif
index 51df3f8550310f2ffdc0b3c5c937ca14ac1bdde1..fd135985e70f8769c4f7cd097cf11c9799490c40 100644 (file)
 
 #include "ivtv-driver.h"
 #include "ivtv-fileops.h"
-#include "ivtv-i2c.h"
 #include "ivtv-queue.h"
 #include "ivtv-mailbox.h"
-#include "ivtv-audio.h"
-#include "ivtv-video.h"
-#include "ivtv-vbi.h"
 #include "ivtv-ioctl.h"
 #include "ivtv-irq.h"
-#include "ivtv-streams.h"
+#include "ivtv-yuv.h"
 #include "ivtv-cards.h"
+#include "ivtv-streams.h"
 
 static struct file_operations ivtv_v4l2_enc_fops = {
       .owner = THIS_MODULE,
@@ -66,6 +63,13 @@ static struct file_operations ivtv_v4l2_dec_fops = {
       .poll = ivtv_v4l2_dec_poll,
 };
 
+#define IVTV_V4L2_DEC_MPG_OFFSET  16   /* offset from 0 to register decoder mpg v4l2 minors on */
+#define IVTV_V4L2_ENC_PCM_OFFSET  24   /* offset from 0 to register pcm v4l2 minors on */
+#define IVTV_V4L2_ENC_YUV_OFFSET  32   /* offset from 0 to register yuv v4l2 minors on */
+#define IVTV_V4L2_DEC_YUV_OFFSET  48   /* offset from 0 to register decoder yuv v4l2 minors on */
+#define IVTV_V4L2_DEC_VBI_OFFSET   8   /* offset from 0 to register decoder vbi input v4l2 minors on */
+#define IVTV_V4L2_DEC_VOUT_OFFSET 16   /* offset from 0 to register vbi output v4l2 minors on */
+
 static struct {
        const char *name;
        int vfl_type;
@@ -75,7 +79,7 @@ static struct {
        struct file_operations *fops;
 } ivtv_stream_info[] = {
        {       /* IVTV_ENC_STREAM_TYPE_MPG */
-               "encoder MPEG",
+               "encoder MPG",
                VFL_TYPE_GRABBER, 0,
                PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
                &ivtv_v4l2_enc_fops
@@ -93,7 +97,7 @@ static struct {
                &ivtv_v4l2_enc_fops
        },
        {       /* IVTV_ENC_STREAM_TYPE_PCM */
-               "encoder PCM audio",
+               "encoder PCM",
                VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET,
                PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE,
                &ivtv_v4l2_enc_fops
@@ -105,7 +109,7 @@ static struct {
                &ivtv_v4l2_enc_fops
        },
        {       /* IVTV_DEC_STREAM_TYPE_MPG */
-               "decoder MPEG",
+               "decoder MPG",
                VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET,
                PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
                &ivtv_v4l2_dec_fops
@@ -150,11 +154,11 @@ static void ivtv_stream_init(struct ivtv *itv, int type)
                s->dma = ivtv_stream_info[type].dma;
        s->buf_size = itv->stream_buf_size[type];
        if (s->buf_size)
-               s->buffers = itv->options.megabytes[type] * 1024 * 1024 / s->buf_size;
+               s->buffers = (itv->options.kilobytes[type] * 1024 + s->buf_size - 1) / s->buf_size;
        spin_lock_init(&s->qlock);
        init_waitqueue_head(&s->waitq);
        s->id = -1;
-       s->SG_handle = IVTV_DMA_UNMAPPED;
+       s->sg_handle = IVTV_DMA_UNMAPPED;
        ivtv_queue_init(&s->q_free);
        ivtv_queue_init(&s->q_full);
        ivtv_queue_init(&s->q_dma);
@@ -192,7 +196,7 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
        /* User explicitly selected 0 buffers for these streams, so don't
           create them. */
        if (minor >= 0 && ivtv_stream_info[type].dma != PCI_DMA_NONE &&
-           itv->options.megabytes[type] == 0) {
+           itv->options.kilobytes[type] == 0) {
                IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name);
                return 0;
        }
@@ -238,18 +242,18 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
 
        switch (vfl_type) {
        case VFL_TYPE_GRABBER:
-               IVTV_INFO("Registered device video%d for %s (%d MB)\n",
-                       s->v4l2dev->minor, s->name, itv->options.megabytes[type]);
+               IVTV_INFO("Registered device video%d for %s (%d kB)\n",
+                       s->v4l2dev->minor, s->name, itv->options.kilobytes[type]);
                break;
        case VFL_TYPE_RADIO:
                IVTV_INFO("Registered device radio%d for %s\n",
                        s->v4l2dev->minor - MINOR_VFL_TYPE_RADIO_MIN, s->name);
                break;
        case VFL_TYPE_VBI:
-               if (itv->options.megabytes[type])
-                       IVTV_INFO("Registered device vbi%d for %s (%d MB)\n",
+               if (itv->options.kilobytes[type])
+                       IVTV_INFO("Registered device vbi%d for %s (%d kB)\n",
                                s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN,
-                               s->name, itv->options.megabytes[type]);
+                               s->name, itv->options.kilobytes[type]);
                else
                        IVTV_INFO("Registered device vbi%d for %s\n",
                                s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN, s->name);
@@ -314,28 +318,9 @@ static void ivtv_vbi_setup(struct ivtv *itv)
        int lines;
        int i;
 
-       /* If Embed then streamtype must be Program */
-       /* TODO: should we really do this? */
-       if (0 && !raw && itv->vbi.insert_mpeg) {
-               itv->params.stream_type = 0;
-
-               /* assign stream type */
-               ivtv_vapi(itv, CX2341X_ENC_SET_STREAM_TYPE, 1, itv->params.stream_type);
-       }
-
        /* Reset VBI */
        ivtv_vapi(itv, CX2341X_ENC_SET_VBI_LINE, 5, 0xffff , 0, 0, 0, 0);
 
-       if (itv->is_60hz) {
-               itv->vbi.count = 12;
-               itv->vbi.start[0] = 10;
-               itv->vbi.start[1] = 273;
-       } else {        /* PAL/SECAM */
-               itv->vbi.count = 18;
-               itv->vbi.start[0] = 6;
-               itv->vbi.start[1] = 318;
-       }
-
        /* setup VBI registers */
        itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
 
@@ -409,8 +394,8 @@ static void ivtv_vbi_setup(struct ivtv *itv)
        if (!itv->vbi.fpi)
                itv->vbi.fpi = 1;
 
-       IVTV_DEBUG_INFO("Setup VBI start 0x%08x frames %d fpi %d lines 0x%08x\n",
-               itv->vbi.enc_start, data[1], itv->vbi.fpi, itv->digitizer);
+       IVTV_DEBUG_INFO("Setup VBI start 0x%08x frames %d fpi %d\n",
+               itv->vbi.enc_start, data[1], itv->vbi.fpi);
 
        /* select VBI lines.
           Note that the sliced argument seems to have no effect. */
@@ -446,9 +431,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
        if (s->v4l2dev == NULL)
                return -EINVAL;
 
-       /* Big serialization lock to ensure no two streams are started
-          simultaneously: that can give all sorts of weird results. */
-       mutex_lock(&itv->serialize_lock);
        IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
 
        switch (s->type) {
@@ -490,7 +472,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
                        0, sizeof(itv->vbi.sliced_mpeg_size));
                break;
        default:
-               mutex_unlock(&itv->serialize_lock);
                return -EINVAL;
        }
        s->subtype = subtype;
@@ -503,6 +484,8 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
        clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
 
        if (atomic_read(&itv->capturing) == 0) {
+               int digitizer;
+
                /* Always use frame based mode. Experiments have demonstrated that byte
                   stream based mode results in dropped frames and corruption. Not often,
                   but occasionally. Many thanks go to Leonard Orb who spent a lot of
@@ -528,7 +511,14 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
                ivtv_vapi(itv, CX2341X_ENC_SET_PLACEHOLDER, 12,
                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 
-               ivtv_vapi(itv, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, itv->digitizer, itv->digitizer);
+               if (itv->card->hw_all & (IVTV_HW_SAA7115 | IVTV_HW_SAA717X))
+                   digitizer = 0xF1;
+               else if (itv->card->hw_all & IVTV_HW_SAA7114)
+                   digitizer = 0xEF;
+               else /* cx25840 */
+                   digitizer = 0x140;
+
+               ivtv_vapi(itv, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, digitizer, digitizer);
 
                /* Setup VBI */
                if (itv->v4l2_cap & V4L2_CAP_VBI_CAPTURE) {
@@ -563,16 +553,16 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
                clear_bit(IVTV_F_I_EOS, &itv->i_flags);
 
                /* Initialize Digitizer for Capture */
+               itv->video_dec_func(itv, VIDIOC_STREAMOFF, 0);
+               ivtv_msleep_timeout(300, 1);
                ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
-
-               ivtv_msleep_timeout(100, 0);
+               itv->video_dec_func(itv, VIDIOC_STREAMON, 0);
        }
 
        /* begin_capture */
        if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype))
        {
                IVTV_DEBUG_WARN( "Error starting capture!\n");
-               mutex_unlock(&itv->serialize_lock);
                return -EINVAL;
        }
 
@@ -588,7 +578,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
 
        /* you're live! sit back and await interrupts :) */
        atomic_inc(&itv->capturing);
-       mutex_unlock(&itv->serialize_lock);
        return 0;
 }
 
@@ -676,10 +665,10 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
        clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
 
        /* Zero out decoder counters */
-       writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_FIELD_DISPLAYED].data[0]);
-       writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_FIELD_DISPLAYED].data[1]);
-       writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_FIELD_DISPLAYED].data[2]);
-       writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_FIELD_DISPLAYED].data[3]);
+       writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[0]);
+       writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[1]);
+       writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[2]);
+       writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA_END].data[3]);
        writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[0]);
        writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[1]);
        writel(0, &itv->dec_mbox.mbox[IVTV_MBOX_DMA].data[2]);
@@ -720,9 +709,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
        struct ivtv *itv = s->itv;
        DECLARE_WAITQUEUE(wait, current);
        int cap_type;
-       unsigned long then;
        int stopmode;
-       u32 data[CX2341X_MBOX_MAX_DATA];
 
        if (s->v4l2dev == NULL)
                return -EINVAL;
@@ -764,15 +751,13 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
        /* when: 0 =  end of GOP  1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */
        ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype);
 
-       then = jiffies;
-
        if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) {
                if (s->type == IVTV_ENC_STREAM_TYPE_MPG && gop_end) {
                        /* only run these if we're shutting down the last cap */
                        unsigned long duration;
+                       unsigned long then = jiffies;
 
-                       then = jiffies;
-                       add_wait_queue(&itv->cap_w, &wait);
+                       add_wait_queue(&itv->eos_waitq, &wait);
 
                        set_current_state(TASK_INTERRUPTIBLE);
 
@@ -798,31 +783,12 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
                                IVTV_DEBUG_INFO("%s: EOS took %lu ms to occur.\n", s->name, duration);
                        }
                        set_current_state(TASK_RUNNING);
-                       remove_wait_queue(&itv->cap_w, &wait);
+                       remove_wait_queue(&itv->eos_waitq, &wait);
+                       set_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
                }
 
-               then = jiffies;
-               /* Make sure DMA is complete */
-               add_wait_queue(&s->waitq, &wait);
-               do {
-                       /* check if DMA is pending */
-                       if ((s->type == IVTV_ENC_STREAM_TYPE_MPG) &&    /* MPG Only */
-                           (read_reg(IVTV_REG_DMASTATUS) & 0x02)) {
-                               /* Check for last DMA */
-                               ivtv_vapi_result(itv, data, CX2341X_ENC_GET_SEQ_END, 2, 0, 0);
-
-                               if (data[0] == 1) {
-                                       IVTV_DEBUG_DMA("%s: Last DMA of size 0x%08x\n", s->name, data[1]);
-                                       break;
-                               }
-                       } else if (read_reg(IVTV_REG_DMASTATUS) & 0x02) {
-                               break;
-                       }
-               } while (!ivtv_msleep_timeout(10, 1) &&
-                        then + msecs_to_jiffies(2000) > jiffies);
-
-               set_current_state(TASK_RUNNING);
-               remove_wait_queue(&s->waitq, &wait);
+               /* Handle any pending interrupts */
+               ivtv_msleep_timeout(100, 1);
        }
 
        atomic_dec(&itv->capturing);
@@ -830,19 +796,16 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
        /* Clear capture and no-read bits */
        clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
 
-       /* ensure these global cleanup actions are done only once */
-       mutex_lock(&itv->serialize_lock);
-
        if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
                ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP);
 
        if (atomic_read(&itv->capturing) > 0) {
-               mutex_unlock(&itv->serialize_lock);
                return 0;
        }
 
        /* Set the following Interrupt mask bits for capture */
        ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
+       del_timer(&itv->dma_timer);
 
        /* event notification (off) */
        if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
@@ -853,7 +816,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
        }
 
        wake_up(&s->waitq);
-       mutex_unlock(&itv->serialize_lock);
 
        return 0;
 }
@@ -900,6 +862,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
        ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
 
        ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
+       del_timer(&itv->dma_timer);
 
        clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
        clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
index 8597b75384a7fe3fcf16c7ca996b3ae4a22a7a5b..8f5f5b1c7c8974f9bf0b4f4077dcfb6ec98b2c05 100644 (file)
@@ -18,6 +18,9 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_STREAMS_H
+#define IVTV_STREAMS_H
+
 int ivtv_streams_setup(struct ivtv *itv);
 void ivtv_streams_cleanup(struct ivtv *itv);
 
@@ -29,3 +32,5 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts);
 
 void ivtv_stop_all_captures(struct ivtv *itv);
 int ivtv_passthrough_mode(struct ivtv *itv, int enable);
+
+#endif
index bd642e1aafc3c11a02f69ffe2d627a62a775b02c..c4626d1cdf41c6f1dcd8757c3871f595001c1b87 100644 (file)
@@ -21,7 +21,6 @@
  */
 
 #include "ivtv-driver.h"
-#include "ivtv-streams.h"
 #include "ivtv-udma.h"
 
 void ivtv_udma_get_page_info(struct ivtv_dma_page_info *dma_page, unsigned long first, unsigned long size)
@@ -38,19 +37,37 @@ void ivtv_udma_get_page_info(struct ivtv_dma_page_info *dma_page, unsigned long
 int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info *dma_page, int map_offset)
 {
        int i, offset;
+       unsigned long flags;
+
+       if (map_offset < 0)
+               return map_offset;
 
        offset = dma_page->offset;
 
        /* Fill SG Array with new values */
        for (i = 0; i < dma_page->page_count; i++) {
-               if (i == dma_page->page_count - 1) {
-                       dma->SGlist[map_offset].length = dma_page->tail;
+               unsigned int len = (i == dma_page->page_count - 1) ?
+                       dma_page->tail : PAGE_SIZE - offset;
+
+               dma->SGlist[map_offset].length = len;
+               dma->SGlist[map_offset].offset = offset;
+               if (PageHighMem(dma->map[map_offset])) {
+                       void *src;
+
+                       if (dma->bouncemap[map_offset] == NULL)
+                               dma->bouncemap[map_offset] = alloc_page(GFP_KERNEL);
+                       if (dma->bouncemap[map_offset] == NULL)
+                               return -1;
+                       local_irq_save(flags);
+                       src = kmap_atomic(dma->map[map_offset], KM_BOUNCE_READ) + offset;
+                       memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
+                       kunmap_atomic(src, KM_BOUNCE_READ);
+                       local_irq_restore(flags);
+                       dma->SGlist[map_offset].page = dma->bouncemap[map_offset];
                }
                else {
-                       dma->SGlist[map_offset].length = PAGE_SIZE - offset;
+                       dma->SGlist[map_offset].page = dma->map[map_offset];
                }
-               dma->SGlist[map_offset].offset = offset;
-               dma->SGlist[map_offset].page = dma->map[map_offset];
                offset = 0;
                map_offset++;
        }
@@ -89,7 +106,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
 {
        struct ivtv_dma_page_info user_dma;
        struct ivtv_user_dma *dma = &itv->udma;
-       int err;
+       int i, err;
 
        IVTV_DEBUG_DMA("ivtv_udma_setup, dst: 0x%08x\n", (unsigned int)ivtv_dest_addr);
 
@@ -123,7 +140,13 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
        dma->page_count = user_dma.page_count;
 
        /* Fill SG List with new values */
-       ivtv_udma_fill_sg_list(dma, &user_dma, 0);
+       if (ivtv_udma_fill_sg_list(dma, &user_dma, 0) < 0) {
+               for (i = 0; i < dma->page_count; i++) {
+                       put_page(dma->map[i]);
+               }
+               dma->page_count = 0;
+               return -ENOMEM;
+       }
 
        /* Map SG List */
        dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
@@ -166,6 +189,8 @@ void ivtv_udma_unmap(struct ivtv *itv)
 
 void ivtv_udma_free(struct ivtv *itv)
 {
+       int i;
+
        /* Unmap SG Array */
        if (itv->udma.SG_handle) {
                pci_unmap_single(itv->dev, itv->udma.SG_handle,
@@ -176,6 +201,11 @@ void ivtv_udma_free(struct ivtv *itv)
        if (itv->udma.SG_length) {
                pci_unmap_sg(itv->dev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
        }
+
+       for (i = 0; i < IVTV_DMA_SG_OSD_ENT; i++) {
+               if (itv->udma.bouncemap[i])
+                       __free_page(itv->udma.bouncemap[i]);
+       }
 }
 
 void ivtv_udma_start(struct ivtv *itv)
index e131bccedec0b753fa2ca3b4168f606d9fd81d52..df727e23be0a4719a57c2e6698821c46a8c1cf3e 100644 (file)
@@ -18,6 +18,9 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_UDMA_H
+#define IVTV_UDMA_H
+
 /* User DMA functions */
 void ivtv_udma_get_page_info(struct ivtv_dma_page_info *dma_page, unsigned long first, unsigned long size);
 int ivtv_udma_fill_sg_list(struct ivtv_user_dma *dma, struct ivtv_dma_page_info *dma_page, int map_offset);
@@ -41,3 +44,5 @@ static inline void ivtv_udma_sync_for_cpu(struct ivtv *itv)
        pci_dma_sync_single_for_cpu((struct pci_dev *)itv->dev, itv->udma.SG_handle,
                sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
 }
+
+#endif
index a7282a91bd9719c029badf20569b1472d5ce24ac..c151bcf5519ae92be2fd189b8f3856f593c04e74 100644 (file)
  */
 
 #include "ivtv-driver.h"
-#include "ivtv-video.h"
-#include "ivtv-vbi.h"
+#include "ivtv-i2c.h"
 #include "ivtv-ioctl.h"
 #include "ivtv-queue.h"
+#include "ivtv-vbi.h"
+
+static void ivtv_set_vps(struct ivtv *itv, int enabled)
+{
+       struct v4l2_sliced_vbi_data data;
+
+       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+               return;
+       data.id = V4L2_SLICED_VPS;
+       data.field = 0;
+       data.line = enabled ? 16 : 0;
+       data.data[2] = itv->vbi.vps_payload.data[0];
+       data.data[8] = itv->vbi.vps_payload.data[1];
+       data.data[9] = itv->vbi.vps_payload.data[2];
+       data.data[10] = itv->vbi.vps_payload.data[3];
+       data.data[11] = itv->vbi.vps_payload.data[4];
+       ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
+}
+
+static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
+{
+       struct v4l2_sliced_vbi_data data;
+
+       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+               return;
+       data.id = V4L2_SLICED_CAPTION_525;
+       data.field = 0;
+       data.line = (mode & 1) ? 21 : 0;
+       data.data[0] = cc->odd[0];
+       data.data[1] = cc->odd[1];
+       ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
+       data.field = 1;
+       data.line = (mode & 2) ? 21 : 0;
+       data.data[0] = cc->even[0];
+       data.data[1] = cc->even[1];
+       ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
+}
+
+static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
+{
+       struct v4l2_sliced_vbi_data data;
+
+       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+               return;
+       /* When using a 50 Hz system, always turn on the
+          wide screen signal with 4x3 ratio as the default.
+          Turning this signal on and off can confuse certain
+          TVs. As far as I can tell there is no reason not to
+          transmit this signal. */
+       if ((itv->std & V4L2_STD_625_50) && !enabled) {
+               enabled = 1;
+               mode = 0x08;  /* 4x3 full format */
+       }
+       data.id = V4L2_SLICED_WSS_625;
+       data.field = 0;
+       data.line = enabled ? 23 : 0;
+       data.data[0] = mode & 0xff;
+       data.data[1] = (mode >> 8) & 0xff;
+       ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
+}
 
 static int odd_parity(u8 c)
 {
@@ -32,62 +91,50 @@ static int odd_parity(u8 c)
        return c & 1;
 }
 
-static void passthrough_vbi_data(struct ivtv *itv, int cnt)
+void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt)
 {
-       int wss = 0;
-       u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 };
-       u8 vps[13];
+       struct vbi_info *vi = &itv->vbi;
+       struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
        int found_cc = 0;
-       int found_wss = 0;
-       int found_vps = 0;
-       int cc_pos = itv->vbi.cc_pos;
-       int i;
+       size_t i;
 
        for (i = 0; i < cnt; i++) {
-               struct v4l2_sliced_vbi_data *d = itv->vbi.sliced_dec_data + i;
+               const struct v4l2_sliced_vbi_data *d = sliced + i;
 
                if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
-                       found_cc = 1;
                        if (d->field) {
-                               cc[2] = d->data[0];
-                               cc[3] = d->data[1];
+                               cc.even[0] = d->data[0];
+                               cc.even[1] = d->data[1];
                        } else {
-                               cc[0] = d->data[0];
-                               cc[1] = d->data[1];
+                               cc.odd[0] = d->data[0];
+                               cc.odd[1] = d->data[1];
                        }
+                       found_cc = 1;
                }
                else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
-                       memcpy(vps, d->data, sizeof(vps));
-                       found_vps = 1;
+                       struct vbi_vps vps;
+
+                       vps.data[0] = d->data[2];
+                       vps.data[1] = d->data[8];
+                       vps.data[2] = d->data[9];
+                       vps.data[3] = d->data[10];
+                       vps.data[4] = d->data[11];
+                       if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
+                               vi->vps_payload = vps;
+                               set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
+                       }
                }
                else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
-                       wss = d->data[0] | d->data[1] << 8;
-                       found_wss = 1;
-               }
-       }
-
-       if (itv->vbi.wss_found != found_wss || itv->vbi.wss != wss) {
-               itv->vbi.wss = wss;
-               itv->vbi.wss_found = found_wss;
-               set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
-       }
+                       int wss = d->data[0] | d->data[1] << 8;
 
-       if (found_vps || itv->vbi.vps_found) {
-               itv->vbi.vps[0] = vps[2];
-               itv->vbi.vps[1] = vps[8];
-               itv->vbi.vps[2] = vps[9];
-               itv->vbi.vps[3] = vps[10];
-               itv->vbi.vps[4] = vps[11];
-               itv->vbi.vps_found = found_vps;
-               set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
+                       if (vi->wss_payload != wss) {
+                               vi->wss_payload = wss;
+                               set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
+                       }
+               }
        }
-
-       if (found_cc && cc_pos < sizeof(itv->vbi.cc_data_even)) {
-               itv->vbi.cc_data_odd[cc_pos] = cc[0];
-               itv->vbi.cc_data_odd[cc_pos + 1] = cc[1];
-               itv->vbi.cc_data_even[cc_pos] = cc[2];
-               itv->vbi.cc_data_even[cc_pos + 1] = cc[3];
-               itv->vbi.cc_pos = cc_pos + 2;
+       if (found_cc && vi->cc_payload_idx < sizeof(vi->cc_payload)) {
+               vi->cc_payload[vi->cc_payload_idx++] = cc;
                set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
        }
 }
@@ -163,8 +210,8 @@ static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
                linemask[1] = 0xf;
                p += 4;
        } else {
-               /* unknown VBI data stream */
-               return 0;
+               /* unknown VBI data, convert to empty VBI frame */
+               linemask[0] = linemask[1] = 0;
        }
        for (i = 0; i < 36; i++) {
                int err = 0;
@@ -211,69 +258,6 @@ static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
        return line * sizeof(itv->vbi.sliced_dec_data[0]);
 }
 
-ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count)
-{
-       /* Should be a __user pointer, but sparse doesn't parse this bit correctly. */
-       const struct v4l2_sliced_vbi_data *p = (const struct v4l2_sliced_vbi_data *)ubuf;
-       u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 };
-       int found_cc = 0;
-       int cc_pos = itv->vbi.cc_pos;
-
-       while (count >= sizeof(struct v4l2_sliced_vbi_data)) {
-               switch (p->id) {
-               case V4L2_SLICED_CAPTION_525:
-                       if (p->line == 21) {
-                               found_cc = 1;
-                               if (p->field) {
-                                       cc[2] = p->data[0];
-                                       cc[3] = p->data[1];
-                               } else {
-                                       cc[0] = p->data[0];
-                                       cc[1] = p->data[1];
-                               }
-                       }
-                       break;
-
-               case V4L2_SLICED_VPS:
-                       if (p->line == 16 && p->field == 0) {
-                               itv->vbi.vps[0] = p->data[2];
-                               itv->vbi.vps[1] = p->data[8];
-                               itv->vbi.vps[2] = p->data[9];
-                               itv->vbi.vps[3] = p->data[10];
-                               itv->vbi.vps[4] = p->data[11];
-                               itv->vbi.vps_found = 1;
-                               set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
-                       }
-                       break;
-
-               case V4L2_SLICED_WSS_625:
-                       if (p->line == 23 && p->field == 0) {
-                               /* No lock needed for WSS */
-                               itv->vbi.wss = p->data[0] | (p->data[1] << 8);
-                               itv->vbi.wss_found = 1;
-                               set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
-                       }
-                       break;
-
-               default:
-                       break;
-               }
-               count -= sizeof(*p);
-               p++;
-       }
-
-       if (found_cc && cc_pos < sizeof(itv->vbi.cc_data_even)) {
-               itv->vbi.cc_data_odd[cc_pos] = cc[0];
-               itv->vbi.cc_data_odd[cc_pos + 1] = cc[1];
-               itv->vbi.cc_data_even[cc_pos] = cc[2];
-               itv->vbi.cc_data_even[cc_pos + 1] = cc[3];
-               itv->vbi.cc_pos = cc_pos + 2;
-               set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
-       }
-
-       return (const char __user *)p - ubuf;
-}
-
 /* Compress raw VBI format, removes leading SAV codes and surplus space after the
    field.
    Returns new compressed size. */
@@ -422,108 +406,95 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
                memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
                buf->bytesused = cnt;
 
-               passthrough_vbi_data(itv, cnt / sizeof(itv->vbi.sliced_dec_data[0]));
+               ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
+                              cnt / sizeof(itv->vbi.sliced_dec_data[0]));
                return;
        }
 }
 
-void ivtv_disable_vbi(struct ivtv *itv)
+void ivtv_disable_cc(struct ivtv *itv)
 {
-       clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
-       clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
+       struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
+
        clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
-       ivtv_set_wss(itv, 0, 0);
-       ivtv_set_cc(itv, 0, 0, 0, 0, 0);
-       ivtv_set_vps(itv, 0, 0, 0, 0, 0, 0);
-       itv->vbi.vps_found = itv->vbi.wss_found = 0;
-       itv->vbi.wss = 0;
-       itv->vbi.cc_pos = 0;
+       ivtv_set_cc(itv, 0, &cc);
+       itv->vbi.cc_payload_idx = 0;
 }
 
 
 void ivtv_vbi_work_handler(struct ivtv *itv)
 {
+       struct vbi_info *vi = &itv->vbi;
        struct v4l2_sliced_vbi_data data;
+       struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
 
        /* Lock */
        if (itv->output_mode == OUT_PASSTHROUGH) {
-               /* Note: currently only the saa7115 is used in a PVR350,
-                  so these commands are for now saa7115 specific. */
                if (itv->is_50hz) {
                        data.id = V4L2_SLICED_WSS_625;
                        data.field = 0;
 
                        if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
                                ivtv_set_wss(itv, 1, data.data[0] & 0xf);
-                               itv->vbi.wss_no_update = 0;
-                       } else if (itv->vbi.wss_no_update == 4) {
+                               vi->wss_missing_cnt = 0;
+                       } else if (vi->wss_missing_cnt == 4) {
                                ivtv_set_wss(itv, 1, 0x8);  /* 4x3 full format */
                        } else {
-                               itv->vbi.wss_no_update++;
+                               vi->wss_missing_cnt++;
                        }
                }
                else {
-                       u8 c1 = 0, c2 = 0, c3 = 0, c4 = 0;
                        int mode = 0;
 
                        data.id = V4L2_SLICED_CAPTION_525;
                        data.field = 0;
                        if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
                                mode |= 1;
-                               c1 = data.data[0];
-                               c2 = data.data[1];
+                               cc.odd[0] = data.data[0];
+                               cc.odd[1] = data.data[1];
                        }
                        data.field = 1;
                        if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
                                mode |= 2;
-                               c3 = data.data[0];
-                               c4 = data.data[1];
+                               cc.even[0] = data.data[0];
+                               cc.even[1] = data.data[1];
                        }
                        if (mode) {
-                               itv->vbi.cc_no_update = 0;
-                               ivtv_set_cc(itv, mode, c1, c2, c3, c4);
-                       } else if (itv->vbi.cc_no_update == 4) {
-                               ivtv_set_cc(itv, 0, 0, 0, 0, 0);
+                               vi->cc_missing_cnt = 0;
+                               ivtv_set_cc(itv, mode, &cc);
+                       } else if (vi->cc_missing_cnt == 4) {
+                               ivtv_set_cc(itv, 0, &cc);
                        } else {
-                               itv->vbi.cc_no_update++;
+                               vi->cc_missing_cnt++;
                        }
                }
                return;
        }
 
        if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
-               /* Lock */
-               ivtv_set_wss(itv, itv->vbi.wss_found, itv->vbi.wss & 0xf);
+               ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
        }
 
-       if (test_and_clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
-               if (itv->vbi.cc_pos == 0) {
-                       ivtv_set_cc(itv, 3, 0x80, 0x80, 0x80, 0x80);
+       if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
+               if (vi->cc_payload_idx == 0) {
+                       clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
+                       ivtv_set_cc(itv, 3, &cc);
                }
-               while (itv->vbi.cc_pos) {
-                       u8 cc_odd0 = itv->vbi.cc_data_odd[0];
-                       u8 cc_odd1 = itv->vbi.cc_data_odd[1];
-                       u8 cc_even0 = itv->vbi.cc_data_even[0];
-                       u8 cc_even1 = itv->vbi.cc_data_even[1];
-
-                       memcpy(itv->vbi.cc_data_odd, itv->vbi.cc_data_odd + 2, sizeof(itv->vbi.cc_data_odd) - 2);
-                       memcpy(itv->vbi.cc_data_even, itv->vbi.cc_data_even + 2, sizeof(itv->vbi.cc_data_even) - 2);
-                       itv->vbi.cc_pos -= 2;
-                       if (itv->vbi.cc_pos && cc_odd0 == 0x80 && cc_odd1 == 0x80)
+               while (vi->cc_payload_idx) {
+                       cc = vi->cc_payload[0];
+
+                       memcpy(vi->cc_payload, vi->cc_payload + 1,
+                                       sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
+                       vi->cc_payload_idx--;
+                       if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
                                continue;
 
-                       /* Send to Saa7127 */
-                       ivtv_set_cc(itv, 3, cc_odd0, cc_odd1, cc_even0, cc_even1);
-                       if (itv->vbi.cc_pos == 0)
-                               set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
+                       ivtv_set_cc(itv, 3, &cc);
                        break;
                }
        }
 
        if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
-               /* Lock */
-               ivtv_set_vps(itv, itv->vbi.vps_found,
-                       itv->vbi.vps[0], itv->vbi.vps[1],
-                       itv->vbi.vps[2], itv->vbi.vps[3], itv->vbi.vps[4]);
+               ivtv_set_vps(itv, 1);
        }
 }
index ec211b49702cc975427fdbee35c7a5bea9d5abdb..970567b9194dafa24d6dfb6025efc5adc9e6b11b 100644 (file)
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count);
+#ifndef IVTV_VBI_H
+#define IVTV_VBI_H
+
+void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t count);
 void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
                           u64 pts_stamp, int streamtype);
 int ivtv_used_line(struct ivtv *itv, int line, int field);
-void ivtv_disable_vbi(struct ivtv *itv);
+void ivtv_disable_cc(struct ivtv *itv);
 void ivtv_set_vbi(unsigned long arg);
 void ivtv_vbi_work_handler(struct ivtv *itv);
+
+#endif
index 85530a3cd36929de3b34ce2855933cc1cffff7c0..d050de2a7229cc2e9bbf37ad77be2b30dbb60958 100644 (file)
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_VERSION_H
+#define IVTV_VERSION_H
+
 #define IVTV_DRIVER_NAME "ivtv"
 #define IVTV_DRIVER_VERSION_MAJOR 1
-#define IVTV_DRIVER_VERSION_MINOR 0
+#define IVTV_DRIVER_VERSION_MINOR 1
 #define IVTV_DRIVER_VERSION_PATCHLEVEL 0
 
 #define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL)
 #define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL)
+
+#endif
index bcea09542e5ae903493c71e2a7584dc9680525cf..e2288f224ab699b2a27688d0cb33d455d5ceb5ea 100644 (file)
  */
 
 #include "ivtv-driver.h"
-#include "ivtv-queue.h"
 #include "ivtv-udma.h"
-#include "ivtv-irq.h"
 #include "ivtv-yuv.h"
 
+const u32 yuv_offset[4] = {
+       IVTV_YUV_BUFFER_OFFSET,
+       IVTV_YUV_BUFFER_OFFSET_1,
+       IVTV_YUV_BUFFER_OFFSET_2,
+       IVTV_YUV_BUFFER_OFFSET_3
+};
+
 static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
                                 struct ivtv_dma_frame *args)
 {
@@ -37,7 +42,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
        int y_decode_height, uv_decode_height, y_size;
        int frame = atomic_read(&itv->yuv_info.next_fill_frame);
 
-       y_buffer_offset = IVTV_DEC_MEM_START + yuv_offset[frame];
+       y_buffer_offset = IVTV_DECODER_OFFSET + yuv_offset[frame];
        uv_buffer_offset = y_buffer_offset + IVTV_YUV_BUFFER_UV_OFFSET;
 
        y_decode_height = uv_decode_height = args->src.height + args->src.top;
@@ -83,7 +88,14 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
        }
 
        /* Fill & map SG List */
-       ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0));
+       if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) {
+               IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n");
+               for (i = 0; i < dma->page_count; i++) {
+                       put_page(dma->map[i]);
+               }
+               dma->page_count = 0;
+               return -ENOMEM;
+       }
        dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
 
        /* Fill SG Array with new values */
@@ -94,7 +106,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
                if (itv->yuv_info.blanking_dmaptr) {
                        dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16);
                        dma->SGarray[dma->SG_length].src = cpu_to_le32(itv->yuv_info.blanking_dmaptr);
-                       dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DEC_MEM_START + yuv_offset[frame]);
+                       dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]);
                        dma->SG_length++;
                }
        }
@@ -612,7 +624,6 @@ static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *wi
                itv->yuv_info.v_filter_2 = v_filter_2;
        }
 
-       itv->yuv_info.frame_interlaced_last = itv->yuv_info.frame_interlaced;
 }
 
 /* Modify the supplied coordinate information to fit the visible osd area */
@@ -799,6 +810,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo
            (itv->yuv_info.old_frame_info.src_y != window->src_y) ||
            (itv->yuv_info.old_frame_info.pan_y != window->pan_y) ||
            (itv->yuv_info.old_frame_info.vis_h != window->vis_h) ||
+           (itv->yuv_info.old_frame_info.lace_mode != window->lace_mode) ||
            (itv->yuv_info.old_frame_info.interlaced_y != window->interlaced_y) ||
            (itv->yuv_info.old_frame_info.interlaced_uv != window->interlaced_uv)) {
                yuv_update |= IVTV_YUV_UPDATE_VERTICAL;
@@ -898,8 +910,21 @@ static void ivtv_yuv_init (struct ivtv *itv)
                itv->yuv_info.decode_height = 480;
 
        /* If no visible size set, assume full size */
-       if (!itv->yuv_info.osd_vis_w) itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset;
-       if (!itv->yuv_info.osd_vis_h) itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+       if (!itv->yuv_info.osd_vis_w)
+               itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset;
+
+       if (!itv->yuv_info.osd_vis_h) {
+               itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+       } else {
+               /* If output video standard has changed, requested height may
+               not be legal */
+               if (itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset > itv->yuv_info.decode_height) {
+                       IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
+                                       itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset,
+                                       itv->yuv_info.decode_height);
+                       itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+               }
+       }
 
        /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
        itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL);
@@ -927,6 +952,7 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
        int rc = 0;
        int got_sig = 0;
        int frame, next_fill_frame, last_fill_frame;
+       int register_update = 0;
 
        IVTV_DEBUG_INFO("yuv_prep_frame\n");
 
@@ -940,6 +966,7 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
                /* Buffers are full - Overwrite the last frame */
                next_fill_frame = frame;
                frame = (frame - 1) & 3;
+               register_update = itv->yuv_info.new_frame_info[frame].update;
        }
 
        /* Take a snapshot of the yuv coordinate information */
@@ -955,6 +982,9 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
        itv->yuv_info.new_frame_info[frame].tru_w = args->src_width;
        itv->yuv_info.new_frame_info[frame].tru_h = args->src_height;
 
+       /* Snapshot field order */
+       itv->yuv_info.sync_field[frame] = itv->yuv_info.lace_sync_field;
+
        /* Are we going to offset the Y plane */
        if (args->src.height + args->src.top < 512-16)
                itv->yuv_info.new_frame_info[frame].offset_y = 1;
@@ -970,6 +1000,7 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
        itv->yuv_info.new_frame_info[frame].update = 0;
        itv->yuv_info.new_frame_info[frame].interlaced_y = 0;
        itv->yuv_info.new_frame_info[frame].interlaced_uv = 0;
+       itv->yuv_info.new_frame_info[frame].lace_mode = itv->yuv_info.lace_mode;
 
        if (memcmp (&itv->yuv_info.old_frame_info_args, &itv->yuv_info.new_frame_info[frame],
            sizeof (itv->yuv_info.new_frame_info[frame]))) {
@@ -978,6 +1009,14 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
 /*             IVTV_DEBUG_YUV ("Requesting register update for frame %d\n",frame); */
        }
 
+       itv->yuv_info.new_frame_info[frame].update |= register_update;
+
+       /* Should this frame be delayed ? */
+       if (itv->yuv_info.sync_field[frame] != itv->yuv_info.sync_field[(frame - 1) & 3])
+               itv->yuv_info.field_delay[frame] = 1;
+       else
+               itv->yuv_info.field_delay[frame] = 0;
+
        /* DMA the frame */
        mutex_lock(&itv->udma.lock);
 
index 88972d3f77c4c30075137fa50ae9b5e9b528cccc..f7215eeca01829bfbab4dd0d79f56fde01944e34 100644 (file)
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef IVTV_YUV_H
+#define IVTV_YUV_H
+
+/* Buffers on hardware offsets */
+#define IVTV_YUV_BUFFER_OFFSET    0x001a8600   /* First YUV Buffer */
+#define IVTV_YUV_BUFFER_OFFSET_1  0x00240400   /* Second YUV Buffer */
+#define IVTV_YUV_BUFFER_OFFSET_2  0x002d8200   /* Third YUV Buffer */
+#define IVTV_YUV_BUFFER_OFFSET_3  0x00370000   /* Fourth YUV Buffer */
+#define IVTV_YUV_BUFFER_UV_OFFSET 0x65400      /* Offset to UV Buffer */
+
+/* Offset to filter table in firmware */
+#define IVTV_YUV_HORIZONTAL_FILTER_OFFSET 0x025d8
+#define IVTV_YUV_VERTICAL_FILTER_OFFSET 0x03358
+
+#define IVTV_YUV_UPDATE_HORIZONTAL  0x01
+#define IVTV_YUV_UPDATE_VERTICAL    0x02
+
+extern const u32 yuv_offset[4];
+
 int ivtv_yuv_filter_check(struct ivtv *itv);
 int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args);
 void ivtv_yuv_close(struct ivtv *itv);
 void ivtv_yuv_work_handler (struct ivtv *itv);
+
+#endif
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
new file mode 100644 (file)
index 0000000..9684048
--- /dev/null
@@ -0,0 +1,1190 @@
+/*
+    On Screen Display cx23415 Framebuffer driver
+
+    This module presents the cx23415 OSD (onscreen display) framebuffer memory
+    as a standard Linux /dev/fb style framebuffer device. The framebuffer has
+    support for 8, 16 & 32 bpp packed pixel formats with alpha channel. In 16bpp
+    mode, there is a choice of a three color depths (12, 15 or 16 bits), but no
+    local alpha. The colorspace is selectable between rgb & yuv.
+    Depending on the TV standard configured in the ivtv module at load time,
+    the initial resolution is either 640x400 (NTSC) or 640x480 (PAL) at 8bpp.
+    Video timings are locked to ensure a vertical refresh rate of 50Hz (PAL)
+    or 59.94 (NTSC)
+
+    Copyright (c) 2003 Matt T. Yourst <yourst@yourst.com>
+
+    Derived from drivers/video/vesafb.c
+    Portions (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+
+    2.6 kernel port:
+    Copyright (C) 2004 Matthias Badaire
+
+    Copyright (C) 2004  Chris Kennedy <c@groovy.org>
+
+    Copyright (C) 2006  Ian Armstrong <ian@iarmst.demon.co.uk>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fb.h>
+#include <linux/ivtvfb.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include "ivtv-driver.h"
+#include "ivtv-udma.h"
+#include "ivtv-mailbox.h"
+
+/* card parameters */
+static int ivtvfb_card_id = -1;
+static int ivtvfb_debug = 0;
+static int osd_laced;
+static int osd_compat;
+static int osd_depth;
+static int osd_upper;
+static int osd_left;
+static int osd_yres;
+static int osd_xres;
+
+module_param(ivtvfb_card_id, int, 0444);
+module_param_named(debug,ivtvfb_debug, int, 0644);
+module_param(osd_laced, bool, 0444);
+module_param(osd_compat, bool, 0444);
+module_param(osd_depth, int, 0444);
+module_param(osd_upper, int, 0444);
+module_param(osd_left, int, 0444);
+module_param(osd_yres, int, 0444);
+module_param(osd_xres, int, 0444);
+
+MODULE_PARM_DESC(ivtvfb_card_id,
+                "Only use framebuffer of the specified ivtv card (0-31)\n"
+                "\t\t\tdefault -1: initialize all available framebuffers");
+
+MODULE_PARM_DESC(debug,
+                "Debug level (bitmask). Default: errors only\n"
+                "\t\t\t(debug = 3 gives full debugging)");
+
+MODULE_PARM_DESC(osd_compat,
+                "Compatibility mode - Display size is locked (use for old X drivers)\n"
+                "\t\t\t0=off\n"
+                "\t\t\t1=on\n"
+                "\t\t\tdefault off");
+
+/* Why upper, left, xres, yres, depth, laced ? To match terminology used
+   by fbset.
+   Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
+
+MODULE_PARM_DESC(osd_laced,
+                "Interlaced mode\n"
+                "\t\t\t0=off\n"
+                "\t\t\t1=on\n"
+                "\t\t\tdefault off");
+
+MODULE_PARM_DESC(osd_depth,
+                "Bits per pixel - 8, 16, 32\n"
+                "\t\t\tdefault 8");
+
+MODULE_PARM_DESC(osd_upper,
+                "Vertical start position\n"
+                "\t\t\tdefault 0 (Centered)");
+
+MODULE_PARM_DESC(osd_left,
+                "Horizontal start position\n"
+                "\t\t\tdefault 0 (Centered)");
+
+MODULE_PARM_DESC(osd_yres,
+                "Display height\n"
+                "\t\t\tdefault 480 (PAL)\n"
+                "\t\t\t        400 (NTSC)");
+
+MODULE_PARM_DESC(osd_xres,
+                "Display width\n"
+                "\t\t\tdefault 640");
+
+MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil, John Harvey, Ian Armstrong");
+MODULE_LICENSE("GPL");
+
+/* --------------------------------------------------------------------- */
+
+#define IVTVFB_DBGFLG_WARN  (1 << 0)
+#define IVTVFB_DBGFLG_INFO  (1 << 1)
+
+#define IVTVFB_DEBUG(x, type, fmt, args...) \
+       do { \
+               if ((x) & ivtvfb_debug) \
+                       printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->num , ## args); \
+       } while (0)
+#define IVTVFB_DEBUG_WARN(fmt, args...)  IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args)
+#define IVTVFB_DEBUG_INFO(fmt, args...)  IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args)
+
+/* Standard kernel messages */
+#define IVTVFB_ERR(fmt, args...)   printk(KERN_ERR  "ivtvfb%d: " fmt, itv->num , ## args)
+#define IVTVFB_WARN(fmt, args...)  printk(KERN_WARNING  "ivtvfb%d: " fmt, itv->num , ## args)
+#define IVTVFB_INFO(fmt, args...)  printk(KERN_INFO "ivtvfb%d: " fmt, itv->num , ## args)
+
+/* --------------------------------------------------------------------- */
+
+#define IVTV_OSD_MAX_WIDTH  720
+#define IVTV_OSD_MAX_HEIGHT 576
+
+#define IVTV_OSD_BPP_8      0x00
+#define IVTV_OSD_BPP_16_444 0x03
+#define IVTV_OSD_BPP_16_555 0x02
+#define IVTV_OSD_BPP_16_565 0x01
+#define IVTV_OSD_BPP_32     0x04
+
+struct osd_info {
+       /* Physical base address */
+       unsigned long video_pbase;
+       /* Relative base address (relative to start of decoder memory) */
+       u32 video_rbase;
+       /* Mapped base address */
+       volatile char __iomem *video_vbase;
+       /* Buffer size */
+       u32 video_buffer_size;
+
+#ifdef CONFIG_MTRR
+       /* video_base rounded down as required by hardware MTRRs */
+       unsigned long fb_start_aligned_physaddr;
+       /* video_base rounded up as required by hardware MTRRs */
+       unsigned long fb_end_aligned_physaddr;
+#endif
+
+       /* Current osd mode */
+       int osd_mode;
+
+       /* Store the buffer offset */
+       int set_osd_coords_x;
+       int set_osd_coords_y;
+
+       /* Current dimensions (NOT VISIBLE SIZE!) */
+       int display_width;
+       int display_height;
+       int display_byte_stride;
+
+       /* Current bits per pixel */
+       int bits_per_pixel;
+       int bytes_per_pixel;
+
+       /* Frame buffer stuff */
+       struct fb_info ivtvfb_info;
+       struct fb_var_screeninfo ivtvfb_defined;
+       struct fb_fix_screeninfo ivtvfb_fix;
+};
+
+struct ivtv_osd_coords {
+       unsigned long offset;
+       unsigned long max_offset;
+       int pixel_stride;
+       int lines;
+       int x;
+       int y;
+};
+
+/* --------------------------------------------------------------------- */
+
+/* ivtv API calls for framebuffer related support */
+
+static int ivtvfb_get_framebuffer(struct ivtv *itv, u32 *fbbase,
+                                      u32 *fblength)
+{
+       u32 data[CX2341X_MBOX_MAX_DATA];
+       int rc;
+
+       rc = ivtv_vapi_result(itv, data, CX2341X_OSD_GET_FRAMEBUFFER, 0);
+       *fbbase = data[0];
+       *fblength = data[1];
+       return rc;
+}
+
+static int ivtvfb_get_osd_coords(struct ivtv *itv,
+                                     struct ivtv_osd_coords *osd)
+{
+       struct osd_info *oi = itv->osd_info;
+       u32 data[CX2341X_MBOX_MAX_DATA];
+
+       ivtv_vapi_result(itv, data, CX2341X_OSD_GET_OSD_COORDS, 0);
+
+       osd->offset = data[0] - oi->video_rbase;
+       osd->max_offset = oi->display_width * oi->display_height * 4;
+       osd->pixel_stride = data[1];
+       osd->lines = data[2];
+       osd->x = data[3];
+       osd->y = data[4];
+       return 0;
+}
+
+static int ivtvfb_set_osd_coords(struct ivtv *itv, const struct ivtv_osd_coords *osd)
+{
+       struct osd_info *oi = itv->osd_info;
+
+       oi->display_width = osd->pixel_stride;
+       oi->display_byte_stride = osd->pixel_stride * oi->bytes_per_pixel;
+       oi->set_osd_coords_x += osd->x;
+       oi->set_osd_coords_y = osd->y;
+
+       return ivtv_vapi(itv, CX2341X_OSD_SET_OSD_COORDS, 5,
+                       osd->offset + oi->video_rbase,
+                       osd->pixel_stride,
+                       osd->lines, osd->x, osd->y);
+}
+
+static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
+{
+       int osd_height_limit = itv->is_50hz ? 576 : 480;
+
+       /* Only fail if resolution too high, otherwise fudge the start coords. */
+       if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
+               return -EINVAL;
+
+       /* Ensure we don't exceed display limits */
+       if (ivtv_window->top + ivtv_window->height > osd_height_limit) {
+               IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid height setting (%d, %d)\n",
+                       ivtv_window->top, ivtv_window->height);
+               ivtv_window->top = osd_height_limit - ivtv_window->height;
+       }
+
+       if (ivtv_window->left + ivtv_window->width > IVTV_OSD_MAX_WIDTH) {
+               IVTVFB_DEBUG_WARN("ivtv_ioctl_fb_set_display_window - Invalid width setting (%d, %d)\n",
+                       ivtv_window->left, ivtv_window->width);
+               ivtv_window->left = IVTV_OSD_MAX_WIDTH - ivtv_window->width;
+       }
+
+       /* Set the OSD origin */
+       write_reg((ivtv_window->top << 16) | ivtv_window->left, 0x02a04);
+
+       /* How much to display */
+       write_reg(((ivtv_window->top+ivtv_window->height) << 16) | (ivtv_window->left+ivtv_window->width), 0x02a08);
+
+       /* Pass this info back the yuv handler */
+       itv->yuv_info.osd_vis_w = ivtv_window->width;
+       itv->yuv_info.osd_vis_h = ivtv_window->height;
+       itv->yuv_info.osd_x_offset = ivtv_window->left;
+       itv->yuv_info.osd_y_offset = ivtv_window->top;
+
+       return 0;
+}
+
+static int ivtvfb_prep_dec_dma_to_device(struct ivtv *itv,
+                                 unsigned long ivtv_dest_addr, void __user *userbuf,
+                                 int size_in_bytes)
+{
+       DEFINE_WAIT(wait);
+       int ret = 0;
+       int got_sig = 0;
+
+       mutex_lock(&itv->udma.lock);
+       /* Map User DMA */
+       if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) {
+               mutex_unlock(&itv->udma.lock);
+               IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, "
+                              "Error with get_user_pages: %d bytes, %d pages returned\n",
+                              size_in_bytes, itv->udma.page_count);
+
+               /* get_user_pages must have failed completely */
+               return -EIO;
+       }
+
+       IVTVFB_DEBUG_INFO("ivtvfb_prep_dec_dma_to_device, %d bytes, %d pages\n",
+                      size_in_bytes, itv->udma.page_count);
+
+       ivtv_udma_prepare(itv);
+       prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
+       /* if no UDMA is pending and no UDMA is in progress, then the DMA
+          is finished */
+       while (itv->i_flags & (IVTV_F_I_UDMA_PENDING | IVTV_F_I_UDMA)) {
+               /* don't interrupt if the DMA is in progress but break off
+                  a still pending DMA. */
+               got_sig = signal_pending(current);
+               if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
+                       break;
+               got_sig = 0;
+               schedule();
+       }
+       finish_wait(&itv->dma_waitq, &wait);
+
+       /* Unmap Last DMA Xfer */
+       ivtv_udma_unmap(itv);
+       mutex_unlock(&itv->udma.lock);
+       if (got_sig) {
+               IVTV_DEBUG_INFO("User stopped OSD\n");
+               return -EINTR;
+       }
+
+       return ret;
+}
+
+static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
+                             unsigned long dest_offset, int count)
+{
+       DEFINE_WAIT(wait);
+       struct osd_info *oi = itv->osd_info;
+
+       /* Nothing to do */
+       if (count == 0) {
+               IVTVFB_DEBUG_WARN("ivtvfb_prep_frame: Nothing to do. count = 0\n");
+               return -EINVAL;
+       }
+
+       /* Check Total FB Size */
+       if ((dest_offset + count) > oi->video_buffer_size) {
+               IVTVFB_WARN("ivtvfb_prep_frame: Overflowing the framebuffer %ld, only %d available\n",
+                       dest_offset + count, oi->video_buffer_size);
+               return -E2BIG;
+       }
+
+       /* Not fatal, but will have undesirable results */
+       if ((unsigned long)source & 3)
+               IVTVFB_WARN("ivtvfb_prep_frame: Source address not 32 bit aligned (0x%08lx)\n",
+                       (unsigned long)source);
+
+       if (dest_offset & 3)
+               IVTVFB_WARN("ivtvfb_prep_frame: Dest offset not 32 bit aligned (%ld)\n", dest_offset);
+
+       if (count & 3)
+               IVTVFB_WARN("ivtvfb_prep_frame: Count not a multiple of 4 (%d)\n", count);
+
+       /* Check Source */
+       if (!access_ok(VERIFY_READ, source + dest_offset, count)) {
+               IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n",
+                       (unsigned long)source);
+
+               IVTVFB_DEBUG_WARN("access_ok() failed for offset 0x%08lx source 0x%08lx count %d\n",
+                       dest_offset, (unsigned long)source,
+                       count);
+               return -EINVAL;
+       }
+
+       /* OSD Address to send DMA to */
+       dest_offset += IVTV_DECODER_OFFSET + oi->video_rbase;
+
+       /* Fill Buffers */
+       return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count);
+}
+
+static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+{
+       DEFINE_WAIT(wait);
+       struct ivtv *itv = (struct ivtv *)info->par;
+       int rc = 0;
+
+       switch (cmd) {
+               case FBIOGET_VBLANK: {
+                       struct fb_vblank vblank;
+                       u32 trace;
+
+                       vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
+                                       FB_VBLANK_HAVE_VSYNC;
+                       trace = read_reg(0x028c0) >> 16;
+                       if (itv->is_50hz && trace > 312) trace -= 312;
+                       else if (itv->is_60hz && trace > 262) trace -= 262;
+                       if (trace == 1) vblank.flags |= FB_VBLANK_VSYNCING;
+                       vblank.count = itv->last_vsync_field;
+                       vblank.vcount = trace;
+                       vblank.hcount = 0;
+                       if (copy_to_user((void __user *)arg, &vblank, sizeof(vblank)))
+                               return -EFAULT;
+                       return 0;
+               }
+
+               case FBIO_WAITFORVSYNC:
+                       prepare_to_wait(&itv->vsync_waitq, &wait, TASK_INTERRUPTIBLE);
+                       if (!schedule_timeout(msecs_to_jiffies(50))) rc = -ETIMEDOUT;
+                       finish_wait(&itv->vsync_waitq, &wait);
+                       return rc;
+
+               case IVTVFB_IOC_DMA_FRAME: {
+                       struct ivtvfb_dma_frame args;
+
+                       IVTVFB_DEBUG_INFO("IVTVFB_IOC_DMA_FRAME\n");
+                       if (copy_from_user(&args, (void __user *)arg, sizeof(args)))
+                               return -EFAULT;
+
+                       return ivtvfb_prep_frame(itv, cmd, args.source, args.dest_offset, args.count);
+               }
+
+               default:
+                       IVTVFB_DEBUG_INFO("Unknown ioctl %08x\n", cmd);
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+/* Framebuffer device handling */
+
+static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
+{
+       struct osd_info *oi = itv->osd_info;
+       struct ivtv_osd_coords ivtv_osd;
+       struct v4l2_rect ivtv_window;
+       int osd_mode = -1;
+
+       IVTVFB_DEBUG_INFO("ivtvfb_set_var\n");
+
+       /* Select color space */
+       if (var->nonstd) /* YUV */
+               write_reg(read_reg(0x02a00) | 0x0002000, 0x02a00);
+       else /* RGB  */
+               write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00);
+
+       /* Set the color mode */
+       switch (var->bits_per_pixel) {
+               case 8:
+                       osd_mode = IVTV_OSD_BPP_8;
+                       break;
+               case 32:
+                       osd_mode = IVTV_OSD_BPP_32;
+                       break;
+               case 16:
+                       switch (var->green.length) {
+                       case 4:
+                               osd_mode = IVTV_OSD_BPP_16_444;
+                               break;
+                       case 5:
+                               osd_mode = IVTV_OSD_BPP_16_555;
+                               break;
+                       case 6:
+                               osd_mode = IVTV_OSD_BPP_16_565;
+                               break;
+                       default:
+                               IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
+                       }
+                       break;
+               default:
+                       IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
+       }
+
+       /* Change osd mode if needed.
+          Although rare, things can go wrong. The extra mode
+          change seems to help... */
+       if (osd_mode != -1 && osd_mode != oi->osd_mode) {
+               ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
+               ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
+               oi->osd_mode = osd_mode;
+       }
+
+       oi->bits_per_pixel = var->bits_per_pixel;
+       oi->bytes_per_pixel = var->bits_per_pixel / 8;
+
+       /* Set the flicker filter */
+       switch (var->vmode & FB_VMODE_MASK) {
+               case FB_VMODE_NONINTERLACED: /* Filter on */
+                       ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 1);
+                       break;
+               case FB_VMODE_INTERLACED: /* Filter off */
+                       ivtv_vapi(itv, CX2341X_OSD_SET_FLICKER_STATE, 1, 0);
+                       break;
+               default:
+                       IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid video mode\n");
+       }
+
+       /* Read the current osd info */
+       ivtvfb_get_osd_coords(itv, &ivtv_osd);
+
+       /* Now set the OSD to the size we want */
+       ivtv_osd.pixel_stride = var->xres_virtual;
+       ivtv_osd.lines = var->yres_virtual;
+       ivtv_osd.x = 0;
+       ivtv_osd.y = 0;
+       ivtvfb_set_osd_coords(itv, &ivtv_osd);
+
+       /* Can't seem to find the right API combo for this.
+          Use another function which does what we need through direct register access. */
+       ivtv_window.width = var->xres;
+       ivtv_window.height = var->yres;
+
+       /* Minimum margin cannot be 0, as X won't allow such a mode */
+       if (!var->upper_margin) var->upper_margin++;
+       if (!var->left_margin) var->left_margin++;
+       ivtv_window.top = var->upper_margin - 1;
+       ivtv_window.left = var->left_margin - 1;
+
+       ivtvfb_set_display_window(itv, &ivtv_window);
+
+       /* Force update of yuv registers */
+       itv->yuv_info.yuv_forced_update = 1;
+
+       IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
+                     var->xres, var->yres,
+                     var->xres_virtual, var->yres_virtual,
+                     var->bits_per_pixel);
+
+       IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
+                     var->left_margin, var->upper_margin);
+
+       IVTVFB_DEBUG_INFO("Display filter: %s\n",
+                       (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
+       IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
+
+       return 0;
+}
+
+static int ivtvfb_get_fix(struct ivtv *itv, struct fb_fix_screeninfo *fix)
+{
+       struct osd_info *oi = itv->osd_info;
+
+       IVTVFB_DEBUG_INFO("ivtvfb_get_fix\n");
+       memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+       strcpy(fix->id, "cx23415 TV out");
+       fix->smem_start = oi->video_pbase;
+       fix->smem_len = oi->video_buffer_size;
+       fix->type = FB_TYPE_PACKED_PIXELS;
+       fix->visual = (oi->bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+       fix->xpanstep = 1;
+       fix->ypanstep = 1;
+       fix->ywrapstep = 0;
+       fix->line_length = oi->display_byte_stride;
+       fix->accel = FB_ACCEL_NONE;
+       return 0;
+}
+
+/* Check the requested display mode, returning -EINVAL if we can't
+   handle it. */
+
+static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
+{
+       struct osd_info *oi = itv->osd_info;
+       int osd_height_limit;
+       u32 pixclock, hlimit, vlimit;
+
+       IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
+
+       /* Set base references for mode calcs. */
+       if (itv->is_50hz) {
+               pixclock = 84316;
+               hlimit = 776;
+               vlimit = 591;
+               osd_height_limit = 576;
+       }
+       else {
+               pixclock = 83926;
+               hlimit = 776;
+               vlimit = 495;
+               osd_height_limit = 480;
+       }
+
+       /* Check the bits per pixel */
+       if (osd_compat) {
+               if (var->bits_per_pixel != 32) {
+                       IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
+                       return -EINVAL;
+               }
+       }
+
+       if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
+               var->transp.offset = 24;
+               var->transp.length = 8;
+               var->red.offset = 16;
+               var->red.length = 8;
+               var->green.offset = 8;
+               var->green.length = 8;
+               var->blue.offset = 0;
+               var->blue.length = 8;
+       }
+       else if (var->bits_per_pixel == 16) {
+               /* To find out the true mode, check green length */
+               switch (var->green.length) {
+                       case 4:
+                               var->red.offset = 8;
+                               var->red.length = 4;
+                               var->green.offset = 4;
+                               var->green.length = 4;
+                               var->blue.offset = 0;
+                               var->blue.length = 4;
+                               var->transp.offset = 12;
+                               var->transp.length = 1;
+                               break;
+                       case 5:
+                               var->red.offset = 10;
+                               var->red.length = 5;
+                               var->green.offset = 5;
+                               var->green.length = 5;
+                               var->blue.offset = 0;
+                               var->blue.length = 5;
+                               var->transp.offset = 15;
+                               var->transp.length = 1;
+                               break;
+                       default:
+                               var->red.offset = 11;
+                               var->red.length = 5;
+                               var->green.offset = 5;
+                               var->green.length = 6;
+                               var->blue.offset = 0;
+                               var->blue.length = 5;
+                               var->transp.offset = 0;
+                               var->transp.length = 0;
+                               break;
+               }
+       }
+       else {
+               IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
+               return -EINVAL;
+       }
+
+       /* Check the resolution */
+       if (osd_compat) {
+               if (var->xres != oi->ivtvfb_defined.xres ||
+                   var->yres != oi->ivtvfb_defined.yres ||
+                   var->xres_virtual != oi->ivtvfb_defined.xres_virtual ||
+                   var->yres_virtual != oi->ivtvfb_defined.yres_virtual) {
+                       IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d (virtual %dx%d)\n",
+                               var->xres, var->yres, var->xres_virtual, var->yres_virtual);
+                       return -EINVAL;
+               }
+       }
+       else {
+               if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
+                       IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
+                                       var->xres, var->yres);
+                       return -EINVAL;
+               }
+
+               /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
+               if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
+                   var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
+                   var->xres_virtual < var->xres ||
+                   var->yres_virtual < var->yres) {
+                       IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
+                               var->xres_virtual, var->yres_virtual);
+                       return -EINVAL;
+               }
+       }
+
+       /* Some extra checks if in 8 bit mode */
+       if (var->bits_per_pixel == 8) {
+               /* Width must be a multiple of 4 */
+               if (var->xres & 3) {
+                       IVTVFB_DEBUG_WARN("Invalid resolution for 8bpp: %d\n", var->xres);
+                       return -EINVAL;
+               }
+               if (var->xres_virtual & 3) {
+                       IVTVFB_DEBUG_WARN("Invalid virtual resolution for 8bpp: %d)\n", var->xres_virtual);
+                       return -EINVAL;
+               }
+       }
+       else if (var->bits_per_pixel == 16) {
+               /* Width must be a multiple of 2 */
+               if (var->xres & 1) {
+                       IVTVFB_DEBUG_WARN("Invalid resolution for 16bpp: %d\n", var->xres);
+                       return -EINVAL;
+               }
+               if (var->xres_virtual & 1) {
+                       IVTVFB_DEBUG_WARN("Invalid virtual resolution for 16bpp: %d)\n", var->xres_virtual);
+                       return -EINVAL;
+               }
+       }
+
+       /* Now check the offsets */
+       if (var->xoffset >= var->xres_virtual || var->yoffset >= var->yres_virtual) {
+               IVTVFB_DEBUG_WARN("Invalid offset: %d (%d) %d (%d)\n",
+                       var->xoffset, var->xres_virtual, var->yoffset, var->yres_virtual);
+               return -EINVAL;
+       }
+
+       /* Check pixel format */
+       if (var->nonstd > 1) {
+               IVTVFB_DEBUG_WARN("Invalid nonstd % d\n", var->nonstd);
+               return -EINVAL;
+       }
+
+       /* Check video mode */
+       if (((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) &&
+               ((var->vmode & FB_VMODE_MASK) != FB_VMODE_INTERLACED)) {
+               IVTVFB_DEBUG_WARN("Invalid video mode: %d\n", var->vmode & FB_VMODE_MASK);
+               return -EINVAL;
+       }
+
+       /* Check the left & upper margins
+          If the margins are too large, just center the screen
+          (enforcing margins causes too many problems) */
+
+       if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1) {
+               var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2);
+       }
+       if (var->upper_margin + var->yres > (itv->is_50hz ? 577 : 481)) {
+               var->upper_margin = 1 + (((itv->is_50hz ? 576 : 480) - var->yres) / 2);
+       }
+
+       /* Maintain overall 'size' for a constant refresh rate */
+       var->right_margin = hlimit - var->left_margin - var->xres;
+       var->lower_margin = vlimit - var->upper_margin - var->yres;
+
+       /* Fixed sync times */
+       var->hsync_len = 24;
+       var->vsync_len = 2;
+
+       /* Non-interlaced / interlaced mode is used to switch the OSD filter
+          on or off. Adjust the clock timings to maintain a constant
+          vertical refresh rate. */
+       if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
+               var->pixclock = pixclock / 2;
+       else
+               var->pixclock = pixclock;
+
+       IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
+                     var->xres, var->yres,
+                     var->xres_virtual, var->yres_virtual,
+                     var->bits_per_pixel);
+
+       IVTVFB_DEBUG_INFO("Display position: %d, %d\n",
+                     var->left_margin, var->upper_margin);
+
+       IVTVFB_DEBUG_INFO("Display filter: %s\n",
+                       (var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED ? "on" : "off");
+       IVTVFB_DEBUG_INFO("Color space: %s\n", var->nonstd ? "YUV" : "RGB");
+       return 0;
+}
+
+static int ivtvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+       struct ivtv *itv = (struct ivtv *) info->par;
+       IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
+       return _ivtvfb_check_var(var, itv);
+}
+
+static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+       u32 osd_pan_index;
+       struct ivtv *itv = (struct ivtv *) info->par;
+
+       osd_pan_index = (var->xoffset + (var->yoffset * var->xres_virtual))*var->bits_per_pixel/8;
+       write_reg(osd_pan_index, 0x02A0C);
+
+       /* Pass this info back the yuv handler */
+       itv->yuv_info.osd_x_pan = var->xoffset;
+       itv->yuv_info.osd_y_pan = var->yoffset;
+       /* Force update of yuv registers */
+       itv->yuv_info.yuv_forced_update = 1;
+       return 0;
+}
+
+static int ivtvfb_set_par(struct fb_info *info)
+{
+       int rc = 0;
+       struct ivtv *itv = (struct ivtv *) info->par;
+
+       IVTVFB_DEBUG_INFO("ivtvfb_set_par\n");
+
+       rc = ivtvfb_set_var(itv, &info->var);
+       ivtvfb_pan_display(&info->var, info);
+       ivtvfb_get_fix(itv, &info->fix);
+       return rc;
+}
+
+static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
+                               unsigned blue, unsigned transp,
+                               struct fb_info *info)
+{
+       u32 color, *palette;
+       struct ivtv *itv = (struct ivtv *)info->par;
+
+       if (regno >= info->cmap.len)
+               return -EINVAL;
+
+       color = ((transp & 0xFF00) << 16) |((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);
+       if (info->var.bits_per_pixel <= 8) {
+               write_reg(regno, 0x02a30);
+               write_reg(color, 0x02a34);
+               return 0;
+       }
+       if (regno >= 16)
+               return -EINVAL;
+
+       palette = info->pseudo_palette;
+       if (info->var.bits_per_pixel == 16) {
+               switch (info->var.green.length) {
+                       case 4:
+                               color = ((red & 0xf000) >> 4) |
+                                       ((green & 0xf000) >> 8) |
+                                       ((blue & 0xf000) >> 12);
+                               break;
+                       case 5:
+                               color = ((red & 0xf800) >> 1) |
+                                       ((green & 0xf800) >> 6) |
+                                       ((blue & 0xf800) >> 11);
+                               break;
+                       case 6:
+                               color = (red & 0xf800 ) |
+                                       ((green & 0xfc00) >> 5) |
+                                       ((blue & 0xf800) >> 11);
+                               break;
+               }
+       }
+       palette[regno] = color;
+       return 0;
+}
+
+/* We don't really support blanking. All this does is enable or
+   disable the OSD. */
+static int ivtvfb_blank(int blank_mode, struct fb_info *info)
+{
+       struct ivtv *itv = (struct ivtv *)info->par;
+
+       IVTVFB_DEBUG_INFO("Set blanking mode : %d\n", blank_mode);
+       switch (blank_mode) {
+       case FB_BLANK_UNBLANK:
+               ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1);
+               break;
+       case FB_BLANK_NORMAL:
+       case FB_BLANK_HSYNC_SUSPEND:
+       case FB_BLANK_VSYNC_SUSPEND:
+       case FB_BLANK_POWERDOWN:
+               ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
+               break;
+       }
+       return 0;
+}
+
+static struct fb_ops ivtvfb_ops = {
+       .owner = THIS_MODULE,
+       .fb_check_var   = ivtvfb_check_var,
+       .fb_set_par     = ivtvfb_set_par,
+       .fb_setcolreg   = ivtvfb_setcolreg,
+       .fb_fillrect    = cfb_fillrect,
+       .fb_copyarea    = cfb_copyarea,
+       .fb_imageblit   = cfb_imageblit,
+       .fb_cursor      = NULL,
+       .fb_ioctl       = ivtvfb_ioctl,
+       .fb_pan_display = ivtvfb_pan_display,
+       .fb_blank       = ivtvfb_blank,
+};
+
+/* Initialization */
+
+
+/* Setup our initial video mode */
+static int ivtvfb_init_vidmode(struct ivtv *itv)
+{
+       struct osd_info *oi = itv->osd_info;
+       struct v4l2_rect start_window;
+       int max_height;
+
+       /* Color mode */
+
+       if (osd_compat) osd_depth = 32;
+       if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) osd_depth = 8;
+       oi->bits_per_pixel = osd_depth;
+       oi->bytes_per_pixel = oi->bits_per_pixel / 8;
+
+       /* Invalidate current osd mode to force a mode switch later */
+       oi->osd_mode = -1;
+
+       /* Horizontal size & position */
+
+       if (osd_xres > 720) osd_xres = 720;
+
+       /* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
+       if (osd_depth == 8)
+               osd_xres &= ~3;
+       else if (osd_depth == 16)
+               osd_xres &= ~1;
+
+       if (osd_xres)
+               start_window.width = osd_xres;
+       else
+               start_window.width = osd_compat ? 720: 640;
+
+       /* Check horizontal start (osd_left). */
+       if (osd_left && osd_left + start_window.width > 721) {
+               IVTVFB_ERR("Invalid osd_left - assuming default\n");
+               osd_left = 0;
+       }
+
+       /* Hardware coords start at 0, user coords start at 1. */
+       osd_left--;
+
+       start_window.left = osd_left >= 0 ? osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
+
+       oi->display_byte_stride =
+                       start_window.width * oi->bytes_per_pixel;
+
+       /* Vertical size & position */
+
+       max_height = itv->is_50hz ? 576 : 480;
+
+       if (osd_yres > max_height)
+               osd_yres = max_height;
+
+       if (osd_yres)
+               start_window.height = osd_yres;
+       else
+               start_window.height = osd_compat ? max_height : (itv->is_50hz ? 480 : 400);
+
+       /* Check vertical start (osd_upper). */
+       if (osd_upper + start_window.height > max_height + 1) {
+               IVTVFB_ERR("Invalid osd_upper - assuming default\n");
+               osd_upper = 0;
+       }
+
+       /* Hardware coords start at 0, user coords start at 1. */
+       osd_upper--;
+
+       start_window.top = osd_upper >= 0 ? osd_upper : ((max_height - start_window.height) / 2);
+
+       oi->display_width = start_window.width;
+       oi->display_height = start_window.height;
+
+       /* Generate a valid fb_var_screeninfo */
+
+       oi->ivtvfb_defined.xres = oi->display_width;
+       oi->ivtvfb_defined.yres = oi->display_height;
+       oi->ivtvfb_defined.xres_virtual = oi->display_width;
+       oi->ivtvfb_defined.yres_virtual = oi->display_height;
+       oi->ivtvfb_defined.bits_per_pixel = oi->bits_per_pixel;
+       oi->ivtvfb_defined.vmode = (osd_laced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED);
+       oi->ivtvfb_defined.left_margin = start_window.left + 1;
+       oi->ivtvfb_defined.upper_margin = start_window.top + 1;
+       oi->ivtvfb_defined.accel_flags = FB_ACCEL_NONE;
+       oi->ivtvfb_defined.nonstd = 0;
+
+       /* We've filled in the most data, let the usual mode check
+          routine fill in the rest. */
+       _ivtvfb_check_var(&oi->ivtvfb_defined, itv);
+
+       /* Generate valid fb_fix_screeninfo */
+
+       ivtvfb_get_fix(itv, &oi->ivtvfb_fix);
+
+       /* Generate valid fb_info */
+
+       oi->ivtvfb_info.node = -1;
+       oi->ivtvfb_info.flags = FBINFO_FLAG_DEFAULT;
+       oi->ivtvfb_info.fbops = &ivtvfb_ops;
+       oi->ivtvfb_info.par = itv;
+       oi->ivtvfb_info.var = oi->ivtvfb_defined;
+       oi->ivtvfb_info.fix = oi->ivtvfb_fix;
+       oi->ivtvfb_info.screen_base = (u8 __iomem *)oi->video_vbase;
+       oi->ivtvfb_info.fbops = &ivtvfb_ops;
+
+       /* Supply some monitor specs. Bogus values will do for now */
+       oi->ivtvfb_info.monspecs.hfmin = 8000;
+       oi->ivtvfb_info.monspecs.hfmax = 70000;
+       oi->ivtvfb_info.monspecs.vfmin = 10;
+       oi->ivtvfb_info.monspecs.vfmax = 100;
+
+       /* Allocate color map */
+       if (fb_alloc_cmap(&oi->ivtvfb_info.cmap, 256, 1)) {
+               IVTVFB_ERR("abort, unable to alloc cmap\n");
+               return -ENOMEM;
+       }
+
+       /* Allocate the pseudo palette */
+       oi->ivtvfb_info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
+
+       if (!oi->ivtvfb_info.pseudo_palette) {
+               IVTVFB_ERR("abort, unable to alloc pseudo pallete\n");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/* Find OSD buffer base & size. Add to mtrr. Zero osd buffer. */
+
+static int ivtvfb_init_io(struct ivtv *itv)
+{
+       struct osd_info *oi = itv->osd_info;
+
+       mutex_lock(&itv->serialize_lock);
+       if (ivtv_init_on_first_open(itv)) {
+               mutex_unlock(&itv->serialize_lock);
+               IVTVFB_ERR("Failed to initialize ivtv\n");
+               return -ENXIO;
+       }
+       mutex_unlock(&itv->serialize_lock);
+
+       ivtvfb_get_framebuffer(itv, &oi->video_rbase, &oi->video_buffer_size);
+
+       /* The osd buffer size depends on the number of video buffers allocated
+          on the PVR350 itself. For now we'll hardcode the smallest osd buffer
+          size to prevent any overlap. */
+       oi->video_buffer_size = 1704960;
+
+       oi->video_pbase = itv->base_addr + IVTV_DECODER_OFFSET + oi->video_rbase;
+       oi->video_vbase = itv->dec_mem + oi->video_rbase;
+
+       if (!oi->video_vbase) {
+               IVTVFB_ERR("abort, video memory 0x%x @ 0x%lx isn't mapped!\n",
+                    oi->video_buffer_size, oi->video_pbase);
+               return -EIO;
+       }
+
+       IVTVFB_INFO("Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
+                       oi->video_pbase, oi->video_vbase,
+                       oi->video_buffer_size / 1024);
+
+#ifdef CONFIG_MTRR
+       {
+               /* Find the largest power of two that maps the whole buffer */
+               int size_shift = 31;
+
+               while (!(oi->video_buffer_size & (1 << size_shift))) {
+                       size_shift--;
+               }
+               size_shift++;
+               oi->fb_start_aligned_physaddr = oi->video_pbase & ~((1 << size_shift) - 1);
+               oi->fb_end_aligned_physaddr = oi->video_pbase + oi->video_buffer_size;
+               oi->fb_end_aligned_physaddr += (1 << size_shift) - 1;
+               oi->fb_end_aligned_physaddr &= ~((1 << size_shift) - 1);
+               if (mtrr_add(oi->fb_start_aligned_physaddr,
+                       oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr,
+                            MTRR_TYPE_WRCOMB, 1) < 0) {
+                       IVTVFB_INFO("disabled mttr\n");
+                       oi->fb_start_aligned_physaddr = 0;
+                       oi->fb_end_aligned_physaddr = 0;
+               }
+       }
+#endif
+
+       /* Blank the entire osd. */
+       memset_io(oi->video_vbase, 0, oi->video_buffer_size);
+
+       return 0;
+}
+
+/* Release any memory we've grabbed & remove mtrr entry */
+static void ivtvfb_release_buffers (struct ivtv *itv)
+{
+       struct osd_info *oi = itv->osd_info;
+
+       /* Release cmap */
+       if (oi->ivtvfb_info.cmap.len)
+               fb_dealloc_cmap(&oi->ivtvfb_info.cmap);
+
+       /* Release pseudo palette */
+       if (oi->ivtvfb_info.pseudo_palette)
+               kfree(oi->ivtvfb_info.pseudo_palette);
+
+#ifdef CONFIG_MTRR
+       if (oi->fb_end_aligned_physaddr) {
+               mtrr_del(-1, oi->fb_start_aligned_physaddr,
+                       oi->fb_end_aligned_physaddr - oi->fb_start_aligned_physaddr);
+       }
+#endif
+
+       kfree(oi);
+       itv->osd_info = NULL;
+}
+
+/* Initialize the specified card */
+
+static int ivtvfb_init_card(struct ivtv *itv)
+{
+       int rc;
+
+       if (itv->osd_info) {
+               IVTVFB_ERR("Card %d already initialised\n", ivtvfb_card_id);
+               return -EBUSY;
+       }
+
+       itv->osd_info = kzalloc(sizeof(struct osd_info), GFP_ATOMIC);
+       if (itv->osd_info == 0) {
+               IVTVFB_ERR("Failed to allocate memory for osd_info\n");
+               return -ENOMEM;
+       }
+
+       /* Find & setup the OSD buffer */
+       if ((rc = ivtvfb_init_io(itv)))
+               return rc;
+
+       /* Set the startup video mode information */
+       if ((rc = ivtvfb_init_vidmode(itv))) {
+               ivtvfb_release_buffers(itv);
+               return rc;
+       }
+
+       /* Register the framebuffer */
+       if (register_framebuffer(&itv->osd_info->ivtvfb_info) < 0) {
+               ivtvfb_release_buffers(itv);
+               return -EINVAL;
+       }
+
+       itv->osd_video_pbase = itv->osd_info->video_pbase;
+
+       /* Set the card to the requested mode */
+       ivtvfb_set_par(&itv->osd_info->ivtvfb_info);
+
+       /* Set color 0 to black */
+       write_reg(0, 0x02a30);
+       write_reg(0, 0x02a34);
+
+       /* Enable the osd */
+       ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
+
+       /* Note if we're running in compatibility mode */
+       if (osd_compat)
+               IVTVFB_INFO("Running in compatibility mode. Display resize & mode change disabled\n");
+
+       /* Allocate DMA */
+       ivtv_udma_alloc(itv);
+       return 0;
+
+}
+
+static int __init ivtvfb_init(void)
+{
+       struct ivtv *itv;
+       int i, registered = 0;
+
+       if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) {
+               printk(KERN_ERR "ivtvfb:  ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n",
+                    IVTV_MAX_CARDS - 1);
+               return -EINVAL;
+       }
+
+       /* Locate & initialise all cards supporting an OSD. */
+       for (i = 0; i < ivtv_cards_active; i++) {
+               if (ivtvfb_card_id != -1 && i != ivtvfb_card_id)
+                       continue;
+               itv = ivtv_cards[i];
+               if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+                       if (ivtvfb_init_card(itv) == 0) {
+                               IVTVFB_INFO("Framebuffer registered on ivtv card id %d\n", i);
+                               registered++;
+                       }
+               }
+       }
+       if (!registered) {
+               printk(KERN_ERR "ivtvfb:  no cards found");
+               return -ENODEV;
+       }
+       return 0;
+}
+
+static void ivtvfb_cleanup(void)
+{
+       struct ivtv *itv;
+       int i;
+
+       printk(KERN_INFO "ivtvfb:  Unloading framebuffer module\n");
+
+       for (i = 0; i < ivtv_cards_active; i++) {
+               itv = ivtv_cards[i];
+               if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) {
+                       IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i);
+                       ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info);
+                       unregister_framebuffer(&itv->osd_info->ivtvfb_info);
+                       ivtvfb_release_buffers(itv);
+                       itv->osd_video_pbase = 0;
+               }
+       }
+}
+
+module_init(ivtvfb_init);
+module_exit(ivtvfb_cleanup);
index 11cfcf18ec3431f6e991400f2fb0db29475bf990..c0c87e06259b9c599c62e03ab26e577e28e5c78e 100644 (file)
@@ -244,17 +244,17 @@ int msp_write_dsp(struct i2c_client *client, int addr, int val)
  * ----------------------------------------------------------------------- */
 
 static int scarts[3][9] = {
-       /* MASK   IN1     IN2     IN3     IN4     IN1_DA  IN2_DA  MONO    MUTE   */
+       /* MASK   IN1     IN2     IN3     IN4     IN1_DA  IN2_DA  MONO    MUTE   */
        /* SCART DSP Input select */
-       { 0x0320, 0x0000, 0x0200, 0x0300, 0x0020, -1,     -1,     0x0100, 0x0320 },
+       { 0x0320, 0x0000, 0x0200, 0x0300, 0x0020, -1,     -1,     0x0100, 0x0320 },
        /* SCART1 Output select */
-       { 0x0c40, 0x0440, 0x0400, 0x0000, 0x0840, 0x0c00, 0x0040, 0x0800, 0x0c40 },
+       { 0x0c40, 0x0440, 0x0400, 0x0000, 0x0840, 0x0c00, 0x0040, 0x0800, 0x0c40 },
        /* SCART2 Output select */
-       { 0x3080, 0x1000, 0x1080, 0x2080, 0x3080, 0x0000, 0x0080, 0x2000, 0x3000 },
+       { 0x3080, 0x1000, 0x1080, 0x2080, 0x3080, 0x0000, 0x0080, 0x2000, 0x3000 },
 };
 
 static char *scart_names[] = {
-       "in1", "in2", "in3", "in4", "in1 da", "in2 da", "mono", "mute"
+       "in1", "in2", "in3", "in4", "in1 da", "in2 da", "mono", "mute"
 };
 
 void msp_set_scart(struct i2c_client *client, int in, int out)
@@ -813,8 +813,9 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
        int msp_rom;
 
        client = kzalloc(sizeof(*client), GFP_KERNEL);
-       if (client == NULL)
+       if (!client)
                return -ENOMEM;
+
        client->addr = address;
        client->adapter = adapter;
        client->driver = &i2c_driver;
@@ -826,14 +827,14 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
                return 0;
        }
 
-       state = kmalloc(sizeof(*state), GFP_KERNEL);
-       if (state == NULL) {
+       state = kzalloc(sizeof(*state), GFP_KERNEL);
+       if (!state) {
                kfree(client);
                return -ENOMEM;
        }
+
        i2c_set_clientdata(client, state);
 
-       memset(state, 0, sizeof(*state));
        state->v4l2_std = V4L2_STD_NTSC;
        state->audmode = V4L2_TUNER_MODE_STEREO;
        state->volume = 58880;  /* 0db gain */
index 7549114aaaca3537f48820287b7921ee8061c703..f49d1f4c40db11cf43650e767848ba9310c23845 100644 (file)
@@ -1,13 +1,20 @@
 /*
- *
  * i2c tv tuner chip device driver
  * controls microtune tuners, mt2032 + mt2050 at the moment.
+ *
+ * This "mt20xx" module was split apart from the original "tuner" module.
  */
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/videodev.h>
-#include <linux/moduleparam.h>
-#include "tuner-driver.h"
+#include "tuner-i2c.h"
+#include "mt20xx.h"
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+#define PREFIX "mt20xx "
 
 /* ---------------------------------------------------------------------- */
 
@@ -20,9 +27,6 @@ module_param(tv_antenna,        int, 0644);
 static unsigned int radio_antenna = 0;
 module_param(radio_antenna,     int, 0644);
 
-/* from tuner-core.c */
-extern int tuner_debug;
-
 /* ---------------------------------------------------------------------- */
 
 #define MT2032 0x04
@@ -38,23 +42,34 @@ static char *microtune_part[] = {
 };
 
 struct microtune_priv {
+       struct tuner_i2c_props i2c_props;
+
        unsigned int xogc;
-       unsigned int radio_if2;
+       //unsigned int radio_if2;
+
+       u32 frequency;
 };
 
-static void microtune_release(struct i2c_client *c)
+static int microtune_release(struct dvb_frontend *fe)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
 
-       kfree(t->priv);
-       t->priv = NULL;
+       return 0;
+}
+
+static int microtune_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
 }
 
 // IsSpurInBand()?
-static int mt2032_spurcheck(struct i2c_client *c,
+static int mt2032_spurcheck(struct dvb_frontend *fe,
                            int f1, int f2, int spectrum_from,int spectrum_to)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct microtune_priv *priv = fe->tuner_priv;
        int n1=1,n2,f;
 
        f1=f1/1000; //scale to kHz to avoid 32bit overflows
@@ -82,7 +97,7 @@ static int mt2032_spurcheck(struct i2c_client *c,
        return 1;
 }
 
-static int mt2032_compute_freq(struct i2c_client *c,
+static int mt2032_compute_freq(struct dvb_frontend *fe,
                               unsigned int rfin,
                               unsigned int if1, unsigned int if2,
                               unsigned int spectrum_from,
@@ -91,7 +106,7 @@ static int mt2032_compute_freq(struct i2c_client *c,
                               int *ret_sel,
                               unsigned int xogc) //all in Hz
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct microtune_priv *priv = fe->tuner_priv;
        unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
                desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
 
@@ -141,7 +156,7 @@ static int mt2032_compute_freq(struct i2c_client *c,
                return(-1);
        }
 
-       mt2032_spurcheck(c, lo1freq, desired_lo2,  spectrum_from, spectrum_to);
+       mt2032_spurcheck(fe, lo1freq, desired_lo2,  spectrum_from, spectrum_to);
        // should recalculate lo1 (one step up/down)
 
        // set up MT2032 register map for transfer over i2c
@@ -165,16 +180,16 @@ static int mt2032_compute_freq(struct i2c_client *c,
        return 0;
 }
 
-static int mt2032_check_lo_lock(struct i2c_client *c)
+static int mt2032_check_lo_lock(struct dvb_frontend *fe)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct microtune_priv *priv = fe->tuner_priv;
        int try,lock=0;
        unsigned char buf[2];
 
        for(try=0;try<10;try++) {
                buf[0]=0x0e;
-               i2c_master_send(c,buf,1);
-               i2c_master_recv(c,buf,1);
+               tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
+               tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
                tuner_dbg("mt2032 Reg.E=0x%02x\n",buf[0]);
                lock=buf[0] &0x06;
 
@@ -187,15 +202,15 @@ static int mt2032_check_lo_lock(struct i2c_client *c)
        return lock;
 }
 
-static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
+static int mt2032_optimize_vco(struct dvb_frontend *fe,int sel,int lock)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct microtune_priv *priv = fe->tuner_priv;
        unsigned char buf[2];
        int tad1;
 
        buf[0]=0x0f;
-       i2c_master_send(c,buf,1);
-       i2c_master_recv(c,buf,1);
+       tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
+       tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
        tuner_dbg("mt2032 Reg.F=0x%02x\n",buf[0]);
        tad1=buf[0]&0x07;
 
@@ -218,58 +233,57 @@ static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
 
        buf[0]=0x0f;
        buf[1]=sel;
-       i2c_master_send(c,buf,2);
-       lock=mt2032_check_lo_lock(c);
+       tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
+       lock=mt2032_check_lo_lock(fe);
        return lock;
 }
 
 
-static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
+static void mt2032_set_if_freq(struct dvb_frontend *fe, unsigned int rfin,
                               unsigned int if1, unsigned int if2,
                               unsigned int from, unsigned int to)
 {
        unsigned char buf[21];
        int lint_try,ret,sel,lock=0;
-       struct tuner *t = i2c_get_clientdata(c);
-       struct microtune_priv *priv = t->priv;
+       struct microtune_priv *priv = fe->tuner_priv;
 
        tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
                  rfin,if1,if2,from,to);
 
        buf[0]=0;
-       ret=i2c_master_send(c,buf,1);
-       i2c_master_recv(c,buf,21);
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
+       tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);
 
        buf[0]=0;
-       ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc);
+       ret=mt2032_compute_freq(fe,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc);
        if (ret<0)
                return;
 
        // send only the relevant registers per Rev. 1.2
        buf[0]=0;
-       ret=i2c_master_send(c,buf,4);
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,4);
        buf[5]=5;
-       ret=i2c_master_send(c,buf+5,4);
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,4);
        buf[11]=11;
-       ret=i2c_master_send(c,buf+11,3);
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+11,3);
        if(ret!=3)
                tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
 
        // wait for PLLs to lock (per manual), retry LINT if not.
        for(lint_try=0; lint_try<2; lint_try++) {
-               lock=mt2032_check_lo_lock(c);
+               lock=mt2032_check_lo_lock(fe);
 
                if(optimize_vco)
-                       lock=mt2032_optimize_vco(c,sel,lock);
+                       lock=mt2032_optimize_vco(fe,sel,lock);
                if(lock==6) break;
 
                tuner_dbg("mt2032: re-init PLLs by LINT\n");
                buf[0]=7;
                buf[1]=0x80 +8+priv->xogc; // set LINT to re-init PLLs
-               i2c_master_send(c,buf,2);
+               tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
                mdelay(10);
                buf[1]=8+priv->xogc;
-               i2c_master_send(c,buf,2);
+               tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
        }
 
        if (lock!=6)
@@ -277,19 +291,19 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
 
        buf[0]=2;
        buf[1]=0x20; // LOGC for optimal phase noise
-       ret=i2c_master_send(c,buf,2);
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
        if (ret!=2)
                tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
 }
 
 
-static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
+static int mt2032_set_tv_freq(struct dvb_frontend *fe,
+                             struct analog_parameters *params)
 {
-       struct tuner *t = i2c_get_clientdata(c);
        int if2,from,to;
 
        // signal bandwidth and picture carrier
-       if (t->std & V4L2_STD_525_60) {
+       if (params->std & V4L2_STD_525_60) {
                // NTSC
                from = 40750*1000;
                to   = 46750*1000;
@@ -301,32 +315,64 @@ static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
                if2  = 38900*1000;
        }
 
-       mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
+       mt2032_set_if_freq(fe, params->frequency*62500,
                           1090*1000*1000, if2, from, to);
+
+       return 0;
 }
 
-static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
+static int mt2032_set_radio_freq(struct dvb_frontend *fe,
+                                struct analog_parameters *params)
 {
-       struct tuner *t = i2c_get_clientdata(c);
-       struct microtune_priv *priv = t->priv;
-       int if2 = priv->radio_if2;
+       struct microtune_priv *priv = fe->tuner_priv;
+       int if2;
+
+       if (params->std & V4L2_STD_525_60) {
+               tuner_dbg("pinnacle ntsc\n");
+               if2 = 41300 * 1000;
+       } else {
+               tuner_dbg("pinnacle pal\n");
+               if2 = 33300 * 1000;
+       }
 
        // per Manual for FM tuning: first if center freq. 1085 MHz
-       mt2032_set_if_freq(c, freq * 1000 / 16,
-                             1085*1000*1000,if2,if2,if2);
+       mt2032_set_if_freq(fe, params->frequency * 125 / 2,
+                          1085*1000*1000,if2,if2,if2);
+
+       return 0;
+}
+
+static int mt2032_set_params(struct dvb_frontend *fe,
+                            struct analog_parameters *params)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       int ret = -EINVAL;
+
+       switch (params->mode) {
+       case V4L2_TUNER_RADIO:
+               ret = mt2032_set_radio_freq(fe, params);
+               priv->frequency = params->frequency * 125 / 2;
+               break;
+       case V4L2_TUNER_ANALOG_TV:
+       case V4L2_TUNER_DIGITAL_TV:
+               ret = mt2032_set_tv_freq(fe, params);
+               priv->frequency = params->frequency * 62500;
+               break;
+       }
+
+       return ret;
 }
 
-static struct tuner_operations mt2032_tuner_ops = {
-       .set_tv_freq    = mt2032_set_tv_freq,
-       .set_radio_freq = mt2032_set_radio_freq,
-       .release        = microtune_release,
+static struct dvb_tuner_ops mt2032_tuner_ops = {
+       .set_analog_params = mt2032_set_params,
+       .release           = microtune_release,
+       .get_frequency     = microtune_get_frequency,
 };
 
 // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
-static int mt2032_init(struct i2c_client *c)
+static int mt2032_init(struct dvb_frontend *fe)
 {
-       struct tuner *t = i2c_get_clientdata(c);
-       struct microtune_priv *priv = t->priv;
+       struct microtune_priv *priv = fe->tuner_priv;
        unsigned char buf[21];
        int ret,xogc,xok=0;
 
@@ -335,7 +381,7 @@ static int mt2032_init(struct i2c_client *c)
        buf[2]=0xff;
        buf[3]=0x0f;
        buf[4]=0x1f;
-       ret=i2c_master_send(c,buf+1,4);
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+1,4);
 
        buf[5]=6; // Index register 6
        buf[6]=0xe4;
@@ -343,11 +389,11 @@ static int mt2032_init(struct i2c_client *c)
        buf[8]=0xc3;
        buf[9]=0x4e;
        buf[10]=0xec;
-       ret=i2c_master_send(c,buf+5,6);
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,6);
 
        buf[12]=13;  // Index register 13
        buf[13]=0x32;
-       ret=i2c_master_send(c,buf+12,2);
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+12,2);
 
        // Adjust XOGC (register 7), wait for XOK
        xogc=7;
@@ -355,8 +401,8 @@ static int mt2032_init(struct i2c_client *c)
                tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
                mdelay(10);
                buf[0]=0x0e;
-               i2c_master_send(c,buf,1);
-               i2c_master_recv(c,buf,1);
+               tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
+               tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
                xok=buf[0]&0x01;
                tuner_dbg("mt2032: xok = 0x%02x\n",xok);
                if (xok == 1) break;
@@ -369,32 +415,32 @@ static int mt2032_init(struct i2c_client *c)
                }
                buf[0]=0x07;
                buf[1]=0x88 + xogc;
-               ret=i2c_master_send(c,buf,2);
+               ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
                if (ret!=2)
                        tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
        } while (xok != 1 );
        priv->xogc=xogc;
 
-       memcpy(&t->ops, &mt2032_tuner_ops, sizeof(struct tuner_operations));
+       memcpy(&fe->ops.tuner_ops, &mt2032_tuner_ops, sizeof(struct dvb_tuner_ops));
 
        return(1);
 }
 
-static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna)
+static void mt2050_set_antenna(struct dvb_frontend *fe, unsigned char antenna)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct microtune_priv *priv = fe->tuner_priv;
        unsigned char buf[2];
        int ret;
 
        buf[0] = 6;
        buf[1] = antenna ? 0x11 : 0x10;
-       ret=i2c_master_send(c,buf,2);
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
        tuner_dbg("mt2050: enabled antenna connector %d\n", antenna);
 }
 
-static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned int if2)
+static void mt2050_set_if_freq(struct dvb_frontend *fe,unsigned int freq, unsigned int if2)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct microtune_priv *priv = fe->tuner_priv;
        unsigned int if1=1218*1000*1000;
        unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b;
        int ret;
@@ -426,7 +472,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
        div2a=(lo2/8)-1;
        div2b=lo2-(div2a+1)*8;
 
-       if (tuner_debug > 1) {
+       if (debug > 1) {
                tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2);
                tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",
                          num1,num2,div1a,div1b,div2a,div2b);
@@ -442,7 +488,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
        buf[5]=div2a;
        if(num2!=0) buf[5]=buf[5]|0x40;
 
-       if (tuner_debug > 1) {
+       if (debug > 1) {
                int i;
                tuner_dbg("bufs is: ");
                for(i=0;i<6;i++)
@@ -450,101 +496,131 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
                printk("\n");
        }
 
-       ret=i2c_master_send(c,buf,6);
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,6);
        if (ret!=6)
                tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
 }
 
-static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
+static int mt2050_set_tv_freq(struct dvb_frontend *fe,
+                             struct analog_parameters *params)
 {
-       struct tuner *t = i2c_get_clientdata(c);
        unsigned int if2;
 
-       if (t->std & V4L2_STD_525_60) {
+       if (params->std & V4L2_STD_525_60) {
                // NTSC
                if2 = 45750*1000;
        } else {
                // PAL
                if2 = 38900*1000;
        }
-       if (V4L2_TUNER_DIGITAL_TV == t->mode) {
+       if (V4L2_TUNER_DIGITAL_TV == params->mode) {
                // DVB (pinnacle 300i)
                if2 = 36150*1000;
        }
-       mt2050_set_if_freq(c, freq*62500, if2);
-       mt2050_set_antenna(c, tv_antenna);
+       mt2050_set_if_freq(fe, params->frequency*62500, if2);
+       mt2050_set_antenna(fe, tv_antenna);
+
+       return 0;
 }
 
-static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq)
+static int mt2050_set_radio_freq(struct dvb_frontend *fe,
+                                struct analog_parameters *params)
 {
-       struct tuner *t = i2c_get_clientdata(c);
-       struct microtune_priv *priv = t->priv;
-       int if2 = priv->radio_if2;
+       struct microtune_priv *priv = fe->tuner_priv;
+       int if2;
+
+       if (params->std & V4L2_STD_525_60) {
+               tuner_dbg("pinnacle ntsc\n");
+               if2 = 41300 * 1000;
+       } else {
+               tuner_dbg("pinnacle pal\n");
+               if2 = 33300 * 1000;
+       }
 
-       mt2050_set_if_freq(c, freq * 1000 / 16, if2);
-       mt2050_set_antenna(c, radio_antenna);
+       mt2050_set_if_freq(fe, params->frequency * 125 / 2, if2);
+       mt2050_set_antenna(fe, radio_antenna);
+
+       return 0;
 }
 
-static struct tuner_operations mt2050_tuner_ops = {
-       .set_tv_freq    = mt2050_set_tv_freq,
-       .set_radio_freq = mt2050_set_radio_freq,
-       .release        = microtune_release,
+static int mt2050_set_params(struct dvb_frontend *fe,
+                            struct analog_parameters *params)
+{
+       struct microtune_priv *priv = fe->tuner_priv;
+       int ret = -EINVAL;
+
+       switch (params->mode) {
+       case V4L2_TUNER_RADIO:
+               ret = mt2050_set_radio_freq(fe, params);
+               priv->frequency = params->frequency * 125 / 2;
+               break;
+       case V4L2_TUNER_ANALOG_TV:
+       case V4L2_TUNER_DIGITAL_TV:
+               ret = mt2050_set_tv_freq(fe, params);
+               priv->frequency = params->frequency * 62500;
+               break;
+       }
+
+       return ret;
+}
+
+static struct dvb_tuner_ops mt2050_tuner_ops = {
+       .set_analog_params = mt2050_set_params,
+       .release           = microtune_release,
+       .get_frequency     = microtune_get_frequency,
 };
 
-static int mt2050_init(struct i2c_client *c)
+static int mt2050_init(struct dvb_frontend *fe)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct microtune_priv *priv = fe->tuner_priv;
        unsigned char buf[2];
        int ret;
 
        buf[0]=6;
        buf[1]=0x10;
-       ret=i2c_master_send(c,buf,2); //  power
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); //  power
 
        buf[0]=0x0f;
        buf[1]=0x0f;
-       ret=i2c_master_send(c,buf,2); // m1lo
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2); // m1lo
 
        buf[0]=0x0d;
-       ret=i2c_master_send(c,buf,1);
-       i2c_master_recv(c,buf,1);
+       ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
+       tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
 
        tuner_dbg("mt2050: sro is %x\n",buf[0]);
 
-       memcpy(&t->ops, &mt2050_tuner_ops, sizeof(struct tuner_operations));
+       memcpy(&fe->ops.tuner_ops, &mt2050_tuner_ops, sizeof(struct dvb_tuner_ops));
 
        return 0;
 }
 
-int microtune_init(struct i2c_client *c)
+struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
+                                     struct i2c_adapter* i2c_adap,
+                                     u8 i2c_addr)
 {
        struct microtune_priv *priv = NULL;
-       struct tuner *t = i2c_get_clientdata(c);
        char *name;
        unsigned char buf[21];
        int company_code;
 
        priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL);
        if (priv == NULL)
-               return -ENOMEM;
-       t->priv = priv;
+               return NULL;
+       fe->tuner_priv = priv;
+
+       priv->i2c_props.addr = i2c_addr;
+       priv->i2c_props.adap = i2c_adap;
 
-       priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */
+       //priv->radio_if2 = 10700 * 1000;       /* 10.7MHz - FM radio */
 
        memset(buf,0,sizeof(buf));
 
-       if (t->std & V4L2_STD_525_60) {
-               tuner_dbg("pinnacle ntsc\n");
-               priv->radio_if2 = 41300 * 1000;
-       } else {
-               tuner_dbg("pinnacle pal\n");
-               priv->radio_if2 = 33300 * 1000;
-       }
        name = "unknown";
 
-       i2c_master_send(c,buf,1);
-       i2c_master_recv(c,buf,21);
-       if (tuner_debug) {
+       tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
+       tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);
+       if (debug) {
                int i;
                tuner_dbg("MT20xx hexdump:");
                for(i=0;i<21;i++) {
@@ -563,10 +639,10 @@ int microtune_init(struct i2c_client *c)
                name = microtune_part[buf[0x13]];
        switch (buf[0x13]) {
        case MT2032:
-               mt2032_init(c);
+               mt2032_init(fe);
                break;
        case MT2050:
-               mt2050_init(c);
+               mt2050_init(fe);
                break;
        default:
                tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
@@ -574,11 +650,18 @@ int microtune_init(struct i2c_client *c)
                return 0;
        }
 
-       strlcpy(c->name, name, sizeof(c->name));
+       strlcpy(fe->ops.tuner_ops.info.name, name,
+               sizeof(fe->ops.tuner_ops.info.name));
        tuner_info("microtune %s found, OK\n",name);
-       return 0;
+       return fe;
 }
 
+EXPORT_SYMBOL_GPL(microtune_attach);
+
+MODULE_DESCRIPTION("Microtune tuner driver");
+MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
+MODULE_LICENSE("GPL");
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * ---------------------------------------------------------------------------
diff --git a/drivers/media/video/mt20xx.h b/drivers/media/video/mt20xx.h
new file mode 100644 (file)
index 0000000..5e9c825
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __MT20XX_H__
+#define __MT20XX_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+#if defined(CONFIG_TUNER_MT20XX) || (defined(CONFIG_TUNER_MT20XX_MODULE) && defined(MODULE))
+extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
+                                            struct i2c_adapter* i2c_adap,
+                                            u8 i2c_addr);
+#else
+static inline struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
+                                            struct i2c_adapter* i2c_adap,
+                                            u8 i2c_addr)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+       return NULL;
+}
+#endif
+
+#endif /* __MT20XX_H__ */
index 152cc6b3e1521232a510442a8e6b980585c6ec75..98ad3092a079cb7659c1f8c6c29c1e6bc3b1f557 100644 (file)
@@ -153,7 +153,6 @@ static int mxb_probe(struct saa7146_dev* dev)
 {
        struct mxb* mxb = NULL;
        struct i2c_client *client;
-       struct list_head *item;
        int result;
 
        if ((result = request_module("saa7111")) < 0) {
@@ -196,8 +195,7 @@ static int mxb_probe(struct saa7146_dev* dev)
        }
 
        /* loop through all i2c-devices on the bus and look who is there */
-       list_for_each(item,&mxb->i2c_adapter.clients) {
-               client = list_entry(item, struct i2c_client, list);
+       list_for_each_entry(client, &mxb->i2c_adapter.clients, list) {
                if( I2C_ADDR_TEA6420_1 == client->addr )
                        mxb->tea6420_1 = client;
                if( I2C_ADDR_TEA6420_2 == client->addr )
index e5edff1059a28f43f8a7487f25ac859a9c306d13..9eb2562347a8dd19622ae94b53ef43c1255ff41e 100644 (file)
@@ -5554,41 +5554,46 @@ error:
  *  sysfs
  ***************************************************************************/
 
-static inline struct usb_ov511 *cd_to_ov(struct class_device *cd)
+static inline struct usb_ov511 *cd_to_ov(struct device *cd)
 {
        struct video_device *vdev = to_video_device(cd);
        return video_get_drvdata(vdev);
 }
 
-static ssize_t show_custom_id(struct class_device *cd, char *buf)
+static ssize_t show_custom_id(struct device *cd,
+                             struct device_attribute *attr, char *buf)
 {
        struct usb_ov511 *ov = cd_to_ov(cd);
        return sprintf(buf, "%d\n", ov->customid);
 }
-static CLASS_DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL);
+static DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL);
 
-static ssize_t show_model(struct class_device *cd, char *buf)
+static ssize_t show_model(struct device *cd,
+                         struct device_attribute *attr, char *buf)
 {
        struct usb_ov511 *ov = cd_to_ov(cd);
        return sprintf(buf, "%s\n", ov->desc);
 }
-static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
+static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
 
-static ssize_t show_bridge(struct class_device *cd, char *buf)
+static ssize_t show_bridge(struct device *cd,
+                          struct device_attribute *attr, char *buf)
 {
        struct usb_ov511 *ov = cd_to_ov(cd);
        return sprintf(buf, "%s\n", symbolic(brglist, ov->bridge));
 }
-static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL);
+static DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL);
 
-static ssize_t show_sensor(struct class_device *cd, char *buf)
+static ssize_t show_sensor(struct device *cd,
+                          struct device_attribute *attr, char *buf)
 {
        struct usb_ov511 *ov = cd_to_ov(cd);
        return sprintf(buf, "%s\n", symbolic(senlist, ov->sensor));
 }
-static CLASS_DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL);
+static DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL);
 
-static ssize_t show_brightness(struct class_device *cd, char *buf)
+static ssize_t show_brightness(struct device *cd,
+                              struct device_attribute *attr, char *buf)
 {
        struct usb_ov511 *ov = cd_to_ov(cd);
        unsigned short x;
@@ -5598,9 +5603,10 @@ static ssize_t show_brightness(struct class_device *cd, char *buf)
        sensor_get_brightness(ov, &x);
        return sprintf(buf, "%d\n", x >> 8);
 }
-static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
+static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
 
-static ssize_t show_saturation(struct class_device *cd, char *buf)
+static ssize_t show_saturation(struct device *cd,
+                              struct device_attribute *attr, char *buf)
 {
        struct usb_ov511 *ov = cd_to_ov(cd);
        unsigned short x;
@@ -5610,9 +5616,10 @@ static ssize_t show_saturation(struct class_device *cd, char *buf)
        sensor_get_saturation(ov, &x);
        return sprintf(buf, "%d\n", x >> 8);
 }
-static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
+static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
 
-static ssize_t show_contrast(struct class_device *cd, char *buf)
+static ssize_t show_contrast(struct device *cd,
+                            struct device_attribute *attr, char *buf)
 {
        struct usb_ov511 *ov = cd_to_ov(cd);
        unsigned short x;
@@ -5622,9 +5629,10 @@ static ssize_t show_contrast(struct class_device *cd, char *buf)
        sensor_get_contrast(ov, &x);
        return sprintf(buf, "%d\n", x >> 8);
 }
-static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
+static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
 
-static ssize_t show_hue(struct class_device *cd, char *buf)
+static ssize_t show_hue(struct device *cd,
+                       struct device_attribute *attr, char *buf)
 {
        struct usb_ov511 *ov = cd_to_ov(cd);
        unsigned short x;
@@ -5634,9 +5642,10 @@ static ssize_t show_hue(struct class_device *cd, char *buf)
        sensor_get_hue(ov, &x);
        return sprintf(buf, "%d\n", x >> 8);
 }
-static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
+static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
 
-static ssize_t show_exposure(struct class_device *cd, char *buf)
+static ssize_t show_exposure(struct device *cd,
+                            struct device_attribute *attr, char *buf)
 {
        struct usb_ov511 *ov = cd_to_ov(cd);
        unsigned char exp = 0;
@@ -5646,49 +5655,49 @@ static ssize_t show_exposure(struct class_device *cd, char *buf)
        sensor_get_exposure(ov, &exp);
        return sprintf(buf, "%d\n", exp >> 8);
 }
-static CLASS_DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL);
+static DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL);
 
 static int ov_create_sysfs(struct video_device *vdev)
 {
        int rc;
 
-       rc = video_device_create_file(vdev, &class_device_attr_custom_id);
+       rc = video_device_create_file(vdev, &dev_attr_custom_id);
        if (rc) goto err;
-       rc = video_device_create_file(vdev, &class_device_attr_model);
+       rc = video_device_create_file(vdev, &dev_attr_model);
        if (rc) goto err_id;
-       rc = video_device_create_file(vdev, &class_device_attr_bridge);
+       rc = video_device_create_file(vdev, &dev_attr_bridge);
        if (rc) goto err_model;
-       rc = video_device_create_file(vdev, &class_device_attr_sensor);
+       rc = video_device_create_file(vdev, &dev_attr_sensor);
        if (rc) goto err_bridge;
-       rc = video_device_create_file(vdev, &class_device_attr_brightness);
+       rc = video_device_create_file(vdev, &dev_attr_brightness);
        if (rc) goto err_sensor;
-       rc = video_device_create_file(vdev, &class_device_attr_saturation);
+       rc = video_device_create_file(vdev, &dev_attr_saturation);
        if (rc) goto err_bright;
-       rc = video_device_create_file(vdev, &class_device_attr_contrast);
+       rc = video_device_create_file(vdev, &dev_attr_contrast);
        if (rc) goto err_sat;
-       rc = video_device_create_file(vdev, &class_device_attr_hue);
+       rc = video_device_create_file(vdev, &dev_attr_hue);
        if (rc) goto err_contrast;
-       rc = video_device_create_file(vdev, &class_device_attr_exposure);
+       rc = video_device_create_file(vdev, &dev_attr_exposure);
        if (rc) goto err_hue;
 
        return 0;
 
 err_hue:
-       video_device_remove_file(vdev, &class_device_attr_hue);
+       video_device_remove_file(vdev, &dev_attr_hue);
 err_contrast:
-       video_device_remove_file(vdev, &class_device_attr_contrast);
+       video_device_remove_file(vdev, &dev_attr_contrast);
 err_sat:
-       video_device_remove_file(vdev, &class_device_attr_saturation);
+       video_device_remove_file(vdev, &dev_attr_saturation);
 err_bright:
-       video_device_remove_file(vdev, &class_device_attr_brightness);
+       video_device_remove_file(vdev, &dev_attr_brightness);
 err_sensor:
-       video_device_remove_file(vdev, &class_device_attr_sensor);
+       video_device_remove_file(vdev, &dev_attr_sensor);
 err_bridge:
-       video_device_remove_file(vdev, &class_device_attr_bridge);
+       video_device_remove_file(vdev, &dev_attr_bridge);
 err_model:
-       video_device_remove_file(vdev, &class_device_attr_model);
+       video_device_remove_file(vdev, &dev_attr_model);
 err_id:
-       video_device_remove_file(vdev, &class_device_attr_custom_id);
+       video_device_remove_file(vdev, &dev_attr_custom_id);
 err:
        return rc;
 }
index c4c5bd67f795a12a66ef1f69cf72d869ee87f8d5..2bc6bdc9c1f2c50eb966aa2fd127a13cc2d8090d 100644 (file)
@@ -12,7 +12,6 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/videodev.h>
index 3fe9fa04cd8419332d8e1ee1bf601e166a78b10a..8063e33f1c85ebc45e2b49780fe0908d581d36cd 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include "ovcamchip_priv.h"
index 4ab1af74a97027f3ecf9503a6d763e44df520492..0ef73d9d5848554054889c5b83540db000b3fc7a 100644 (file)
@@ -844,21 +844,21 @@ cmd_tab_mask_end:
 /*********************************/
 
 static int palette2fmt[] = {
-       0,
-       PLANB_GRAY,
-       0,
-       0,
-       0,
-       PLANB_COLOUR32,
-       PLANB_COLOUR15,
-       0,
-       0,
-       0,
-       0,
-       0,
-       0,
-       0,
-       0,
+       0,
+       PLANB_GRAY,
+       0,
+       0,
+       0,
+       PLANB_COLOUR32,
+       PLANB_COLOUR15,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
 };
 
 #define PLANB_PALETTE_MAX 15
index 6bbed88d7867af00ae9de1cafe2751ec35d56bee..22719ba861aceb2d0e0c3f2b70b467b39ef26de9 100644 (file)
@@ -33,8 +33,10 @@ static void pvr2_context_destroy(struct pvr2_context *mp)
 {
        if (mp->hdw) pvr2_hdw_destroy(mp->hdw);
        pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr_main id=%p",mp);
-       flush_workqueue(mp->workqueue);
-       destroy_workqueue(mp->workqueue);
+       if (mp->workqueue) {
+               flush_workqueue(mp->workqueue);
+               destroy_workqueue(mp->workqueue);
+       }
        kfree(mp);
 }
 
index d95a8588e4f840e759439890eb136e1848052120..da6441b88f31af8ebae32a62533f9d6330f2823c 100644 (file)
@@ -26,32 +26,33 @@ extern int pvrusb2_debug;
 
 /* These are listed in *rough* order of decreasing usefulness and
    increasing noise level. */
-#define PVR2_TRACE_INFO       (1 <<  0) // Normal messages
-#define PVR2_TRACE_ERROR_LEGS (1 <<  1) // error messages
-#define PVR2_TRACE_TOLERANCE  (1 <<  2) // track tolerance-affected errors
-#define PVR2_TRACE_TRAP       (1 <<  3) // Trap & report misbehavior from app
-#define PVR2_TRACE_INIT       (1 <<  4) // misc initialization steps
-#define PVR2_TRACE_START_STOP (1 <<  5) // Streaming start / stop
-#define PVR2_TRACE_CTL        (1 <<  6) // commit of control changes
-#define PVR2_TRACE_DEBUG      (1 <<  7) // Temporary debug code
-#define PVR2_TRACE_EEPROM     (1 <<  8) // eeprom parsing / report
-#define PVR2_TRACE_STRUCT     (1 <<  9) // internal struct creation
-#define PVR2_TRACE_OPEN_CLOSE (1 << 10) // application open / close
-#define PVR2_TRACE_CREG       (1 << 11) // Main critical region entry / exit
-#define PVR2_TRACE_SYSFS      (1 << 12) // Sysfs driven I/O
-#define PVR2_TRACE_FIRMWARE   (1 << 13) // firmware upload actions
-#define PVR2_TRACE_CHIPS      (1 << 14) // chip broadcast operation
-#define PVR2_TRACE_I2C        (1 << 15) // I2C related stuff
-#define PVR2_TRACE_I2C_CMD    (1 << 16) // Software commands to I2C modules
-#define PVR2_TRACE_I2C_CORE   (1 << 17) // I2C core debugging
-#define PVR2_TRACE_I2C_TRAF   (1 << 18) // I2C traffic through the adapter
-#define PVR2_TRACE_V4LIOCTL   (1 << 19) // v4l ioctl details
-#define PVR2_TRACE_ENCODER    (1 << 20) // mpeg2 encoder operation
-#define PVR2_TRACE_BUF_POOL   (1 << 21) // Track buffer pool management
-#define PVR2_TRACE_BUF_FLOW   (1 << 22) // Track buffer flow in system
-#define PVR2_TRACE_DATA_FLOW  (1 << 23) // Track data flow
-#define PVR2_TRACE_DEBUGIFC   (1 << 24) // Debug interface actions
-#define PVR2_TRACE_GPIO       (1 << 25) // GPIO state bit changes
+#define PVR2_TRACE_INFO       (1 <<  0) /* Normal messages */
+#define PVR2_TRACE_ERROR_LEGS (1 <<  1) /* error messages */
+#define PVR2_TRACE_TOLERANCE  (1 <<  2) /* track tolerance-affected errors */
+#define PVR2_TRACE_TRAP       (1 <<  3) /* Trap & report app misbehavior */
+#define PVR2_TRACE_STD        (1 <<  4) /* Log video standard stuff */
+#define PVR2_TRACE_INIT       (1 <<  5) /* misc initialization steps */
+#define PVR2_TRACE_START_STOP (1 <<  6) /* Streaming start / stop */
+#define PVR2_TRACE_CTL        (1 <<  7) /* commit of control changes */
+#define PVR2_TRACE_DEBUG      (1 <<  8) /* Temporary debug code */
+#define PVR2_TRACE_EEPROM     (1 <<  9) /* eeprom parsing / report */
+#define PVR2_TRACE_STRUCT     (1 << 10) /* internal struct creation */
+#define PVR2_TRACE_OPEN_CLOSE (1 << 11) /* application open / close */
+#define PVR2_TRACE_CREG       (1 << 12) /* Main critical region entry / exit */
+#define PVR2_TRACE_SYSFS      (1 << 13) /* Sysfs driven I/O */
+#define PVR2_TRACE_FIRMWARE   (1 << 14) /* firmware upload actions */
+#define PVR2_TRACE_CHIPS      (1 << 15) /* chip broadcast operation */
+#define PVR2_TRACE_I2C        (1 << 16) /* I2C related stuff */
+#define PVR2_TRACE_I2C_CMD    (1 << 17) /* Software commands to I2C modules */
+#define PVR2_TRACE_I2C_CORE   (1 << 18) /* I2C core debugging */
+#define PVR2_TRACE_I2C_TRAF   (1 << 19) /* I2C traffic through the adapter */
+#define PVR2_TRACE_V4LIOCTL   (1 << 20) /* v4l ioctl details */
+#define PVR2_TRACE_ENCODER    (1 << 21) /* mpeg2 encoder operation */
+#define PVR2_TRACE_BUF_POOL   (1 << 22) /* Track buffer pool management */
+#define PVR2_TRACE_BUF_FLOW   (1 << 23) /* Track buffer flow in system */
+#define PVR2_TRACE_DATA_FLOW  (1 << 24) /* Track data flow */
+#define PVR2_TRACE_DEBUGIFC   (1 << 25) /* Debug interface actions */
+#define PVR2_TRACE_GPIO       (1 << 26) /* GPIO state bit changes */
 
 
 #endif /* __PVRUSB2_HDW_INTERNAL_H */
index e9da9bb8f8dea1f8901b1428c48b2cc1ce95c8cc..6f135f4a2497d89d55d760d6f6f812cc87a5253f 100644 (file)
@@ -397,10 +397,22 @@ static int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf,
                count -= scnt; buf += scnt;
                if (!wptr) return -EINVAL;
                if (debugifc_match_keyword(wptr,wlen,"fetch")) {
-                       pvr2_hdw_cpufw_set_enabled(hdw,!0);
+                       scnt = debugifc_isolate_word(buf,count,&wptr,&wlen);
+                       if (scnt && wptr) {
+                               count -= scnt; buf += scnt;
+                               if (debugifc_match_keyword(wptr,wlen,"prom")) {
+                                       pvr2_hdw_cpufw_set_enabled(hdw,!0,!0);
+                               } else if (debugifc_match_keyword(wptr,wlen,
+                                                                 "ram")) {
+                                       pvr2_hdw_cpufw_set_enabled(hdw,0,!0);
+                               } else {
+                                       return -EINVAL;
+                               }
+                       }
+                       pvr2_hdw_cpufw_set_enabled(hdw,0,!0);
                        return 0;
                } else if (debugifc_match_keyword(wptr,wlen,"done")) {
-                       pvr2_hdw_cpufw_set_enabled(hdw,0);
+                       pvr2_hdw_cpufw_set_enabled(hdw,0,0);
                        return 0;
                } else {
                        return -EINVAL;
index ce66ab8ff2d8eec0a5de487bc6cf68956a3c121a..985d9ae7f5ee1c11486ba7ff6cfeb4303a920b95 100644 (file)
@@ -238,6 +238,7 @@ struct pvr2_hdw {
        // CPU firmware info (used to help find / save firmware data)
        char *fw_buffer;
        unsigned int fw_size;
+       int fw_cpu_flag; /* True if we are dealing with the CPU */
 
        // Which subsystem pieces have been enabled / configured
        unsigned long subsys_enabled_mask;
index 1311891e7ee3dd0d85acc751c0ad40362271e3c4..27b12b4b5c883c449b3ce3bd267fdb338ba1e870 100644 (file)
@@ -492,7 +492,7 @@ static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp)
        cs.controls = &c1;
        cs.count = 1;
        c1.id = cptr->info->v4l_id;
-       ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
+       ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs,
                                VIDIOC_G_EXT_CTRLS);
        if (ret) return ret;
        *vp = c1.value;
@@ -510,7 +510,7 @@ static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v)
        cs.count = 1;
        c1.id = cptr->info->v4l_id;
        c1.value = v;
-       ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs,
+       ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state, 0, &cs,
                                VIDIOC_S_EXT_CTRLS);
        if (ret) return ret;
        cptr->hdw->enc_stale = !0;
@@ -1143,6 +1143,13 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw)
                        fw_files_24xxx, ARRAY_SIZE(fw_files_24xxx)
                },
        };
+
+       if ((hdw->hdw_type >= ARRAY_SIZE(fw_file_defs)) ||
+           (!fw_file_defs[hdw->hdw_type].lst)) {
+               hdw->fw1_state = FW1_STATE_OK;
+               return 0;
+       }
+
        hdw->fw1_state = FW1_STATE_FAILED; // default result
 
        trace_firmware("pvr2_upload_firmware1");
@@ -1224,6 +1231,11 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
                CX2341X_FIRM_ENC_FILENAME,
        };
 
+       if ((hdw->hdw_type != PVR2_HDW_TYPE_29XXX) &&
+           (hdw->hdw_type != PVR2_HDW_TYPE_24XXX)) {
+               return 0;
+       }
+
        trace_firmware("pvr2_upload_firmware2");
 
        ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder",
@@ -1682,6 +1694,44 @@ static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
        return result == 0;
 }
 
+struct pvr2_std_hack {
+       v4l2_std_id pat;  /* Pattern to match */
+       v4l2_std_id msk;  /* Which bits we care about */
+       v4l2_std_id std;  /* What additional standards or default to set */
+};
+
+/* This data structure labels specific combinations of standards from
+   tveeprom that we'll try to recognize.  If we recognize one, then assume
+   a specified default standard to use.  This is here because tveeprom only
+   tells us about available standards not the intended default standard (if
+   any) for the device in question.  We guess the default based on what has
+   been reported as available.  Note that this is only for guessing a
+   default - which can always be overridden explicitly - and if the user
+   has otherwise named a default then that default will always be used in
+   place of this table. */
+const static struct pvr2_std_hack std_eeprom_maps[] = {
+       {       /* PAL(B/G) */
+               .pat = V4L2_STD_B|V4L2_STD_GH,
+               .std = V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_PAL_G,
+       },
+       {       /* NTSC(M) */
+               .pat = V4L2_STD_MN,
+               .std = V4L2_STD_NTSC_M,
+       },
+       {       /* PAL(I) */
+               .pat = V4L2_STD_PAL_I,
+               .std = V4L2_STD_PAL_I,
+       },
+       {       /* SECAM(L/L') */
+               .pat = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
+               .std = V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC,
+       },
+       {       /* PAL(D/D1/K) */
+               .pat = V4L2_STD_DK,
+               .std = V4L2_STD_PAL_D/V4L2_STD_PAL_D1|V4L2_STD_PAL_K,
+       },
+};
+
 static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
 {
        char buf[40];
@@ -1691,7 +1741,7 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
        std1 = get_default_standard(hdw);
 
        bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom);
-       pvr2_trace(PVR2_TRACE_INIT,
+       pvr2_trace(PVR2_TRACE_STD,
                   "Supported video standard(s) reported by eeprom: %.*s",
                   bcnt,buf);
 
@@ -1700,7 +1750,7 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
        std2 = std1 & ~hdw->std_mask_avail;
        if (std2) {
                bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2);
-               pvr2_trace(PVR2_TRACE_INIT,
+               pvr2_trace(PVR2_TRACE_STD,
                           "Expanding supported video standards"
                           " to include: %.*s",
                           bcnt,buf);
@@ -1711,7 +1761,7 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
 
        if (std1) {
                bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1);
-               pvr2_trace(PVR2_TRACE_INIT,
+               pvr2_trace(PVR2_TRACE_STD,
                           "Initial video standard forced to %.*s",
                           bcnt,buf);
                hdw->std_mask_cur = std1;
@@ -1720,12 +1770,33 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
                return;
        }
 
+       {
+               unsigned int idx;
+               for (idx = 0; idx < ARRAY_SIZE(std_eeprom_maps); idx++) {
+                       if (std_eeprom_maps[idx].msk ?
+                           ((std_eeprom_maps[idx].pat ^
+                            hdw->std_mask_eeprom) &
+                            std_eeprom_maps[idx].msk) :
+                           (std_eeprom_maps[idx].pat !=
+                            hdw->std_mask_eeprom)) continue;
+                       bcnt = pvr2_std_id_to_str(buf,sizeof(buf),
+                                                 std_eeprom_maps[idx].std);
+                       pvr2_trace(PVR2_TRACE_STD,
+                                  "Initial video standard guessed as %.*s",
+                                  bcnt,buf);
+                       hdw->std_mask_cur = std_eeprom_maps[idx].std;
+                       hdw->std_dirty = !0;
+                       pvr2_hdw_internal_find_stdenum(hdw);
+                       return;
+               }
+       }
+
        if (hdw->std_enum_cnt > 1) {
                // Autoselect the first listed standard
                hdw->std_enum_cur = 1;
                hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id;
                hdw->std_dirty = !0;
-               pvr2_trace(PVR2_TRACE_INIT,
+               pvr2_trace(PVR2_TRACE_STD,
                           "Initial video standard auto-selected to %s",
                           hdw->std_defs[hdw->std_enum_cur-1].name);
                return;
@@ -1742,29 +1813,35 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
        unsigned int idx;
        struct pvr2_ctrl *cptr;
        int reloadFl = 0;
-       if (!reloadFl) {
-               reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
-                           == 0);
-               if (reloadFl) {
-                       pvr2_trace(PVR2_TRACE_INIT,
-                                  "USB endpoint config looks strange"
-                                  "; possibly firmware needs to be loaded");
+       if ((hdw->hdw_type == PVR2_HDW_TYPE_29XXX) ||
+           (hdw->hdw_type == PVR2_HDW_TYPE_24XXX)) {
+               if (!reloadFl) {
+                       reloadFl =
+                               (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints
+                                == 0);
+                       if (reloadFl) {
+                               pvr2_trace(PVR2_TRACE_INIT,
+                                          "USB endpoint config looks strange"
+                                          "; possibly firmware needs to be"
+                                          " loaded");
+                       }
                }
-       }
-       if (!reloadFl) {
-               reloadFl = !pvr2_hdw_check_firmware(hdw);
-               if (reloadFl) {
-                       pvr2_trace(PVR2_TRACE_INIT,
-                                  "Check for FX2 firmware failed"
-                                  "; possibly firmware needs to be loaded");
+               if (!reloadFl) {
+                       reloadFl = !pvr2_hdw_check_firmware(hdw);
+                       if (reloadFl) {
+                               pvr2_trace(PVR2_TRACE_INIT,
+                                          "Check for FX2 firmware failed"
+                                          "; possibly firmware needs to be"
+                                          " loaded");
+                       }
                }
-       }
-       if (reloadFl) {
-               if (pvr2_upload_firmware1(hdw) != 0) {
-                       pvr2_trace(PVR2_TRACE_ERROR_LEGS,
-                                  "Failure uploading firmware1");
+               if (reloadFl) {
+                       if (pvr2_upload_firmware1(hdw) != 0) {
+                               pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+                                          "Failure uploading firmware1");
+                       }
+                       return;
                }
-               return;
        }
        hdw->fw1_state = FW1_STATE_OK;
 
@@ -1773,17 +1850,25 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
        }
        if (!pvr2_hdw_dev_ok(hdw)) return;
 
-       for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) {
-               request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]);
+       if (hdw->hdw_type < ARRAY_SIZE(pvr2_client_lists)) {
+               for (idx = 0;
+                    idx < pvr2_client_lists[hdw->hdw_type].cnt;
+                    idx++) {
+                       request_module(
+                               pvr2_client_lists[hdw->hdw_type].lst[idx]);
+               }
        }
 
-       pvr2_hdw_cmd_powerup(hdw);
-       if (!pvr2_hdw_dev_ok(hdw)) return;
+       if ((hdw->hdw_type == PVR2_HDW_TYPE_29XXX) ||
+           (hdw->hdw_type == PVR2_HDW_TYPE_24XXX)) {
+               pvr2_hdw_cmd_powerup(hdw);
+               if (!pvr2_hdw_dev_ok(hdw)) return;
 
-       if (pvr2_upload_firmware2(hdw)){
-               pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!");
-               pvr2_hdw_render_useless(hdw);
-               return;
+               if (pvr2_upload_firmware2(hdw)){
+                       pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!");
+                       pvr2_hdw_render_useless(hdw);
+                       return;
+               }
        }
 
        // This step MUST happen after the earlier powerup step.
@@ -2172,6 +2257,7 @@ static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
 /* Destroy hardware interaction structure */
 void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
 {
+       if (!hdw) return;
        pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw);
        if (hdw->fw_buffer) {
                kfree(hdw->fw_buffer);
@@ -2478,7 +2564,7 @@ static int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw)
                cs.count = 1;
                c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
                c1.value = hdw->srate_val;
-               cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS);
+               cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
        }
 
        /* Scan i2c core at this point - before we clear all the dirty
@@ -2604,7 +2690,85 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
        } while (0); LOCK_GIVE(hdw->big_lock);
 }
 
-void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag)
+
+/* Grab EEPROM contents, needed for direct method. */
+#define EEPROM_SIZE 8192
+#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__)
+static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw)
+{
+       struct i2c_msg msg[2];
+       u8 *eeprom;
+       u8 iadd[2];
+       u8 addr;
+       u16 eepromSize;
+       unsigned int offs;
+       int ret;
+       int mode16 = 0;
+       unsigned pcnt,tcnt;
+       eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL);
+       if (!eeprom) {
+               pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+                          "Failed to allocate memory"
+                          " required to read eeprom");
+               return NULL;
+       }
+
+       trace_eeprom("Value for eeprom addr from controller was 0x%x",
+                    hdw->eeprom_addr);
+       addr = hdw->eeprom_addr;
+       /* Seems that if the high bit is set, then the *real* eeprom
+          address is shifted right now bit position (noticed this in
+          newer PVR USB2 hardware) */
+       if (addr & 0x80) addr >>= 1;
+
+       /* FX2 documentation states that a 16bit-addressed eeprom is
+          expected if the I2C address is an odd number (yeah, this is
+          strange but it's what they do) */
+       mode16 = (addr & 1);
+       eepromSize = (mode16 ? EEPROM_SIZE : 256);
+       trace_eeprom("Examining %d byte eeprom at location 0x%x"
+                    " using %d bit addressing",eepromSize,addr,
+                    mode16 ? 16 : 8);
+
+       msg[0].addr = addr;
+       msg[0].flags = 0;
+       msg[0].len = mode16 ? 2 : 1;
+       msg[0].buf = iadd;
+       msg[1].addr = addr;
+       msg[1].flags = I2C_M_RD;
+
+       /* We have to do the actual eeprom data fetch ourselves, because
+          (1) we're only fetching part of the eeprom, and (2) if we were
+          getting the whole thing our I2C driver can't grab it in one
+          pass - which is what tveeprom is otherwise going to attempt */
+       memset(eeprom,0,EEPROM_SIZE);
+       for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) {
+               pcnt = 16;
+               if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt;
+               offs = tcnt + (eepromSize - EEPROM_SIZE);
+               if (mode16) {
+                       iadd[0] = offs >> 8;
+                       iadd[1] = offs;
+               } else {
+                       iadd[0] = offs;
+               }
+               msg[1].len = pcnt;
+               msg[1].buf = eeprom+tcnt;
+               if ((ret = i2c_transfer(&hdw->i2c_adap,
+                                       msg,ARRAY_SIZE(msg))) != 2) {
+                       pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+                                  "eeprom fetch set offs err=%d",ret);
+                       kfree(eeprom);
+                       return NULL;
+               }
+       }
+       return eeprom;
+}
+
+
+void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
+                               int prom_flag,
+                               int enable_flag)
 {
        int ret;
        u16 address;
@@ -2618,37 +2782,59 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag)
                        kfree(hdw->fw_buffer);
                        hdw->fw_buffer = NULL;
                        hdw->fw_size = 0;
-                       /* Now release the CPU.  It will disconnect and
-                          reconnect later. */
-                       pvr2_hdw_cpureset_assert(hdw,0);
+                       if (hdw->fw_cpu_flag) {
+                               /* Now release the CPU.  It will disconnect
+                                  and reconnect later. */
+                               pvr2_hdw_cpureset_assert(hdw,0);
+                       }
                        break;
                }
 
-               pvr2_trace(PVR2_TRACE_FIRMWARE,
-                          "Preparing to suck out CPU firmware");
-               hdw->fw_size = 0x2000;
-               hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
-               if (!hdw->fw_buffer) {
-                       hdw->fw_size = 0;
-                       break;
-               }
+               hdw->fw_cpu_flag = (prom_flag == 0);
+               if (hdw->fw_cpu_flag) {
+                       pvr2_trace(PVR2_TRACE_FIRMWARE,
+                                  "Preparing to suck out CPU firmware");
+                       hdw->fw_size = 0x2000;
+                       hdw->fw_buffer = kzalloc(hdw->fw_size,GFP_KERNEL);
+                       if (!hdw->fw_buffer) {
+                               hdw->fw_size = 0;
+                               break;
+                       }
 
-               /* We have to hold the CPU during firmware upload. */
-               pvr2_hdw_cpureset_assert(hdw,1);
+                       /* We have to hold the CPU during firmware upload. */
+                       pvr2_hdw_cpureset_assert(hdw,1);
 
-               /* download the firmware from address 0000-1fff in 2048
-                  (=0x800) bytes chunk. */
+                       /* download the firmware from address 0000-1fff in 2048
+                          (=0x800) bytes chunk. */
 
-               pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware");
-               pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
-               for(address = 0; address < hdw->fw_size; address += 0x800) {
-                       ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0,
-                                             address,0,
-                                             hdw->fw_buffer+address,0x800,HZ);
-                       if (ret < 0) break;
-               }
+                       pvr2_trace(PVR2_TRACE_FIRMWARE,
+                                  "Grabbing CPU firmware");
+                       pipe = usb_rcvctrlpipe(hdw->usb_dev, 0);
+                       for(address = 0; address < hdw->fw_size;
+                           address += 0x800) {
+                               ret = usb_control_msg(hdw->usb_dev,pipe,
+                                                     0xa0,0xc0,
+                                                     address,0,
+                                                     hdw->fw_buffer+address,
+                                                     0x800,HZ);
+                               if (ret < 0) break;
+                       }
 
-               pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware");
+                       pvr2_trace(PVR2_TRACE_FIRMWARE,
+                                  "Done grabbing CPU firmware");
+               } else {
+                       pvr2_trace(PVR2_TRACE_FIRMWARE,
+                                  "Sucking down EEPROM contents");
+                       hdw->fw_buffer = pvr2_full_eeprom_fetch(hdw);
+                       if (!hdw->fw_buffer) {
+                               pvr2_trace(PVR2_TRACE_FIRMWARE,
+                                          "EEPROM content suck failed.");
+                               break;
+                       }
+                       hdw->fw_size = EEPROM_SIZE;
+                       pvr2_trace(PVR2_TRACE_FIRMWARE,
+                                  "Done sucking down EEPROM contents");
+               }
 
        } while (0); LOCK_GIVE(hdw->big_lock);
 }
@@ -3272,7 +3458,6 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
                             int setFl,u64 *val_ptr)
 {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-       struct list_head *item;
        struct pvr2_i2c_client *cp;
        struct v4l2_register req;
        int stat = 0;
@@ -3285,8 +3470,7 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
        req.reg = reg_id;
        if (setFl) req.val = *val_ptr;
        mutex_lock(&hdw->i2c_list_lock); do {
-               list_for_each(item,&hdw->i2c_clients) {
-                       cp = list_entry(item,struct pvr2_i2c_client,list);
+               list_for_each_entry(cp, &hdw->i2c_clients, list) {
                        if (!v4l2_chip_match_i2c_client(
                                    cp->client,
                                    req.match_type, req.match_chip)) {
index 4dba8d0063244fbb85128a13a170841ed91c46b1..e2f9d5e4cb653c191f1a07ed94bf14a5799d3a4f 100644 (file)
@@ -197,11 +197,13 @@ void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw,
 unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *);
 
 
-/* Enable / disable retrieval of CPU firmware.  This must be enabled before
-   pvr2_hdw_cpufw_get() will function.  Note that doing this may prevent
-   the device from running (and leaving this mode may imply a device
-   reset). */
-void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, int enable_flag);
+/* Enable / disable retrieval of CPU firmware or prom contents.  This must
+   be enabled before pvr2_hdw_cpufw_get() will function.  Note that doing
+   this may prevent the device from running (and leaving this mode may
+   imply a device reset). */
+void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *,
+                               int prom_flag,
+                               int enable_flag);
 
 /* Return true if we're in a mode for retrieval CPU firmware */
 int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *);
index 6786d3c0c98beaf8b1a3fc84d55787f97a7f5d89..898c9d2e4cdfb6f25420c404cd8937cc2b0030b0 100644 (file)
@@ -389,10 +389,6 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
                ret = -EINVAL;
                goto done;
        }
-       if ((msgs[0].flags & I2C_M_NOSTART)) {
-               trace_i2c("i2c refusing I2C_M_NOSTART");
-               goto done;
-       }
        if (msgs[0].addr < PVR2_I2C_FUNC_CNT) {
                funcp = hdw->i2c_func[msgs[0].addr];
        }
@@ -494,14 +490,12 @@ static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
                        cnt = msgs[idx].len;
                        printk(KERN_INFO
                               "pvrusb2 i2c xfer %u/%u:"
-                              " addr=0x%x len=%d %s%s",
+                              " addr=0x%x len=%d %s",
                               idx+1,num,
                               msgs[idx].addr,
                               cnt,
                               (msgs[idx].flags & I2C_M_RD ?
-                               "read" : "write"),
-                              (msgs[idx].flags & I2C_M_NOSTART ?
-                               " nostart" : ""));
+                               "read" : "write"));
                        if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) {
                                if (cnt > 8) cnt = 8;
                                printk(" [");
@@ -534,7 +528,7 @@ static int pvr2_i2c_control(struct i2c_adapter *adapter,
 
 static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
 {
-       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA;
+       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
 }
 
 static int pvr2_i2c_core_singleton(struct i2c_client *cp,
@@ -576,15 +570,13 @@ int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg)
 
 int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg)
 {
-       struct list_head *item,*nc;
-       struct pvr2_i2c_client *cp;
+       struct pvr2_i2c_client *cp, *ncp;
        int stat = -EINVAL;
 
        if (!hdw) return stat;
 
        mutex_lock(&hdw->i2c_list_lock);
-       list_for_each_safe(item,nc,&hdw->i2c_clients) {
-               cp = list_entry(item,struct pvr2_i2c_client,list);
+       list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
                if (!cp->recv_enable) continue;
                mutex_unlock(&hdw->i2c_list_lock);
                stat = pvr2_i2c_client_cmd(cp,cmd,arg);
@@ -608,13 +600,11 @@ static int handler_check(struct pvr2_i2c_client *cp)
 
 void pvr2_i2c_core_status_poll(struct pvr2_hdw *hdw)
 {
-       struct list_head *item;
        struct pvr2_i2c_client *cp;
        mutex_lock(&hdw->i2c_list_lock); do {
                struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
                memset(vtp,0,sizeof(*vtp));
-               list_for_each(item,&hdw->i2c_clients) {
-                       cp = list_entry(item,struct pvr2_i2c_client,list);
+               list_for_each_entry(cp, &hdw->i2c_clients, list) {
                        if (!cp->detected_flag) continue;
                        if (!cp->status_poll) continue;
                        cp->status_poll(cp);
@@ -636,8 +626,7 @@ void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
 {
        unsigned long msk;
        unsigned int idx;
-       struct list_head *item,*nc;
-       struct pvr2_i2c_client *cp;
+       struct pvr2_i2c_client *cp, *ncp;
 
        if (!hdw->i2c_linked) return;
        if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) {
@@ -655,9 +644,7 @@ void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
                        buf = kmalloc(BUFSIZE,GFP_KERNEL);
                        pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT");
                        hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT;
-                       list_for_each(item,&hdw->i2c_clients) {
-                               cp = list_entry(item,struct pvr2_i2c_client,
-                                               list);
+                       list_for_each_entry(cp, &hdw->i2c_clients, list) {
                                if (!cp->detected_flag) {
                                        cp->ctl_mask = 0;
                                        pvr2_i2c_probe(hdw,cp);
@@ -693,9 +680,7 @@ void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
                                   "i2c: PEND_STALE (0x%lx)",
                                   hdw->i2c_stale_mask);
                        hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE;
-                       list_for_each(item,&hdw->i2c_clients) {
-                               cp = list_entry(item,struct pvr2_i2c_client,
-                                               list);
+                       list_for_each_entry(cp, &hdw->i2c_clients, list) {
                                m2 = hdw->i2c_stale_mask;
                                m2 &= cp->ctl_mask;
                                m2 &= ~cp->pend_mask;
@@ -716,9 +701,8 @@ void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
                           and update each one. */
                        pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT");
                        hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT;
-                       list_for_each_safe(item,nc,&hdw->i2c_clients) {
-                               cp = list_entry(item,struct pvr2_i2c_client,
-                                               list);
+                       list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients,
+                                                list) {
                                if (!cp->handler) continue;
                                if (!cp->handler->func_table->update) continue;
                                pvr2_trace(PVR2_TRACE_I2C_CORE,
@@ -750,10 +734,8 @@ void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
                        for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
                                if (!(pm & msk)) continue;
                                pm &= ~msk;
-                               list_for_each(item,&hdw->i2c_clients) {
-                                       cp = list_entry(item,
-                                                       struct pvr2_i2c_client,
-                                                       list);
+                               list_for_each_entry(cp, &hdw->i2c_clients,
+                                                   list) {
                                        if (cp->pend_mask & msk) {
                                                cp->pend_mask &= ~msk;
                                                cp->recv_enable = !0;
@@ -777,7 +759,6 @@ int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw)
        unsigned long msk,sm,pm;
        unsigned int idx;
        const struct pvr2_i2c_op *opf;
-       struct list_head *item;
        struct pvr2_i2c_client *cp;
        unsigned int pt = 0;
 
@@ -796,11 +777,9 @@ int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw)
        }
        if (sm) pt |= PVR2_I2C_PEND_STALE;
 
-       list_for_each(item,&hdw->i2c_clients) {
-               cp = list_entry(item,struct pvr2_i2c_client,list);
-               if (!handler_check(cp)) continue;
-               pt |= PVR2_I2C_PEND_CLIENT;
-       }
+       list_for_each_entry(cp, &hdw->i2c_clients, list)
+               if (handler_check(cp))
+                       pt |= PVR2_I2C_PEND_CLIENT;
 
        if (pt) {
                mutex_lock(&hdw->i2c_list_lock); do {
@@ -888,12 +867,10 @@ unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw,
                             char *buf,unsigned int maxlen)
 {
        unsigned int ccnt,bcnt;
-       struct list_head *item;
        struct pvr2_i2c_client *cp;
        ccnt = 0;
        mutex_lock(&hdw->i2c_list_lock); do {
-               list_for_each(item,&hdw->i2c_clients) {
-                       cp = list_entry(item,struct pvr2_i2c_client,list);
+               list_for_each_entry(cp, &hdw->i2c_clients, list) {
                        bcnt = pvr2_i2c_client_describe(
                                cp,
                                (PVR2_I2C_DETAIL_HANDLER|
@@ -931,13 +908,11 @@ static int pvr2_i2c_attach_inform(struct i2c_client *client)
 static int pvr2_i2c_detach_inform(struct i2c_client *client)
 {
        struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
-       struct pvr2_i2c_client *cp;
-       struct list_head *item,*nc;
+       struct pvr2_i2c_client *cp, *ncp;
        unsigned long amask = 0;
        int foundfl = 0;
        mutex_lock(&hdw->i2c_list_lock); do {
-               list_for_each_safe(item,nc,&hdw->i2c_clients) {
-                       cp = list_entry(item,struct pvr2_i2c_client,list);
+               list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
                        if (cp->client == client) {
                                trace_i2c("pvr2_i2c_detach"
                                          " [client=%s @ 0x%x ctxt=%p]",
index 9ea41c6699bbdcc7b3bee873bcbf52f836f6762d..ca9e2789c8ca58d5c00988cb56158a4cbffb519b 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/usb.h>
 #include <linux/videodev2.h>
 
@@ -42,6 +41,7 @@
 
 #define DEFAULT_DEBUG_MASK (PVR2_TRACE_ERROR_LEGS| \
                            PVR2_TRACE_INFO| \
+                           PVR2_TRACE_STD| \
                            PVR2_TRACE_TOLERANCE| \
                            PVR2_TRACE_TRAP| \
                            0)
index 81de26ba41d9af1527f87f6a68d7bf9cda025a7b..63e55bb59fcbc9f698600f613459c505d56cd91c 100644 (file)
@@ -298,7 +298,7 @@ static int pvr2_std_fill(struct v4l2_standard *std,v4l2_std_id id)
        std->id = id;
        bcnt = pvr2_std_id_to_str(std->name,sizeof(std->name)-1,id);
        std->name[bcnt] = 0;
-       pvr2_trace(PVR2_TRACE_INIT,"Set up standard idx=%u name=%s",
+       pvr2_trace(PVR2_TRACE_STD,"Set up standard idx=%u name=%s",
                   std->index,std->name);
        return !0;
 }
@@ -320,11 +320,11 @@ struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
        v4l2_std_id idmsk,cmsk,fmsk;
        struct v4l2_standard *stddefs;
 
-       if (pvrusb2_debug & PVR2_TRACE_INIT) {
+       if (pvrusb2_debug & PVR2_TRACE_STD) {
                char buf[50];
                bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id);
                pvr2_trace(
-                       PVR2_TRACE_INIT,"Mapping standards mask=0x%x (%.*s)",
+                       PVR2_TRACE_STD,"Mapping standards mask=0x%x (%.*s)",
                        (int)id,bcnt,buf);
        }
 
@@ -355,7 +355,7 @@ struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
                        bcnt,buf);
        }
 
-       pvr2_trace(PVR2_TRACE_INIT,"Setting up %u unique standard(s)",
+       pvr2_trace(PVR2_TRACE_STD,"Setting up %u unique standard(s)",
                   std_cnt);
        if (!std_cnt) return NULL; // paranoia
 
index 7ab79baa1c8ce43aa771e21001b83e24006d25e5..7a78d6b34738827e1b74eca6df1260aad0ad4201 100644 (file)
 
 struct pvr2_sysfs {
        struct pvr2_channel channel;
-       struct class_device *class_dev;
+       struct device *class_dev;
 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
        struct pvr2_sysfs_debugifc *debugifc;
 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
        struct pvr2_sysfs_ctl_item *item_first;
        struct pvr2_sysfs_ctl_item *item_last;
-       struct class_device_attribute attr_v4l_minor_number;
-       struct class_device_attribute attr_v4l_radio_minor_number;
-       struct class_device_attribute attr_unit_number;
-       struct class_device_attribute attr_bus_info;
+       struct device_attribute attr_v4l_minor_number;
+       struct device_attribute attr_v4l_radio_minor_number;
+       struct device_attribute attr_unit_number;
+       struct device_attribute attr_bus_info;
        int v4l_minor_number_created_ok;
        int v4l_radio_minor_number_created_ok;
        int unit_number_created_ok;
@@ -51,22 +51,22 @@ struct pvr2_sysfs {
 
 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
 struct pvr2_sysfs_debugifc {
-       struct class_device_attribute attr_debugcmd;
-       struct class_device_attribute attr_debuginfo;
+       struct device_attribute attr_debugcmd;
+       struct device_attribute attr_debuginfo;
        int debugcmd_created_ok;
        int debuginfo_created_ok;
 };
 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
 
 struct pvr2_sysfs_ctl_item {
-       struct class_device_attribute attr_name;
-       struct class_device_attribute attr_type;
-       struct class_device_attribute attr_min;
-       struct class_device_attribute attr_max;
-       struct class_device_attribute attr_enum;
-       struct class_device_attribute attr_bits;
-       struct class_device_attribute attr_val;
-       struct class_device_attribute attr_custom;
+       struct device_attribute attr_name;
+       struct device_attribute attr_type;
+       struct device_attribute attr_min;
+       struct device_attribute attr_max;
+       struct device_attribute attr_enum;
+       struct device_attribute attr_bits;
+       struct device_attribute attr_val;
+       struct device_attribute attr_custom;
        struct pvr2_ctrl *cptr;
        struct pvr2_sysfs *chptr;
        struct pvr2_sysfs_ctl_item *item_next;
@@ -80,13 +80,13 @@ struct pvr2_sysfs_class {
        struct class class;
 };
 
-static ssize_t show_name(int id,struct class_device *class_dev,char *buf)
+static ssize_t show_name(int id,struct device *class_dev,char *buf)
 {
        struct pvr2_ctrl *cptr;
        struct pvr2_sysfs *sfp;
        const char *name;
 
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
        if (!cptr) return -EINVAL;
@@ -99,14 +99,14 @@ static ssize_t show_name(int id,struct class_device *class_dev,char *buf)
        return scnprintf(buf,PAGE_SIZE,"%s\n",name);
 }
 
-static ssize_t show_type(int id,struct class_device *class_dev,char *buf)
+static ssize_t show_type(int id,struct device *class_dev,char *buf)
 {
        struct pvr2_ctrl *cptr;
        struct pvr2_sysfs *sfp;
        const char *name;
        enum pvr2_ctl_type tp;
 
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
        if (!cptr) return -EINVAL;
@@ -126,13 +126,13 @@ static ssize_t show_type(int id,struct class_device *class_dev,char *buf)
        return scnprintf(buf,PAGE_SIZE,"%s\n",name);
 }
 
-static ssize_t show_min(int id,struct class_device *class_dev,char *buf)
+static ssize_t show_min(int id,struct device *class_dev,char *buf)
 {
        struct pvr2_ctrl *cptr;
        struct pvr2_sysfs *sfp;
        long val;
 
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
        if (!cptr) return -EINVAL;
@@ -143,13 +143,13 @@ static ssize_t show_min(int id,struct class_device *class_dev,char *buf)
        return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
 }
 
-static ssize_t show_max(int id,struct class_device *class_dev,char *buf)
+static ssize_t show_max(int id,struct device *class_dev,char *buf)
 {
        struct pvr2_ctrl *cptr;
        struct pvr2_sysfs *sfp;
        long val;
 
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
        if (!cptr) return -EINVAL;
@@ -160,14 +160,14 @@ static ssize_t show_max(int id,struct class_device *class_dev,char *buf)
        return scnprintf(buf,PAGE_SIZE,"%ld\n",val);
 }
 
-static ssize_t show_val_norm(int id,struct class_device *class_dev,char *buf)
+static ssize_t show_val_norm(int id,struct device *class_dev,char *buf)
 {
        struct pvr2_ctrl *cptr;
        struct pvr2_sysfs *sfp;
        int val,ret;
        unsigned int cnt = 0;
 
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
        if (!cptr) return -EINVAL;
@@ -184,14 +184,14 @@ static ssize_t show_val_norm(int id,struct class_device *class_dev,char *buf)
        return cnt+1;
 }
 
-static ssize_t show_val_custom(int id,struct class_device *class_dev,char *buf)
+static ssize_t show_val_custom(int id,struct device *class_dev,char *buf)
 {
        struct pvr2_ctrl *cptr;
        struct pvr2_sysfs *sfp;
        int val,ret;
        unsigned int cnt = 0;
 
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
        if (!cptr) return -EINVAL;
@@ -208,14 +208,14 @@ static ssize_t show_val_custom(int id,struct class_device *class_dev,char *buf)
        return cnt+1;
 }
 
-static ssize_t show_enum(int id,struct class_device *class_dev,char *buf)
+static ssize_t show_enum(int id,struct device *class_dev,char *buf)
 {
        struct pvr2_ctrl *cptr;
        struct pvr2_sysfs *sfp;
        long val;
        unsigned int bcnt,ccnt,ecnt;
 
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
        if (!cptr) return -EINVAL;
@@ -233,14 +233,14 @@ static ssize_t show_enum(int id,struct class_device *class_dev,char *buf)
        return bcnt;
 }
 
-static ssize_t show_bits(int id,struct class_device *class_dev,char *buf)
+static ssize_t show_bits(int id,struct device *class_dev,char *buf)
 {
        struct pvr2_ctrl *cptr;
        struct pvr2_sysfs *sfp;
        int valid_bits,msk;
        unsigned int bcnt,ccnt;
 
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id);
        if (!cptr) return -EINVAL;
@@ -278,23 +278,23 @@ static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp,
        return ret;
 }
 
-static ssize_t store_val_norm(int id,struct class_device *class_dev,
+static ssize_t store_val_norm(int id,struct device *class_dev,
                             const char *buf,size_t count)
 {
        struct pvr2_sysfs *sfp;
        int ret;
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        ret = store_val_any(id,0,sfp,buf,count);
        if (!ret) ret = count;
        return ret;
 }
 
-static ssize_t store_val_custom(int id,struct class_device *class_dev,
+static ssize_t store_val_custom(int id,struct device *class_dev,
                                const char *buf,size_t count)
 {
        struct pvr2_sysfs *sfp;
        int ret;
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        ret = store_val_any(id,1,sfp,buf,count);
        if (!ret) ret = count;
        return ret;
@@ -304,7 +304,7 @@ static ssize_t store_val_custom(int id,struct class_device *class_dev,
   Mike Isely <isely@pobox.com> 30-April-2005
 
   This next batch of horrible preprocessor hackery is needed because the
-  kernel's class_device_attribute mechanism fails to pass the actual
+  kernel's device_attribute mechanism fails to pass the actual
   attribute through to the show / store functions, which means we have no
   way to package up any attribute-specific parameters, like for example the
   control id.  So we work around this brain-damage by encoding the control
@@ -314,11 +314,13 @@ static ssize_t store_val_custom(int id,struct class_device *class_dev,
 */
 
 #define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \
-static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,char *buf) \
+static ssize_t sf_name##_##ctl_id(struct device *class_dev, \
+struct device_attribute *attr, char *buf) \
 { return sf_name(ctl_id,class_dev,buf); }
 
 #define CREATE_STORE_INSTANCE(sf_name,ctl_id) \
-static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,const char *buf,size_t count) \
+static ssize_t sf_name##_##ctl_id(struct device *class_dev, \
+struct device_attribute *attr, const char *buf, size_t count) \
 { return sf_name(ctl_id,class_dev,buf,count); }
 
 #define CREATE_BATCH(ctl_id) \
@@ -395,17 +397,27 @@ CREATE_BATCH(58)
 CREATE_BATCH(59)
 
 struct pvr2_sysfs_func_set {
-       ssize_t (*show_name)(struct class_device *,char *);
-       ssize_t (*show_type)(struct class_device *,char *);
-       ssize_t (*show_min)(struct class_device *,char *);
-       ssize_t (*show_max)(struct class_device *,char *);
-       ssize_t (*show_enum)(struct class_device *,char *);
-       ssize_t (*show_bits)(struct class_device *,char *);
-       ssize_t (*show_val_norm)(struct class_device *,char *);
-       ssize_t (*store_val_norm)(struct class_device *,
+       ssize_t (*show_name)(struct device *,
+                            struct device_attribute *attr, char *);
+       ssize_t (*show_type)(struct device *,
+                            struct device_attribute *attr, char *);
+       ssize_t (*show_min)(struct device *,
+                           struct device_attribute *attr, char *);
+       ssize_t (*show_max)(struct device *,
+                           struct device_attribute *attr, char *);
+       ssize_t (*show_enum)(struct device *,
+                            struct device_attribute *attr, char *);
+       ssize_t (*show_bits)(struct device *,
+                            struct device_attribute *attr, char *);
+       ssize_t (*show_val_norm)(struct device *,
+                                struct device_attribute *attr, char *);
+       ssize_t (*store_val_norm)(struct device *,
+                                 struct device_attribute *attr,
                                  const char *,size_t);
-       ssize_t (*show_val_custom)(struct class_device *,char *);
-       ssize_t (*store_val_custom)(struct class_device *,
+       ssize_t (*show_val_custom)(struct device *,
+                                  struct device_attribute *attr, char *);
+       ssize_t (*store_val_custom)(struct device *,
+                                   struct device_attribute *attr,
                                    const char *,size_t);
 };
 
@@ -597,9 +609,12 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
 }
 
 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
-static ssize_t debuginfo_show(struct class_device *,char *);
-static ssize_t debugcmd_show(struct class_device *,char *);
-static ssize_t debugcmd_store(struct class_device *,const char *,size_t count);
+static ssize_t debuginfo_show(struct device *, struct device_attribute *,
+                             char *);
+static ssize_t debugcmd_show(struct device *, struct device_attribute *,
+                            char *);
+static ssize_t debugcmd_store(struct device *, struct device_attribute *,
+                             const char *, size_t count);
 
 static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
 {
@@ -616,16 +631,16 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
        dip->attr_debuginfo.attr.mode = S_IRUGO;
        dip->attr_debuginfo.show = debuginfo_show;
        sfp->debugifc = dip;
-       ret = class_device_create_file(sfp->class_dev,&dip->attr_debugcmd);
+       ret = device_create_file(sfp->class_dev,&dip->attr_debugcmd);
        if (ret < 0) {
-               printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+               printk(KERN_WARNING "%s: device_create_file error: %d\n",
                       __FUNCTION__, ret);
        } else {
                dip->debugcmd_created_ok = !0;
        }
-       ret = class_device_create_file(sfp->class_dev,&dip->attr_debuginfo);
+       ret = device_create_file(sfp->class_dev,&dip->attr_debuginfo);
        if (ret < 0) {
-               printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+               printk(KERN_WARNING "%s: device_create_file error: %d\n",
                       __FUNCTION__, ret);
        } else {
                dip->debuginfo_created_ok = !0;
@@ -637,11 +652,11 @@ static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
 {
        if (!sfp->debugifc) return;
        if (sfp->debugifc->debuginfo_created_ok) {
-               class_device_remove_file(sfp->class_dev,
+               device_remove_file(sfp->class_dev,
                                         &sfp->debugifc->attr_debuginfo);
        }
        if (sfp->debugifc->debugcmd_created_ok) {
-               class_device_remove_file(sfp->class_dev,
+               device_remove_file(sfp->class_dev,
                                         &sfp->debugifc->attr_debugcmd);
        }
        kfree(sfp->debugifc);
@@ -683,7 +698,7 @@ static void pvr2_sysfs_class_release(struct class *class)
 }
 
 
-static void pvr2_sysfs_release(struct class_device *class_dev)
+static void pvr2_sysfs_release(struct device *class_dev)
 {
        pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev);
        kfree(class_dev);
@@ -698,32 +713,33 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp)
 #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
        pvr2_sysfs_tear_down_controls(sfp);
        if (sfp->bus_info_created_ok) {
-               class_device_remove_file(sfp->class_dev,
+               device_remove_file(sfp->class_dev,
                                         &sfp->attr_bus_info);
        }
        if (sfp->v4l_minor_number_created_ok) {
-               class_device_remove_file(sfp->class_dev,
+               device_remove_file(sfp->class_dev,
                                         &sfp->attr_v4l_minor_number);
        }
        if (sfp->v4l_radio_minor_number_created_ok) {
-               class_device_remove_file(sfp->class_dev,
+               device_remove_file(sfp->class_dev,
                                         &sfp->attr_v4l_radio_minor_number);
        }
        if (sfp->unit_number_created_ok) {
-               class_device_remove_file(sfp->class_dev,
+               device_remove_file(sfp->class_dev,
                                         &sfp->attr_unit_number);
        }
        pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
-       sfp->class_dev->class_data = NULL;
-       class_device_unregister(sfp->class_dev);
+       sfp->class_dev->driver_data = NULL;
+       device_unregister(sfp->class_dev);
        sfp->class_dev = NULL;
 }
 
 
-static ssize_t v4l_minor_number_show(struct class_device *class_dev,char *buf)
+static ssize_t v4l_minor_number_show(struct device *class_dev,
+                                    struct device_attribute *attr, char *buf)
 {
        struct pvr2_sysfs *sfp;
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        return scnprintf(buf,PAGE_SIZE,"%d\n",
                         pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
@@ -731,21 +747,23 @@ static ssize_t v4l_minor_number_show(struct class_device *class_dev,char *buf)
 }
 
 
-static ssize_t bus_info_show(struct class_device *class_dev,char *buf)
+static ssize_t bus_info_show(struct device *class_dev,
+                            struct device_attribute *attr, char *buf)
 {
        struct pvr2_sysfs *sfp;
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        return scnprintf(buf,PAGE_SIZE,"%s\n",
                         pvr2_hdw_get_bus_info(sfp->channel.hdw));
 }
 
 
-static ssize_t v4l_radio_minor_number_show(struct class_device *class_dev,
+static ssize_t v4l_radio_minor_number_show(struct device *class_dev,
+                                          struct device_attribute *attr,
                                           char *buf)
 {
        struct pvr2_sysfs *sfp;
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        return scnprintf(buf,PAGE_SIZE,"%d\n",
                         pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
@@ -753,10 +771,11 @@ static ssize_t v4l_radio_minor_number_show(struct class_device *class_dev,
 }
 
 
-static ssize_t unit_number_show(struct class_device *class_dev,char *buf)
+static ssize_t unit_number_show(struct device *class_dev,
+                               struct device_attribute *attr, char *buf)
 {
        struct pvr2_sysfs *sfp;
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        return scnprintf(buf,PAGE_SIZE,"%d\n",
                         pvr2_hdw_get_unit_number(sfp->channel.hdw));
@@ -767,7 +786,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
                             struct pvr2_sysfs_class *class_ptr)
 {
        struct usb_device *usb_dev;
-       struct class_device *class_dev;
+       struct device *class_dev;
        int ret;
 
        usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw);
@@ -779,23 +798,23 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
 
        class_dev->class = &class_ptr->class;
        if (pvr2_hdw_get_sn(sfp->channel.hdw)) {
-               snprintf(class_dev->class_id,BUS_ID_SIZE,"sn-%lu",
+               snprintf(class_dev->bus_id, BUS_ID_SIZE, "sn-%lu",
                         pvr2_hdw_get_sn(sfp->channel.hdw));
        } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
-               snprintf(class_dev->class_id,BUS_ID_SIZE,"unit-%c",
+               snprintf(class_dev->bus_id, BUS_ID_SIZE, "unit-%c",
                         pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
        } else {
                kfree(class_dev);
                return;
        }
 
-       class_dev->dev = &usb_dev->dev;
+       class_dev->parent = &usb_dev->dev;
 
        sfp->class_dev = class_dev;
-       class_dev->class_data = sfp;
-       ret = class_device_register(class_dev);
+       class_dev->driver_data = sfp;
+       ret = device_register(class_dev);
        if (ret) {
-               printk(KERN_ERR "%s: class_device_register failed\n",
+               printk(KERN_ERR "%s: device_register failed\n",
                       __FUNCTION__);
                kfree(class_dev);
                return;
@@ -805,10 +824,10 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
        sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
        sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
        sfp->attr_v4l_minor_number.store = NULL;
-       ret = class_device_create_file(sfp->class_dev,
+       ret = device_create_file(sfp->class_dev,
                                       &sfp->attr_v4l_minor_number);
        if (ret < 0) {
-               printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+               printk(KERN_WARNING "%s: device_create_file error: %d\n",
                       __FUNCTION__, ret);
        } else {
                sfp->v4l_minor_number_created_ok = !0;
@@ -818,10 +837,10 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
        sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
        sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
        sfp->attr_v4l_radio_minor_number.store = NULL;
-       ret = class_device_create_file(sfp->class_dev,
+       ret = device_create_file(sfp->class_dev,
                                       &sfp->attr_v4l_radio_minor_number);
        if (ret < 0) {
-               printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+               printk(KERN_WARNING "%s: device_create_file error: %d\n",
                       __FUNCTION__, ret);
        } else {
                sfp->v4l_radio_minor_number_created_ok = !0;
@@ -831,9 +850,9 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
        sfp->attr_unit_number.attr.mode = S_IRUGO;
        sfp->attr_unit_number.show = unit_number_show;
        sfp->attr_unit_number.store = NULL;
-       ret = class_device_create_file(sfp->class_dev,&sfp->attr_unit_number);
+       ret = device_create_file(sfp->class_dev,&sfp->attr_unit_number);
        if (ret < 0) {
-               printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+               printk(KERN_WARNING "%s: device_create_file error: %d\n",
                       __FUNCTION__, ret);
        } else {
                sfp->unit_number_created_ok = !0;
@@ -843,10 +862,10 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
        sfp->attr_bus_info.attr.mode = S_IRUGO;
        sfp->attr_bus_info.show = bus_info_show;
        sfp->attr_bus_info.store = NULL;
-       ret = class_device_create_file(sfp->class_dev,
+       ret = device_create_file(sfp->class_dev,
                                       &sfp->attr_bus_info);
        if (ret < 0) {
-               printk(KERN_WARNING "%s: class_device_create_file error: %d\n",
+               printk(KERN_WARNING "%s: device_create_file error: %d\n",
                       __FUNCTION__, ret);
        } else {
                sfp->bus_info_created_ok = !0;
@@ -886,7 +905,7 @@ struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
 }
 
 
-static int pvr2_sysfs_hotplug(struct class_device *cd,char **envp,
+static int pvr2_sysfs_hotplug(struct device *cd,char **envp,
                              int numenvp,char *buf,int size)
 {
        /* Even though we don't do anything here, we still need this function
@@ -902,8 +921,8 @@ struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
        pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp);
        clp->class.name = "pvrusb2";
        clp->class.class_release = pvr2_sysfs_class_release;
-       clp->class.release = pvr2_sysfs_release;
-       clp->class.uevent = pvr2_sysfs_hotplug;
+       clp->class.dev_release = pvr2_sysfs_release;
+       clp->class.dev_uevent = pvr2_sysfs_hotplug;
        if (class_register(&clp->class)) {
                pvr2_sysfs_trace(
                        "Registration failed for pvr2_sysfs_class id=%p",clp);
@@ -921,32 +940,35 @@ void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
 
 
 #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
-static ssize_t debuginfo_show(struct class_device *class_dev,char *buf)
+static ssize_t debuginfo_show(struct device *class_dev,
+                             struct device_attribute *attr, char *buf)
 {
        struct pvr2_sysfs *sfp;
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        pvr2_hdw_trigger_module_log(sfp->channel.hdw);
        return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE);
 }
 
 
-static ssize_t debugcmd_show(struct class_device *class_dev,char *buf)
+static ssize_t debugcmd_show(struct device *class_dev,
+                            struct device_attribute *attr, char *buf)
 {
        struct pvr2_sysfs *sfp;
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
        return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE);
 }
 
 
-static ssize_t debugcmd_store(struct class_device *class_dev,
-                             const char *buf,size_t count)
+static ssize_t debugcmd_store(struct device *class_dev,
+                             struct device_attribute *attr,
+                             const char *buf, size_t count)
 {
        struct pvr2_sysfs *sfp;
        int ret;
 
-       sfp = (struct pvr2_sysfs *)class_dev->class_data;
+       sfp = (struct pvr2_sysfs *)class_dev->driver_data;
        if (!sfp) return -EINVAL;
 
        ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
index 338ced7188f2758d59d3da8e5736e7da49fe8e6d..ea53316d2111fdb2141fc8840755a6b57ce2fe94 100644 (file)
@@ -1648,7 +1648,7 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
                ARG_OUT(cmd)
                break;
        }
-       /*
+       /*
        case VIDIOCPWCGVIDTABLE:
        {
                ARG_DEF(struct pwc_table_init_buffer, table);
index 931b274bffcadf82bc5fa85cf7d9041721e961f8..0b67d4ec0318f7ab9ef675940cb45057aad12524 100644 (file)
@@ -64,7 +64,6 @@
 #include <linux/vmalloc.h>
 #include <linux/version.h>
 #include <asm/io.h>
-#include <linux/moduleparam.h>
 
 #include "pwc.h"
 #include "pwc-kiara.h"
@@ -127,9 +126,9 @@ static struct usb_driver pwc_driver = {
 static int default_size = PSZ_QCIF;
 static int default_fps = 10;
 static int default_fbufs = 3;   /* Default number of frame buffers */
-       int pwc_mbufs = 2;      /* Default number of mmap() buffers */
+       int pwc_mbufs = 2;      /* Default number of mmap() buffers */
 #ifdef CONFIG_USB_PWC_DEBUG
-       int pwc_trace = PWC_DEBUG_LEVEL;
+       int pwc_trace = PWC_DEBUG_LEVEL;
 #endif
 static int power_save = 0;
 static int led_on = 100, led_off = 0; /* defaults to LED that is on while in use */
@@ -908,31 +907,49 @@ int pwc_isoc_init(struct pwc_device *pdev)
        return 0;
 }
 
-void pwc_isoc_cleanup(struct pwc_device *pdev)
+static void pwc_iso_stop(struct pwc_device *pdev)
 {
        int i;
 
-       PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
-       if (pdev == NULL)
-               return;
-       if (pdev->iso_init == 0)
-               return;
-
        /* Unlinking ISOC buffers one by one */
        for (i = 0; i < MAX_ISO_BUFS; i++) {
                struct urb *urb;
 
                urb = pdev->sbuf[i].urb;
                if (urb != 0) {
-                       if (pdev->iso_init) {
-                               PWC_DEBUG_MEMORY("Unlinking URB %p\n", urb);
-                               usb_kill_urb(urb);
-                       }
+                       PWC_DEBUG_MEMORY("Unlinking URB %p\n", urb);
+                       usb_kill_urb(urb);
+               }
+       }
+}
+
+static void pwc_iso_free(struct pwc_device *pdev)
+{
+       int i;
+
+       /* Freeing ISOC buffers one by one */
+       for (i = 0; i < MAX_ISO_BUFS; i++) {
+               struct urb *urb;
+
+               urb = pdev->sbuf[i].urb;
+               if (urb != 0) {
                        PWC_DEBUG_MEMORY("Freeing URB\n");
                        usb_free_urb(urb);
                        pdev->sbuf[i].urb = NULL;
                }
        }
+}
+
+void pwc_isoc_cleanup(struct pwc_device *pdev)
+{
+       PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
+       if (pdev == NULL)
+               return;
+       if (pdev->iso_init == 0)
+               return;
+
+       pwc_iso_stop(pdev);
+       pwc_iso_free(pdev);
 
        /* Stop camera, but only if we are sure the camera is still there (unplug
           is signalled by EPIPE)
@@ -979,20 +996,22 @@ int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_f
 /*********
  * sysfs
  *********/
-static struct pwc_device *cd_to_pwc(struct class_device *cd)
+static struct pwc_device *cd_to_pwc(struct device *cd)
 {
        struct video_device *vdev = to_video_device(cd);
        return video_get_drvdata(vdev);
 }
 
-static ssize_t show_pan_tilt(struct class_device *class_dev, char *buf)
+static ssize_t show_pan_tilt(struct device *class_dev,
+                            struct device_attribute *attr, char *buf)
 {
        struct pwc_device *pdev = cd_to_pwc(class_dev);
        return sprintf(buf, "%d %d\n", pdev->pan_angle, pdev->tilt_angle);
 }
 
-static ssize_t store_pan_tilt(struct class_device *class_dev, const char *buf,
-                        size_t count)
+static ssize_t store_pan_tilt(struct device *class_dev,
+                             struct device_attribute *attr,
+                             const char *buf, size_t count)
 {
        struct pwc_device *pdev = cd_to_pwc(class_dev);
        int pan, tilt;
@@ -1008,10 +1027,11 @@ static ssize_t store_pan_tilt(struct class_device *class_dev, const char *buf,
                return ret;
        return strlen(buf);
 }
-static CLASS_DEVICE_ATTR(pan_tilt, S_IRUGO | S_IWUSR, show_pan_tilt,
-                        store_pan_tilt);
+static DEVICE_ATTR(pan_tilt, S_IRUGO | S_IWUSR, show_pan_tilt,
+                  store_pan_tilt);
 
-static ssize_t show_snapshot_button_status(struct class_device *class_dev, char *buf)
+static ssize_t show_snapshot_button_status(struct device *class_dev,
+                                          struct device_attribute *attr, char *buf)
 {
        struct pwc_device *pdev = cd_to_pwc(class_dev);
        int status = pdev->snapshot_button_status;
@@ -1019,26 +1039,26 @@ static ssize_t show_snapshot_button_status(struct class_device *class_dev, char
        return sprintf(buf, "%d\n", status);
 }
 
-static CLASS_DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status,
-                        NULL);
+static DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status,
+                  NULL);
 
 static int pwc_create_sysfs_files(struct video_device *vdev)
 {
        struct pwc_device *pdev = video_get_drvdata(vdev);
        int rc;
 
-       rc = video_device_create_file(vdev, &class_device_attr_button);
+       rc = video_device_create_file(vdev, &dev_attr_button);
        if (rc)
                goto err;
        if (pdev->features & FEATURE_MOTOR_PANTILT) {
-               rc = video_device_create_file(vdev,&class_device_attr_pan_tilt);
+               rc = video_device_create_file(vdev, &dev_attr_pan_tilt);
                if (rc) goto err_button;
        }
 
        return 0;
 
 err_button:
-       video_device_remove_file(vdev, &class_device_attr_button);
+       video_device_remove_file(vdev, &dev_attr_button);
 err:
        return rc;
 }
@@ -1047,8 +1067,8 @@ static void pwc_remove_sysfs_files(struct video_device *vdev)
 {
        struct pwc_device *pdev = video_get_drvdata(vdev);
        if (pdev->features & FEATURE_MOTOR_PANTILT)
-               video_device_remove_file(vdev, &class_device_attr_pan_tilt);
-       video_device_remove_file(vdev, &class_device_attr_button);
+               video_device_remove_file(vdev, &dev_attr_pan_tilt);
+       video_device_remove_file(vdev, &dev_attr_button);
 }
 
 #ifdef CONFIG_USB_PWC_DEBUG
@@ -1212,6 +1232,7 @@ static int pwc_video_close(struct inode *inode, struct file *file)
 
        PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
 
+       lock_kernel();
        pdev = (struct pwc_device *)vdev->priv;
        if (pdev->vopen == 0)
                PWC_DEBUG_MODULE("video_close() called on closed device?\n");
@@ -1231,7 +1252,6 @@ static int pwc_video_close(struct inode *inode, struct file *file)
        pwc_isoc_cleanup(pdev);
        pwc_free_buffers(pdev);
 
-       lock_kernel();
        /* Turn off LEDS and power down camera, but only when not unplugged */
        if (!pdev->unplugged) {
                /* Turn LEDs off */
@@ -1277,7 +1297,7 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
        struct pwc_device *pdev;
        int noblock = file->f_flags & O_NONBLOCK;
        DECLARE_WAITQUEUE(wait, current);
-       int bytes_to_read;
+       int bytes_to_read, rv = 0;
        void *image_buffer_addr;
 
        PWC_DEBUG_READ("pwc_video_read(vdev=0x%p, buf=%p, count=%zd) called.\n",
@@ -1287,8 +1307,12 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
        pdev = vdev->priv;
        if (pdev == NULL)
                return -EFAULT;
-       if (pdev->error_status)
-               return -pdev->error_status; /* Something happened, report what. */
+
+       mutex_lock(&pdev->modlock);
+       if (pdev->error_status) {
+               rv = -pdev->error_status; /* Something happened, report what. */
+               goto err_out;
+       }
 
        /* In case we're doing partial reads, we don't have to wait for a frame */
        if (pdev->image_read_pos == 0) {
@@ -1299,17 +1323,20 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
                        if (pdev->error_status) {
                                remove_wait_queue(&pdev->frameq, &wait);
                                set_current_state(TASK_RUNNING);
-                               return -pdev->error_status ;
+                               rv = -pdev->error_status ;
+                               goto err_out;
                        }
                        if (noblock) {
                                remove_wait_queue(&pdev->frameq, &wait);
                                set_current_state(TASK_RUNNING);
-                               return -EWOULDBLOCK;
+                               rv = -EWOULDBLOCK;
+                               goto err_out;
                        }
                        if (signal_pending(current)) {
                                remove_wait_queue(&pdev->frameq, &wait);
                                set_current_state(TASK_RUNNING);
-                               return -ERESTARTSYS;
+                               rv = -ERESTARTSYS;
+                               goto err_out;
                        }
                        schedule();
                        set_current_state(TASK_INTERRUPTIBLE);
@@ -1318,8 +1345,10 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
                set_current_state(TASK_RUNNING);
 
                /* Decompress and release frame */
-               if (pwc_handle_frame(pdev))
-                       return -EFAULT;
+               if (pwc_handle_frame(pdev)) {
+                       rv = -EFAULT;
+                       goto err_out;
+               }
        }
 
        PWC_DEBUG_READ("Copying data to user space.\n");
@@ -1334,14 +1363,20 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
        image_buffer_addr = pdev->image_data;
        image_buffer_addr += pdev->images[pdev->fill_image].offset;
        image_buffer_addr += pdev->image_read_pos;
-       if (copy_to_user(buf, image_buffer_addr, count))
-               return -EFAULT;
+       if (copy_to_user(buf, image_buffer_addr, count)) {
+               rv = -EFAULT;
+               goto err_out;
+       }
        pdev->image_read_pos += count;
        if (pdev->image_read_pos >= bytes_to_read) { /* All data has been read */
                pdev->image_read_pos = 0;
                pwc_next_image(pdev);
        }
+       mutex_unlock(&pdev->modlock);
        return count;
+err_out:
+       mutex_unlock(&pdev->modlock);
+       return rv;
 }
 
 static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
@@ -1367,7 +1402,20 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
 static int pwc_video_ioctl(struct inode *inode, struct file *file,
                           unsigned int cmd, unsigned long arg)
 {
-       return video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl);
+       struct video_device *vdev = file->private_data;
+       struct pwc_device *pdev;
+       int r = -ENODEV;
+
+       if (!vdev)
+               goto out;
+       pdev = vdev->priv;
+
+       mutex_lock(&pdev->modlock);
+       if (!pdev->unplugged)
+               r = video_usercopy(inode, file, cmd, arg, pwc_video_do_ioctl);
+       mutex_unlock(&pdev->modlock);
+out:
+       return r;
 }
 
 static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
@@ -1810,7 +1858,10 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
        wake_up_interruptible(&pdev->frameq);
        /* Wait until device is closed */
        if(pdev->vopen) {
+               mutex_lock(&pdev->modlock);
                pdev->unplugged = 1;
+               mutex_unlock(&pdev->modlock);
+               pwc_iso_stop(pdev);
        } else {
                /* Device is closed, so we can safely unregister it */
                PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
@@ -1828,7 +1879,6 @@ disconnect_out:
        unlock_kernel();
 }
 
-
 /* *grunt* We have to do atoi ourselves :-( */
 static int pwc_atoi(const char *s)
 {
index 92eabf88a09b72e336ce55ea1b4f4901b432ce18..72e344a12c798e86a5ca06db54c4c7a8059e423b 100644 (file)
@@ -406,6 +406,7 @@ static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind)
                kfree(s);
                return -ENOMEM;
        }
+       spin_lock_init(&s->lock);
        s->client = client_template;
        s->block_count = 0;
        s->wr_index = 0;
index 9f986930490f7022326cd3c4a1b844b13a3e573d..e35ef321ec717b7da3b1a8e0ef0fa2eb424df718 100644 (file)
@@ -332,11 +332,11 @@ static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_dat
        if (!enable)
                return 0;
 
-       state->vps_data[0] = data->data[4];
-       state->vps_data[1] = data->data[10];
-       state->vps_data[2] = data->data[11];
-       state->vps_data[3] = data->data[12];
-       state->vps_data[4] = data->data[13];
+       state->vps_data[0] = data->data[2];
+       state->vps_data[1] = data->data[8];
+       state->vps_data[2] = data->data[9];
+       state->vps_data[3] = data->data[10];
+       state->vps_data[4] = data->data[11];
        v4l_dbg(1, debug, client, "Set VPS data %02x %02x %02x %02x %02x\n",
                state->vps_data[0], state->vps_data[1],
                state->vps_data[2], state->vps_data[3],
index 9f1417a4f7d2f49143a30f5bb8b788b4a7caf44f..d6d8d660196d992c6fad885c30fb7c7b0661eda5 100644 (file)
@@ -1,7 +1,7 @@
 config VIDEO_SAA7134
        tristate "Philips SAA7134 support"
        depends on VIDEO_DEV && PCI && I2C
-       select VIDEO_BUF
+       select VIDEOBUF_DMA_SG
        select VIDEO_IR
        select VIDEO_TUNER
        select CRC32
@@ -38,7 +38,7 @@ config VIDEO_SAA7134_OSS
 config VIDEO_SAA7134_DVB
        tristate "DVB/ATSC Support for saa7134 based TV cards"
        depends on VIDEO_SAA7134 && DVB_CORE
-       select VIDEO_BUF_DVB
+       select VIDEOBUF_DVB
        select FW_LOADER
        select DVB_PLL if !DVB_FE_CUSTOMISE
        select DVB_MT352 if !DVB_FE_CUSTOMISE
index 3c0fc9027ad01118d8c67ee0e82fe74ab4597741..c6f7279669c184257dbcd8961478edced7f1627f 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/wait.h>
-#include <linux/moduleparam.h>
 #include <linux/module.h>
 #include <sound/driver.h>
 #include <sound/core.h>
@@ -313,7 +312,7 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
        dev->dmasound.blksize = 0;
        dev->dmasound.bufsize = 0;
 
-       return 0;
+       return 0;
 }
 
 
index 25ec16810818c2758555ad11a3c98ffc4e466e92..a4c192fb4e41172cb97e7a8104aecdda16341d74 100644 (file)
@@ -32,6 +32,7 @@ static char name_mute[]    = "mute";
 static char name_radio[]   = "Radio";
 static char name_tv[]      = "Television";
 static char name_tv_mono[] = "TV (mono only)";
+static char name_comp[]    = "Composite";
 static char name_comp1[]   = "Composite1";
 static char name_comp2[]   = "Composite2";
 static char name_comp3[]   = "Composite3";
@@ -1535,12 +1536,7 @@ struct saa7134_board saa7134_boards[] = {
                        .tv   = 1,
                        .gpio = 0x00,
                },{
-                       .name = name_comp1,
-                       .vmux = 0,
-                       .amux = LINE1,
-                       .gpio = 0x02,
-               },{
-                       .name = name_comp2,
+                       .name = name_comp,
                        .vmux = 3,
                        .amux = LINE1,
                        .gpio = 0x02,
@@ -2771,6 +2767,7 @@ struct saa7134_board saa7134_boards[] = {
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
                .mpeg           = SAA7134_MPEG_DVB,
+               .gpiomask       = 1 << 21,
                .inputs = {{
                        .name   = name_tv,
                        .vmux   = 1,
@@ -2781,13 +2778,18 @@ struct saa7134_board saa7134_boards[] = {
                        .vmux   = 3,
                        .amux   = LINE1,
                },{
-                       .name   = name_svideo,
+                       .name   = name_comp2,
                        .vmux   = 0,
                        .amux   = LINE1,
+               },{
+                       .name   = name_svideo,
+                       .vmux   = 8,
+                       .amux   = LINE1,
                }},
                .radio = {
                        .name   = name_radio,
-                       .amux   = LINE1,
+                       .amux   = TV,
+                       .gpio   = 0x0200000,
                },
        },
        [SAA7134_BOARD_KWORLD_DVBT_210] = {
@@ -2820,7 +2822,7 @@ struct saa7134_board saa7134_boards[] = {
                },
        },
        [SAA7134_BOARD_KWORLD_ATSC110] = {
-               .name           = "Kworld ATSC110",
+               .name           = "Kworld ATSC110/115",
                .audio_clock    = 0x00187de7,
                .tuner_type     = TUNER_PHILIPS_TUV1236D,
                .radio_type     = UNSET,
@@ -2896,7 +2898,7 @@ struct saa7134_board saa7134_boards[] = {
                .radio_addr     = ADDR_UNSET,
        },
        [SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS] = {
-               .name           = "LifeView FlyDVB-T Hybrid Cardbus",
+               .name           = "LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB",
                .audio_clock    = 0x00200000,
                .tuner_type     = TUNER_PHILIPS_TDA8290,
                .radio_type     = UNSET,
@@ -3534,6 +3536,22 @@ struct saa7134_board saa7134_boards[] = {
                        .gpio = 0x3000,
                },
        },
+       [SAA7134_BOARD_AVERMEDIA_SUPER_007] = {
+               .name           = "Avermedia Super 007",
+               .audio_clock    = 0x00187de7,
+               .tuner_type     = TUNER_PHILIPS_TDA8290,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .tuner_config   = 0,
+               .mpeg           = SAA7134_MPEG_DVB,
+               .inputs = {{
+                       .name   = name_tv, /* FIXME: analog tv untested */
+                       .vmux   = 1,
+                       .amux   = TV,
+                       .tv     = 1,
+               }},
+       },
 };
 
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -4064,6 +4082,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x17de,
                .subdevice    = 0x7350,
                .driver_data  = SAA7134_BOARD_KWORLD_ATSC110,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
+               .subvendor    = 0x17de,
+               .subdevice    = 0x7352,
+               .driver_data  = SAA7134_BOARD_KWORLD_ATSC110, /* ATSC 115 */
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -4256,6 +4280,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = PCI_VENDOR_ID_PHILIPS,
                .subdevice    = 0x2304,
                .driver_data  = SAA7134_BOARD_10MOONSTVMASTER3,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+               .subvendor    = 0x1461, /* Avermedia Technologies Inc */
+               .subdevice    = 0xf01d, /* AVerTV DVB-T Super 007 */
+               .driver_data  = SAA7134_BOARD_AVERMEDIA_SUPER_007,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+               .subvendor    = 0x4e42,
+               .subdevice    = 0x3502,
+               .driver_data  = SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS
        },{
                /* --- boards without eeprom + subsystem ID --- */
                .vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -4564,6 +4600,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
                break;
        case SAA7134_BOARD_PHILIPS_TIGER:
        case SAA7134_BOARD_PHILIPS_TIGER_S:
+       case SAA7134_BOARD_AVERMEDIA_SUPER_007:
                {
                u8 data[] = { 0x3c, 0x33, 0x60};
                struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
index 25f84701a8e8f8a473ff617cb7dc898f265f2302..1a4a24471f204da1bd71cfd6c3578725a09d4da7 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
@@ -32,6 +31,7 @@
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/dma-mapping.h>
+#include <linux/pm.h>
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
@@ -237,9 +237,10 @@ int saa7134_buffer_startpage(struct saa7134_buf *buf)
 unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
 {
        unsigned long base;
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
 
        base  = saa7134_buffer_startpage(buf) * 4096;
-       base += buf->vb.dma.sglist[0].offset;
+       base += dma->sglist[0].offset;
        return base;
 }
 
@@ -287,11 +288,12 @@ void saa7134_pgtable_free(struct pci_dev *pci, struct saa7134_pgtable *pt)
 
 void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf)
 {
+       struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
        BUG_ON(in_interrupt());
 
        videobuf_waiton(&buf->vb,0,0);
-       videobuf_dma_unmap(q, &buf->vb.dma);
-       videobuf_dma_free(&buf->vb.dma);
+       videobuf_dma_unmap(q, dma);
+       videobuf_dma_free(dma);
        buf->vb.state = STATE_NEEDS_INIT;
 }
 
@@ -391,6 +393,32 @@ void saa7134_buffer_timeout(unsigned long data)
        spin_unlock_irqrestore(&dev->slock,flags);
 }
 
+/* resends a current buffer in queue after resume */
+
+int saa7134_buffer_requeue(struct saa7134_dev *dev,
+                        struct saa7134_dmaqueue *q)
+{
+       struct saa7134_buf *buf, *next;
+
+       assert_spin_locked(&dev->slock);
+
+       buf  = q->curr;
+       next = buf;
+       dprintk("buffer_requeue\n");
+
+       if (!buf)
+               return 0;
+
+       dprintk("buffer_requeue : resending active buffers \n");
+
+       if (!list_empty(&q->queue))
+               next = list_entry(q->queue.next, struct saa7134_buf,
+                                         vb.queue);
+       buf->activate(dev, buf, next);
+
+       return 0;
+}
+
 /* ------------------------------------------------------------------ */
 
 int saa7134_set_dmabits(struct saa7134_dev *dev)
@@ -401,6 +429,9 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
 
        assert_spin_locked(&dev->slock);
 
+       if (dev->inresume)
+               return 0;
+
        /* video capture -- dma 0 + video task A */
        if (dev->video_q.curr) {
                task |= 0x01;
@@ -560,8 +591,10 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id)
                        print_irqstatus(dev,loop,report,status);
 
 
-               if (report & SAA7134_IRQ_REPORT_RDCAP /* _INTL */)
-                       saa7134_irq_video_intl(dev);
+               if ((report & SAA7134_IRQ_REPORT_RDCAP) ||
+                       (report & SAA7134_IRQ_REPORT_INTL))
+                               saa7134_irq_video_signalchange(dev);
+
 
                if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
                    (status & 0x60) == 0)
@@ -646,6 +679,39 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id)
 /* ------------------------------------------------------------------ */
 
 /* early init (no i2c, no irq) */
+
+static int saa7134_hw_enable1(struct saa7134_dev *dev)
+{
+       /* RAM FIFO config */
+       saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
+       saa_writel(SAA7134_THRESHOULD, 0x02020202);
+
+       /* enable audio + video processing */
+       saa_writel(SAA7134_MAIN_CTRL,
+                       SAA7134_MAIN_CTRL_VPLLE |
+                       SAA7134_MAIN_CTRL_APLLE |
+                       SAA7134_MAIN_CTRL_EXOSC |
+                       SAA7134_MAIN_CTRL_EVFE1 |
+                       SAA7134_MAIN_CTRL_EVFE2 |
+                       SAA7134_MAIN_CTRL_ESFE  |
+                       SAA7134_MAIN_CTRL_EBDAC);
+
+       /*
+       * Initialize OSS _after_ enabling audio clock PLL and audio processing.
+       * OSS initialization writes to registers via the audio DSP; these
+       * writes will fail unless the audio clock has been started.  At worst,
+       * audio will not work.
+       */
+
+       /* enable peripheral devices */
+       saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
+
+       /* set vertical line numbering start (vbi needs this) */
+       saa_writeb(SAA7134_SOURCE_TIMING2, 0x20);
+
+       return 0;
+}
+
 static int saa7134_hwinit1(struct saa7134_dev *dev)
 {
        dprintk("hwinit1\n");
@@ -662,44 +728,16 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
                saa7134_ts_init1(dev);
        saa7134_input_init1(dev);
 
-       /* RAM FIFO config */
-       saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
-       saa_writel(SAA7134_THRESHOULD,0x02020202);
-
-       /* enable audio + video processing */
-       saa_writel(SAA7134_MAIN_CTRL,
-                  SAA7134_MAIN_CTRL_VPLLE |
-                  SAA7134_MAIN_CTRL_APLLE |
-                  SAA7134_MAIN_CTRL_EXOSC |
-                  SAA7134_MAIN_CTRL_EVFE1 |
-                  SAA7134_MAIN_CTRL_EVFE2 |
-                  SAA7134_MAIN_CTRL_ESFE  |
-                  SAA7134_MAIN_CTRL_EBDAC);
-
-       /*
-        * Initialize OSS _after_ enabling audio clock PLL and audio processing.
-        * OSS initialization writes to registers via the audio DSP; these
-        * writes will fail unless the audio clock has been started.  At worst,
-        * audio will not work.
-        */
-
-       /* enable peripheral devices */
-       saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
-
-       /* set vertical line numbering start (vbi needs this) */
-       saa_writeb(SAA7134_SOURCE_TIMING2, 0x20);
+       saa7134_hw_enable1(dev);
 
        return 0;
 }
 
 /* late init (with i2c + irq) */
-static int saa7134_hwinit2(struct saa7134_dev *dev)
+static int saa7134_hw_enable2(struct saa7134_dev *dev)
 {
-       unsigned int irq2_mask;
-       dprintk("hwinit2\n");
 
-       saa7134_video_init2(dev);
-       saa7134_tvaudio_init2(dev);
+       unsigned int irq2_mask;
 
        /* enable IRQ's */
        irq2_mask =
@@ -725,6 +763,20 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
        return 0;
 }
 
+static int saa7134_hwinit2(struct saa7134_dev *dev)
+{
+
+       dprintk("hwinit2\n");
+
+       saa7134_video_init2(dev);
+       saa7134_tvaudio_init2(dev);
+
+       saa7134_hw_enable2(dev);
+
+       return 0;
+}
+
+
 /* shutdown */
 static int saa7134_hwfini(struct saa7134_dev *dev)
 {
@@ -838,7 +890,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
                                     const struct pci_device_id *pci_id)
 {
        struct saa7134_dev *dev;
-       struct list_head *item;
        struct saa7134_mpeg_ops *mops;
        int err;
 
@@ -1020,15 +1071,13 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
        saa7134_devcount++;
 
        mutex_lock(&devlist_lock);
-       list_for_each(item,&mops_list) {
-               mops = list_entry(item, struct saa7134_mpeg_ops, next);
+       list_for_each_entry(mops, &mops_list, next)
                mpeg_ops_attach(mops, dev);
-       }
        list_add_tail(&dev->devlist,&saa7134_devlist);
        mutex_unlock(&devlist_lock);
 
        /* check for signal */
-       saa7134_irq_video_intl(dev);
+       saa7134_irq_video_signalchange(dev);
 
        if (saa7134_dmasound_init && !dev->dmasound.priv_data) {
                saa7134_dmasound_init(dev);
@@ -1057,7 +1106,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
 static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
 {
        struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
-       struct list_head *item;
        struct saa7134_mpeg_ops *mops;
 
        /* Release DMA sound modules if present */
@@ -1086,10 +1134,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
        /* unregister */
        mutex_lock(&devlist_lock);
        list_del(&dev->devlist);
-       list_for_each(item,&mops_list) {
-               mops = list_entry(item, struct saa7134_mpeg_ops, next);
+       list_for_each_entry(mops, &mops_list, next)
                mpeg_ops_detach(mops, dev);
-       }
        mutex_unlock(&devlist_lock);
        saa7134_devcount--;
 
@@ -1117,18 +1163,79 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
        kfree(dev);
 }
 
+static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
+{
+
+       struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+
+       /* disable overlay - apps should enable it explicitly on resume*/
+       dev->ovenable = 0;
+
+       /* Disable interrupts, DMA, and rest of the chip*/
+       saa_writel(SAA7134_IRQ1, 0);
+       saa_writel(SAA7134_IRQ2, 0);
+       saa_writel(SAA7134_MAIN_CTRL, 0);
+
+       pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
+       pci_save_state(pci_dev);
+
+    return 0;
+}
+
+static int saa7134_resume(struct pci_dev *pci_dev)
+{
+
+       struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+       unsigned int flags;
+
+       pci_restore_state(pci_dev);
+       pci_set_power_state(pci_dev, PCI_D0);
+
+       /* Do things that are done in saa7134_initdev ,
+               except of initializing memory structures.*/
+
+       dev->inresume = 1;
+       saa7134_board_init1(dev);
+
+       if (saa7134_boards[dev->board].video_out)
+               saa7134_videoport_init(dev);
+
+       if (card_has_mpeg(dev))
+               saa7134_ts_init_hw(dev);
+
+       saa7134_hw_enable1(dev);
+       saa7134_set_decoder(dev);
+       saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+       saa7134_board_init2(dev);
+       saa7134_hw_enable2(dev);
+
+       saa7134_tvaudio_setmute(dev);
+       saa7134_tvaudio_setvolume(dev, dev->ctl_volume);
+       saa7134_enable_i2s(dev);
+
+       /*resume unfinished buffer(s)*/
+       spin_lock_irqsave(&dev->slock, flags);
+       saa7134_buffer_requeue(dev, &dev->video_q);
+       saa7134_buffer_requeue(dev, &dev->vbi_q);
+       saa7134_buffer_requeue(dev, &dev->ts_q);
+
+       /* start DMA now*/
+       dev->inresume = 0;
+       saa7134_set_dmabits(dev);
+       spin_unlock_irqrestore(&dev->slock, flags);
+
+       return 0;
+}
+
 /* ----------------------------------------------------------- */
 
 int saa7134_ts_register(struct saa7134_mpeg_ops *ops)
 {
-       struct list_head *item;
        struct saa7134_dev *dev;
 
        mutex_lock(&devlist_lock);
-       list_for_each(item,&saa7134_devlist) {
-               dev = list_entry(item, struct saa7134_dev, devlist);
+       list_for_each_entry(dev, &saa7134_devlist, devlist)
                mpeg_ops_attach(ops, dev);
-       }
        list_add_tail(&ops->next,&mops_list);
        mutex_unlock(&devlist_lock);
        return 0;
@@ -1136,15 +1243,12 @@ int saa7134_ts_register(struct saa7134_mpeg_ops *ops)
 
 void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops)
 {
-       struct list_head *item;
        struct saa7134_dev *dev;
 
        mutex_lock(&devlist_lock);
        list_del(&ops->next);
-       list_for_each(item,&saa7134_devlist) {
-               dev = list_entry(item, struct saa7134_dev, devlist);
+       list_for_each_entry(dev, &saa7134_devlist, devlist)
                mpeg_ops_detach(ops, dev);
-       }
        mutex_unlock(&devlist_lock);
 }
 
@@ -1158,6 +1262,8 @@ static struct pci_driver saa7134_pci_driver = {
        .id_table = saa7134_pci_tbl,
        .probe    = saa7134_initdev,
        .remove   = __devexit_p(saa7134_finidev),
+       .suspend  = saa7134_suspend,
+       .resume   = saa7134_resume
 };
 
 static int saa7134_init(void)
index 1f6bd3300715994db922aff1b00de86f7953410a..38d87332cc5dcd312fd815bece3d40709ee38c42 100644 (file)
@@ -567,6 +567,7 @@ static void configure_tda827x_fe(struct saa7134_dev *dev, struct tda1004x_config
 }
 
 /* ------------------------------------------------------------------ */
+
 static struct tda1004x_config tda827x_lifeview_config = {
        .demod_address = 0x08,
        .invert        = 1,
@@ -746,6 +747,7 @@ static struct tda1004x_config asus_p7131_hybrid_lna_config = {
        .antenna_switch= 2,
        .request_firmware = philips_tda1004x_request_firmware
 };
+
 static struct tda1004x_config kworld_dvb_t_210_config = {
        .demod_address = 0x08,
        .invert        = 1,
@@ -760,6 +762,22 @@ static struct tda1004x_config kworld_dvb_t_210_config = {
        .antenna_switch= 1,
        .request_firmware = philips_tda1004x_request_firmware
 };
+
+static struct tda1004x_config avermedia_super_007_config = {
+       .demod_address = 0x08,
+       .invert        = 1,
+       .invert_oclk   = 0,
+       .xtal_freq     = TDA10046_XTAL_16M,
+       .agc_config    = TDA10046_AGC_TDA827X,
+       .gpio_config   = TDA10046_GP01_I,
+       .if_freq       = TDA10046_FREQ_045,
+       .i2c_gate      = 0x4b,
+       .tuner_address = 0x60,
+       .tuner_config  = 0,
+       .antenna_switch= 1,
+       .request_firmware = philips_tda1004x_request_firmware
+};
+
 /* ------------------------------------------------------------------
  * special case: this card uses saa713x GPIO22 for the mode switch
  */
@@ -832,7 +850,7 @@ static int dvb_init(struct saa7134_dev *dev)
        dev->ts.nr_bufs    = 32;
        dev->ts.nr_packets = 32*4;
        dev->dvb.name = dev->name;
-       videobuf_queue_init(&dev->dvb.dvbq, &saa7134_ts_qops,
+       videobuf_queue_pci_init(&dev->dvb.dvbq, &saa7134_ts_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_ALTERNATE,
@@ -1022,6 +1040,9 @@ static int dvb_init(struct saa7134_dev *dev)
        case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
                configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config);
                break;
+       case SAA7134_BOARD_AVERMEDIA_SUPER_007:
+               configure_tda827x_fe(dev, &avermedia_super_007_config);
+               break;
        default:
                wprintk("Huh? unknown DVB card?\n");
                break;
index fc260ec8fdc2b940af785559b3cac06f73cd2258..34ca874dd7fe4e8a65a8643a682954ae1fb80e15 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -77,17 +76,14 @@ static int ts_init_encoder(struct saa7134_dev* dev)
 static int ts_open(struct inode *inode, struct file *file)
 {
        int minor = iminor(inode);
-       struct saa7134_dev *h,*dev = NULL;
-       struct list_head *list;
+       struct saa7134_dev *dev;
        int err;
 
-       list_for_each(list,&saa7134_devlist) {
-               h = list_entry(list, struct saa7134_dev, devlist);
-               if (h->empress_dev && h->empress_dev->minor == minor)
-                       dev = h;
-       }
-       if (NULL == dev)
-               return -ENODEV;
+       list_for_each_entry(dev, &saa7134_devlist, devlist)
+               if (dev->empress_dev && dev->empress_dev->minor == minor)
+                       goto found;
+       return -ENODEV;
+ found:
 
        dprintk("open minor=%d\n",minor);
        err = -EBUSY;
@@ -401,7 +397,7 @@ static int empress_init(struct saa7134_dev *dev)
        printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
               dev->name,dev->empress_dev->minor & 0x1f);
 
-       videobuf_queue_init(&dev->empress_tsq, &saa7134_ts_qops,
+       videobuf_queue_pci_init(&dev->empress_tsq, &saa7134_ts_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_ALTERNATE,
index 1cb8c709ca905bdeef19f91ff6c29d6bc0765147..cc87f5855a211101188a89377f06902d481d28b9 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
index 1b6dfd801cc1f6e9d0c3c95571b0eaf4974bf3b7..80d2644f765a9170d82a1f0c5410cd57a4cbcaee 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
index 72444f039e3d932ceb685f9d3c40408df08d3e1f..aedf04653e0e8c0617890e7a857cb23ad1a4969b 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
@@ -240,17 +239,14 @@ static int dsp_rec_stop(struct saa7134_dev *dev)
 static int dsp_open(struct inode *inode, struct file *file)
 {
        int minor = iminor(inode);
-       struct saa7134_dev *h,*dev = NULL;
-       struct list_head *list;
+       struct saa7134_dev *dev;
        int err;
 
-       list_for_each(list,&saa7134_devlist) {
-               h = list_entry(list, struct saa7134_dev, devlist);
-               if (h->dmasound.minor_dsp == minor)
-                       dev = h;
-       }
-       if (NULL == dev)
-               return -ENODEV;
+       list_for_each_entry(dev, &saa7134_devlist, devlist)
+               if (dev->dmasound.minor_dsp == minor)
+                       goto found;
+       return -ENODEV;
+ found:
 
        mutex_lock(&dev->dmasound.lock);
        err = -EBUSY;
@@ -681,19 +677,14 @@ mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level)
 static int mixer_open(struct inode *inode, struct file *file)
 {
        int minor = iminor(inode);
-       struct saa7134_dev *h,*dev = NULL;
-       struct list_head *list;
+       struct saa7134_dev *dev;
 
-       list_for_each(list,&saa7134_devlist) {
-               h = list_entry(list, struct saa7134_dev, devlist);
-               if (h->dmasound.minor_mixer == minor)
-                       dev = h;
-       }
-       if (NULL == dev)
-               return -ENODEV;
-
-       file->private_data = dev;
-       return 0;
+       list_for_each_entry(dev, &saa7134_devlist, devlist)
+               if (dev->dmasound.minor_mixer == minor) {
+                       file->private_data = dev;
+                       return 0;
+               }
+       return -ENODEV;
 }
 
 static int mixer_release(struct inode *inode, struct file *file)
@@ -1023,18 +1014,14 @@ static int saa7134_oss_init(void)
 
 static void saa7134_oss_exit(void)
 {
-       struct saa7134_dev *dev = NULL;
-       struct list_head *list;
-
-       list_for_each(list,&saa7134_devlist) {
-               dev = list_entry(list, struct saa7134_dev, devlist);
+       struct saa7134_dev *dev;
 
+       list_for_each_entry(dev, &saa7134_devlist, devlist) {
                /* Device isn't registered by OSS, probably ALSA's */
                if (!dev->dmasound.minor_dsp)
                        continue;
 
                oss_device_exit(dev);
-
        }
 
        saa7134_dmasound_init = NULL;
index 60a90a2617aea615849e0550efa7757e5296f0c5..4b63ad3e84664ec566a4b5f22c7e87690603434c 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -93,6 +92,8 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
        }
 
        if (STATE_NEEDS_INIT == buf->vb.state) {
+               struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
+
                buf->vb.width  = llength;
                buf->vb.height = lines;
                buf->vb.size   = size;
@@ -102,8 +103,8 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
                if (err)
                        goto oops;
                err = saa7134_pgtable_build(dev->pci,buf->pt,
-                                           buf->vb.dma.sglist,
-                                           buf->vb.dma.sglen,
+                                           dma->sglist,
+                                           dma->sglen,
                                            saa7134_buffer_startpage(buf));
                if (err)
                        goto oops;
@@ -176,6 +177,22 @@ static unsigned int ts_nr_packets = 64;
 module_param(ts_nr_packets, int, 0444);
 MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
 
+int saa7134_ts_init_hw(struct saa7134_dev *dev)
+{
+       /* deactivate TS softreset */
+       saa_writeb(SAA7134_TS_SERIAL1, 0x00);
+       /* TSSOP high active, TSVAL high active, TSLOCK ignored */
+       saa_writeb(SAA7134_TS_PARALLEL, 0xec);
+       saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1));
+       saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff));
+       saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff));
+       /* TSNOPIT=0, TSCOLAP=0 */
+       saa_writeb(SAA7134_TS_DMA2,
+               ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00));
+
+       return 0;
+}
+
 int saa7134_ts_init1(struct saa7134_dev *dev)
 {
        /* sanitycheck insmod options */
@@ -199,12 +216,7 @@ int saa7134_ts_init1(struct saa7134_dev *dev)
        saa7134_pgtable_alloc(dev->pci,&dev->ts.pt_ts);
 
        /* init TS hw */
-       saa_writeb(SAA7134_TS_SERIAL1, 0x00);  /* deactivate TS softreset */
-       saa_writeb(SAA7134_TS_PARALLEL, 0xec); /* TSSOP high active, TSVAL high active, TSLOCK ignored */
-       saa_writeb(SAA7134_TS_PARALLEL_SERIAL, (TS_PACKET_SIZE-1));
-       saa_writeb(SAA7134_TS_DMA0, ((dev->ts.nr_packets-1)&0xff));
-       saa_writeb(SAA7134_TS_DMA1, (((dev->ts.nr_packets-1)>>8)&0xff));
-       saa_writeb(SAA7134_TS_DMA2, ((((dev->ts.nr_packets-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */
+       saa7134_ts_init_hw(dev);
 
        return 0;
 }
index 18b4817b4aac6edb2ac79f0f6298f24cbdd0fb4f..1b9e39a5ea47650ea2a3688d173de3e755d2d8a2 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/kthread.h>
 #include <linux/slab.h>
@@ -232,7 +231,7 @@ static void mute_input_7134(struct saa7134_dev *dev)
        }
 
        if (dev->hw_mute  == mute &&
-               dev->hw_input == in) {
+               dev->hw_input == in && !dev->inresume) {
                dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
                        mute,in->name);
                return;
@@ -877,7 +876,7 @@ static int tvaudio_thread_ddep(void *data)
 /* ------------------------------------------------------------------ */
 /* common stuff + external entry points                               */
 
-static void saa7134_enable_i2s(struct saa7134_dev *dev)
+void saa7134_enable_i2s(struct saa7134_dev *dev)
 {
        int i2s_format;
 
index f38366a470fa58c4cb677f3af1074054418710c8..81a2aedeff5c4d6218fdb94baece6850edac2ddb 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 
@@ -138,6 +137,8 @@ static int buffer_prepare(struct videobuf_queue *q,
                saa7134_dma_free(q,buf);
 
        if (STATE_NEEDS_INIT == buf->vb.state) {
+               struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
+
                buf->vb.width  = llength;
                buf->vb.height = lines;
                buf->vb.size   = size;
@@ -147,8 +148,8 @@ static int buffer_prepare(struct videobuf_queue *q,
                if (err)
                        goto oops;
                err = saa7134_pgtable_build(dev->pci,buf->pt,
-                                           buf->vb.dma.sglist,
-                                           buf->vb.dma.sglen,
+                                           dma->sglist,
+                                           dma->sglen,
                                            saa7134_buffer_startpage(buf));
                if (err)
                        goto oops;
index 9985ded209505103acfef03352cdd13493d9f1e5..471b92793c124aca8a94626390ef079175a3c53c 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sort.h>
@@ -41,7 +40,7 @@
 
 static unsigned int video_debug   = 0;
 static unsigned int gbuffers      = 8;
-static unsigned int noninterlaced = 1;
+static unsigned int noninterlaced = 0;
 static unsigned int gbufsize      = 720*576*4;
 static unsigned int gbufsize_max  = 720*576*4;
 static char secam[] = "--";
@@ -541,22 +540,12 @@ void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
 
 /* ------------------------------------------------------------------ */
 
-static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
+void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
 {
-       int luma_control,sync_control,mux;
 
        dprintk("set tv norm = %s\n",norm->name);
        dev->tvnorm = norm;
 
-       mux = card_in(dev,dev->ctl_input).vmux;
-       luma_control = norm->luma_control;
-       sync_control = norm->sync_control;
-
-       if (mux > 5)
-               luma_control |= 0x80; /* svideo */
-       if (noninterlaced || dev->nosignal)
-               sync_control |= 0x20;
-
        /* setup cropping */
        dev->crop_bounds.left    = norm->h_start;
        dev->crop_defrect.left   = norm->h_start;
@@ -571,6 +560,40 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
 
        dev->crop_current = dev->crop_defrect;
 
+       saa7134_set_decoder(dev);
+
+       if (card_in(dev, dev->ctl_input).tv) {
+               if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
+                               && ((card(dev).tuner_config == 1)
+                               ||  (card(dev).tuner_config == 2)))
+                       saa7134_set_gpio(dev, 22, 5);
+               saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &norm->id);
+       }
+}
+
+static void video_mux(struct saa7134_dev *dev, int input)
+{
+       dprintk("video input = %d [%s]\n", input, card_in(dev, input).name);
+       dev->ctl_input = input;
+       set_tvnorm(dev, dev->tvnorm);
+       saa7134_tvaudio_setinput(dev, &card_in(dev, input));
+}
+
+void saa7134_set_decoder(struct saa7134_dev *dev)
+{
+       int luma_control, sync_control, mux;
+
+       struct saa7134_tvnorm *norm = dev->tvnorm;
+       mux = card_in(dev, dev->ctl_input).vmux;
+
+       luma_control = norm->luma_control;
+       sync_control = norm->sync_control;
+
+       if (mux > 5)
+               luma_control |= 0x80; /* svideo */
+       if (noninterlaced || dev->nosignal)
+               sync_control |= 0x20;
+
        /* setup video decoder */
        saa_writeb(SAA7134_INCR_DELAY,            0x08);
        saa_writeb(SAA7134_ANALOG_IN_CTRL1,       0xc0 | mux);
@@ -585,9 +608,13 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
        saa_writeb(SAA7134_SYNC_CTRL,             sync_control);
        saa_writeb(SAA7134_LUMA_CTRL,             luma_control);
        saa_writeb(SAA7134_DEC_LUMA_BRIGHT,       dev->ctl_bright);
-       saa_writeb(SAA7134_DEC_LUMA_CONTRAST,     dev->ctl_contrast);
 
-       saa_writeb(SAA7134_DEC_CHROMA_SATURATION, dev->ctl_saturation);
+       saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
+               dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
+
+       saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
+               dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
+
        saa_writeb(SAA7134_DEC_CHROMA_HUE,        dev->ctl_hue);
        saa_writeb(SAA7134_CHROMA_CTRL1,          norm->chroma_ctrl1);
        saa_writeb(SAA7134_CHROMA_GAIN,           norm->chroma_gain);
@@ -601,23 +628,6 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
        saa_writeb(SAA7134_MISC_VGATE_MSB,        norm->vgate_misc);
        saa_writeb(SAA7134_RAW_DATA_GAIN,         0x40);
        saa_writeb(SAA7134_RAW_DATA_OFFSET,       0x80);
-
-       /* only tell the tuner if this is a tv input */
-       if (card_in(dev,dev->ctl_input).tv) {
-               if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
-                               && ((card(dev).tuner_config == 1)
-                               ||  (card(dev).tuner_config == 2)))
-                       saa7134_set_gpio(dev, 22, 5);
-               saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id);
-       }
-}
-
-static void video_mux(struct saa7134_dev *dev, int input)
-{
-       dprintk("video input = %d [%s]\n",input,card_in(dev,input).name);
-       dev->ctl_input = input;
-       set_tvnorm(dev,dev->tvnorm);
-       saa7134_tvaudio_setinput(dev,&card_in(dev,input));
 }
 
 static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
@@ -1038,6 +1048,8 @@ static int buffer_prepare(struct videobuf_queue *q,
        }
 
        if (STATE_NEEDS_INIT == buf->vb.state) {
+               struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
+
                buf->vb.width  = fh->width;
                buf->vb.height = fh->height;
                buf->vb.size   = size;
@@ -1049,8 +1061,8 @@ static int buffer_prepare(struct videobuf_queue *q,
                if (err)
                        goto oops;
                err = saa7134_pgtable_build(dev->pci,buf->pt,
-                                           buf->vb.dma.sglist,
-                                           buf->vb.dma.sglen,
+                                           dma->sglist,
+                                           dma->sglen,
                                            saa7134_buffer_startpage(buf));
                if (err)
                        goto oops;
@@ -1273,26 +1285,24 @@ static int saa7134_resource(struct saa7134_fh *fh)
 static int video_open(struct inode *inode, struct file *file)
 {
        int minor = iminor(inode);
-       struct saa7134_dev *h,*dev = NULL;
+       struct saa7134_dev *dev;
        struct saa7134_fh *fh;
-       struct list_head *list;
        enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        int radio = 0;
-       list_for_each(list,&saa7134_devlist) {
-               h = list_entry(list, struct saa7134_dev, devlist);
-               if (h->video_dev && (h->video_dev->minor == minor))
-                       dev = h;
-               if (h->radio_dev && (h->radio_dev->minor == minor)) {
+       list_for_each_entry(dev, &saa7134_devlist, devlist) {
+               if (dev->video_dev && (dev->video_dev->minor == minor))
+                       goto found;
+               if (dev->radio_dev && (dev->radio_dev->minor == minor)) {
                        radio = 1;
-                       dev = h;
+                       goto found;
                }
-               if (h->vbi_dev && (h->vbi_dev->minor == minor)) {
+               if (dev->vbi_dev && (dev->vbi_dev->minor == minor)) {
                        type = V4L2_BUF_TYPE_VBI_CAPTURE;
-                       dev = h;
+                       goto found;
                }
        }
-       if (NULL == dev)
-               return -ENODEV;
+       return -ENODEV;
+ found:
 
        dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
                v4l2_type_names[type]);
@@ -1310,13 +1320,13 @@ static int video_open(struct inode *inode, struct file *file)
        fh->height   = 576;
        v4l2_prio_open(&dev->prio,&fh->prio);
 
-       videobuf_queue_init(&fh->cap, &video_qops,
+       videobuf_queue_pci_init(&fh->cap, &video_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VIDEO_CAPTURE,
                            V4L2_FIELD_INTERLACED,
                            sizeof(struct saa7134_buf),
                            fh);
-       videobuf_queue_init(&fh->vbi, &saa7134_vbi_qops,
+       videobuf_queue_pci_init(&fh->vbi, &saa7134_vbi_qops,
                            dev->pci, &dev->slock,
                            V4L2_BUF_TYPE_VBI_CAPTURE,
                            V4L2_FIELD_SEQ_TB,
@@ -1833,7 +1843,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
                if (res_check(fh, RESOURCE_OVERLAY)) {
                        spin_lock_irqsave(&dev->slock,flags);
                        stop_preview(dev,fh);
+                       spin_unlock_irqrestore(&dev->slock, flags);
+
                        set_tvnorm(dev,&tvnorms[i]);
+
+                       spin_lock_irqsave(&dev->slock, flags);
                        start_preview(dev,fh);
                        spin_unlock_irqrestore(&dev->slock,flags);
                } else
@@ -2138,29 +2152,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
        }
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
        case VIDIOCGMBUF:
-       {
-               struct video_mbuf *mbuf = arg;
-               struct videobuf_queue *q;
-               struct v4l2_requestbuffers req;
-               unsigned int i;
-
-               q = saa7134_queue(fh);
-               memset(&req,0,sizeof(req));
-               req.type   = q->type;
-               req.count  = gbuffers;
-               req.memory = V4L2_MEMORY_MMAP;
-               err = videobuf_reqbufs(q,&req);
-               if (err < 0)
-                       return err;
-               memset(mbuf,0,sizeof(*mbuf));
-               mbuf->frames = req.count;
-               mbuf->size   = 0;
-               for (i = 0; i < mbuf->frames; i++) {
-                       mbuf->offsets[i]  = q->bufs[i]->boff;
-                       mbuf->size       += q->bufs[i]->bsize;
-               }
-               return 0;
-       }
+               return videobuf_cgmbuf(saa7134_queue(fh), arg, gbuffers);
 #endif
        case VIDIOC_REQBUFS:
                return videobuf_reqbufs(saa7134_queue(fh),arg);
@@ -2412,34 +2404,40 @@ int saa7134_video_init1(struct saa7134_dev *dev)
        dev->video_q.timeout.data     = (unsigned long)(&dev->video_q);
        dev->video_q.dev              = dev;
 
-       if (saa7134_boards[dev->board].video_out) {
-               /* enable video output */
-               int vo = saa7134_boards[dev->board].video_out;
-               int video_reg;
-               unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
-               video_reg = video_out[vo][1];
-               if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED)
-                       video_reg &= ~VP_T_CODE_P_INVERTED;
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg);
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
-               video_reg = video_out[vo][5];
-               if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
-                       video_reg &= ~VP_CLK_CTRL2_DELAYED;
-               if (vid_port_opts & SET_CLOCK_INVERTED)
-                       video_reg |= VP_CLK_CTRL1_INVERTED;
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg);
-               video_reg = video_out[vo][6];
-               if (vid_port_opts & SET_VSYNC_OFF) {
-                       video_reg &= ~VP_VS_TYPE_MASK;
-                       video_reg |= VP_VS_TYPE_OFF;
-               }
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg);
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
-               saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
-       }
+       if (saa7134_boards[dev->board].video_out)
+               saa7134_videoport_init(dev);
+
+       return 0;
+}
+
+int saa7134_videoport_init(struct saa7134_dev *dev)
+{
+       /* enable video output */
+       int vo = saa7134_boards[dev->board].video_out;
+       int video_reg;
+       unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
+       saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
+       video_reg = video_out[vo][1];
+       if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED)
+               video_reg &= ~VP_T_CODE_P_INVERTED;
+       saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg);
+       saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
+       saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
+       saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
+       video_reg = video_out[vo][5];
+       if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
+               video_reg &= ~VP_CLK_CTRL2_DELAYED;
+       if (vid_port_opts & SET_CLOCK_INVERTED)
+               video_reg |= VP_CLK_CTRL1_INVERTED;
+       saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg);
+       video_reg = video_out[vo][6];
+       if (vid_port_opts & SET_VSYNC_OFF) {
+               video_reg &= ~VP_VS_TYPE_MASK;
+               video_reg |= VP_VS_TYPE_OFF;
+       }
+       saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg);
+       saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
+       saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
 
        return 0;
 }
@@ -2454,7 +2452,7 @@ int saa7134_video_init2(struct saa7134_dev *dev)
        return 0;
 }
 
-void saa7134_irq_video_intl(struct saa7134_dev *dev)
+void saa7134_irq_video_signalchange(struct saa7134_dev *dev)
 {
        static const char *st[] = {
                "(no signal)", "NTSC", "PAL", "SECAM" };
@@ -2466,24 +2464,28 @@ void saa7134_irq_video_intl(struct saa7134_dev *dev)
                (st1 & 0x40) ? "not locked" : "locked",
                (st2 & 0x40) ? "no"         : "yes",
                st[st1 & 0x03]);
-       dev->nosignal = (st1 & 0x40) || (st2 & 0x40);
+       dev->nosignal = (st1 & 0x40) || (st2 & 0x40)  || !(st2 & 0x1);
 
        if (dev->nosignal) {
                /* no video signal -> mute audio */
                if (dev->ctl_automute)
                        dev->automute = 1;
                saa7134_tvaudio_setmute(dev);
-               saa_setb(SAA7134_SYNC_CTRL, 0x20);
        } else {
                /* wake up tvaudio audio carrier scan thread */
                saa7134_tvaudio_do_scan(dev);
-               if (!noninterlaced)
-                       saa_clearb(SAA7134_SYNC_CTRL, 0x20);
        }
+
+       if ((st2 & 0x80) && !noninterlaced && !dev->nosignal)
+               saa_clearb(SAA7134_SYNC_CTRL, 0x20);
+       else
+               saa_setb(SAA7134_SYNC_CTRL, 0x20);
+
        if (dev->mops && dev->mops->signal_change)
                dev->mops->signal_change(dev);
 }
 
+
 void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
 {
        enum v4l2_field field;
index 346255468dad2f478795f41ebfef86002f80e658..28ec6804bd5dca50b472cd40e07973d05c66beab 100644 (file)
 #include <media/tuner.h>
 #include <media/ir-common.h>
 #include <media/ir-kbd-i2c.h>
-#include <media/video-buf.h>
+#include <media/videobuf-dma-sg.h>
 #include <sound/driver.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
-#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
-#include <media/video-buf-dvb.h>
+#if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE)
+#include <media/videobuf-dvb.h>
 #endif
 
 #define UNSET (-1U)
@@ -239,6 +239,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_KWORLD_DVBT_210 114
 #define SAA7134_BOARD_SABRENT_TV_PCB05     115
 #define SAA7134_BOARD_10MOONSTVMASTER3     116
+#define SAA7134_BOARD_AVERMEDIA_SUPER_007  117
 
 #define SAA7134_MAXBOARDS 8
 #define SAA7134_INPUT_MAX 8
@@ -523,6 +524,7 @@ struct saa7134_dev {
        unsigned int               hw_mute;
        int                        last_carrier;
        int                        nosignal;
+       unsigned int               inresume;
 
        /* SAA7134_MPEG_* */
        struct saa7134_ts          ts;
@@ -536,7 +538,7 @@ struct saa7134_dev {
        struct work_struct         empress_workqueue;
        int                        empress_started;
 
-#if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE)
+#if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE)
        /* SAA7134_MPEG_DVB only */
        struct videobuf_dvb        dvb;
        int (*original_demod_sleep)(struct dvb_frontend* fe);
@@ -593,6 +595,9 @@ void saa7134_buffer_next(struct saa7134_dev *dev, struct saa7134_dmaqueue *q);
 void saa7134_buffer_timeout(unsigned long data);
 void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf);
 
+int saa7134_buffer_requeue(struct saa7134_dev *dev,
+                        struct saa7134_dmaqueue *q);
+
 int saa7134_set_dmabits(struct saa7134_dev *dev);
 
 extern int (*saa7134_dmasound_init)(struct saa7134_dev *dev);
@@ -625,12 +630,16 @@ void saa7134_i2c_call_clients(struct saa7134_dev *dev,
 extern struct video_device saa7134_video_template;
 extern struct video_device saa7134_radio_template;
 
+void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm);
+int saa7134_videoport_init(struct saa7134_dev *dev);
+void saa7134_set_decoder(struct saa7134_dev *dev);
+
 int saa7134_common_ioctl(struct saa7134_dev *dev,
                         unsigned int cmd, void *arg);
 
 int saa7134_video_init1(struct saa7134_dev *dev);
 int saa7134_video_init2(struct saa7134_dev *dev);
-void saa7134_irq_video_intl(struct saa7134_dev *dev);
+void saa7134_irq_video_signalchange(struct saa7134_dev *dev);
 void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status);
 
 
@@ -648,6 +657,8 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status);
 int saa7134_ts_register(struct saa7134_mpeg_ops *ops);
 void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops);
 
+int saa7134_ts_init_hw(struct saa7134_dev *dev);
+
 /* ----------------------------------------------------------- */
 /* saa7134-vbi.c                                               */
 
@@ -676,6 +687,8 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev);
 
 int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value);
 
+void saa7134_enable_i2s(struct saa7134_dev *dev);
+
 /* ----------------------------------------------------------- */
 /* saa7134-oss.c                                               */
 
index 36d8a455e0ecf224ab41d49000fcaa968602726f..6991e06f7651a1601c33688f10bc4e1f16e37f5d 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/param.h>
-#include <linux/moduleparam.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/device.h>
@@ -1030,7 +1029,8 @@ static u16 sn9c102_strtou16(const char* buff, size_t len, ssize_t* count)
    NOTE 2: buffers are PAGE_SIZE long
 */
 
-static ssize_t sn9c102_show_reg(struct class_device* cd, char* buf)
+static ssize_t sn9c102_show_reg(struct device* cd,
+                               struct device_attribute *attr, char* buf)
 {
        struct sn9c102_device* cam;
        ssize_t count;
@@ -1054,7 +1054,8 @@ static ssize_t sn9c102_show_reg(struct class_device* cd, char* buf)
 
 
 static ssize_t
-sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len)
+sn9c102_store_reg(struct device* cd, struct device_attribute *attr,
+                 const char* buf, size_t len)
 {
        struct sn9c102_device* cam;
        u16 index;
@@ -1087,7 +1088,8 @@ sn9c102_store_reg(struct class_device* cd, const char* buf, size_t len)
 }
 
 
-static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
+static ssize_t sn9c102_show_val(struct device* cd,
+                               struct device_attribute *attr, char* buf)
 {
        struct sn9c102_device* cam;
        ssize_t count;
@@ -1119,7 +1121,8 @@ static ssize_t sn9c102_show_val(struct class_device* cd, char* buf)
 
 
 static ssize_t
-sn9c102_store_val(struct class_device* cd, const char* buf, size_t len)
+sn9c102_store_val(struct device* cd, struct device_attribute *attr,
+                 const char* buf, size_t len)
 {
        struct sn9c102_device* cam;
        u16 value;
@@ -1158,7 +1161,8 @@ sn9c102_store_val(struct class_device* cd, const char* buf, size_t len)
 }
 
 
-static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf)
+static ssize_t sn9c102_show_i2c_reg(struct device* cd,
+                                   struct device_attribute *attr, char* buf)
 {
        struct sn9c102_device* cam;
        ssize_t count;
@@ -1184,7 +1188,8 @@ static ssize_t sn9c102_show_i2c_reg(struct class_device* cd, char* buf)
 
 
 static ssize_t
-sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
+sn9c102_store_i2c_reg(struct device* cd, struct device_attribute *attr,
+                     const char* buf, size_t len)
 {
        struct sn9c102_device* cam;
        u16 index;
@@ -1217,7 +1222,8 @@ sn9c102_store_i2c_reg(struct class_device* cd, const char* buf, size_t len)
 }
 
 
-static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
+static ssize_t sn9c102_show_i2c_val(struct device* cd,
+                                   struct device_attribute *attr, char* buf)
 {
        struct sn9c102_device* cam;
        ssize_t count;
@@ -1254,7 +1260,8 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
 
 
 static ssize_t
-sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
+sn9c102_store_i2c_val(struct device* cd, struct device_attribute *attr,
+                     const char* buf, size_t len)
 {
        struct sn9c102_device* cam;
        u16 value;
@@ -1299,7 +1306,8 @@ sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
 
 
 static ssize_t
-sn9c102_store_green(struct class_device* cd, const char* buf, size_t len)
+sn9c102_store_green(struct device* cd, struct device_attribute *attr,
+                   const char* buf, size_t len)
 {
        struct sn9c102_device* cam;
        enum sn9c102_bridge bridge;
@@ -1330,16 +1338,16 @@ sn9c102_store_green(struct class_device* cd, const char* buf, size_t len)
        case BRIDGE_SN9C102:
                if (value > 0x0f)
                        return -EINVAL;
-               if ((res = sn9c102_store_reg(cd, "0x11", 4)) >= 0)
-                       res = sn9c102_store_val(cd, buf, len);
+               if ((res = sn9c102_store_reg(cd, attr, "0x11", 4)) >= 0)
+                       res = sn9c102_store_val(cd, attr, buf, len);
                break;
        case BRIDGE_SN9C103:
        case BRIDGE_SN9C105:
        case BRIDGE_SN9C120:
                if (value > 0x7f)
                        return -EINVAL;
-               if ((res = sn9c102_store_reg(cd, "0x07", 4)) >= 0)
-                       res = sn9c102_store_val(cd, buf, len);
+               if ((res = sn9c102_store_reg(cd, attr, "0x07", 4)) >= 0)
+                       res = sn9c102_store_val(cd, attr, buf, len);
                break;
        }
 
@@ -1348,7 +1356,8 @@ sn9c102_store_green(struct class_device* cd, const char* buf, size_t len)
 
 
 static ssize_t
-sn9c102_store_blue(struct class_device* cd, const char* buf, size_t len)
+sn9c102_store_blue(struct device* cd, struct device_attribute *attr,
+                  const char* buf, size_t len)
 {
        ssize_t res = 0;
        u16 value;
@@ -1358,15 +1367,16 @@ sn9c102_store_blue(struct class_device* cd, const char* buf, size_t len)
        if (!count || value > 0x7f)
                return -EINVAL;
 
-       if ((res = sn9c102_store_reg(cd, "0x06", 4)) >= 0)
-               res = sn9c102_store_val(cd, buf, len);
+       if ((res = sn9c102_store_reg(cd, attr, "0x06", 4)) >= 0)
+               res = sn9c102_store_val(cd, attr, buf, len);
 
        return res;
 }
 
 
 static ssize_t
-sn9c102_store_red(struct class_device* cd, const char* buf, size_t len)
+sn9c102_store_red(struct device* cd, struct device_attribute *attr,
+                 const char* buf, size_t len)
 {
        ssize_t res = 0;
        u16 value;
@@ -1376,14 +1386,16 @@ sn9c102_store_red(struct class_device* cd, const char* buf, size_t len)
        if (!count || value > 0x7f)
                return -EINVAL;
 
-       if ((res = sn9c102_store_reg(cd, "0x05", 4)) >= 0)
-               res = sn9c102_store_val(cd, buf, len);
+       if ((res = sn9c102_store_reg(cd, attr, "0x05", 4)) >= 0)
+               res = sn9c102_store_val(cd, attr, buf, len);
 
        return res;
 }
 
 
-static ssize_t sn9c102_show_frame_header(struct class_device* cd, char* buf)
+static ssize_t sn9c102_show_frame_header(struct device* cd,
+                                        struct device_attribute *attr,
+                                        char* buf)
 {
        struct sn9c102_device* cam;
        ssize_t count;
@@ -1402,72 +1414,63 @@ static ssize_t sn9c102_show_frame_header(struct class_device* cd, char* buf)
 }
 
 
-static CLASS_DEVICE_ATTR(reg, S_IRUGO | S_IWUSR,
-                        sn9c102_show_reg, sn9c102_store_reg);
-static CLASS_DEVICE_ATTR(val, S_IRUGO | S_IWUSR,
-                        sn9c102_show_val, sn9c102_store_val);
-static CLASS_DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
-                        sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
-static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
-                        sn9c102_show_i2c_val, sn9c102_store_i2c_val);
-static CLASS_DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green);
-static CLASS_DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue);
-static CLASS_DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red);
-static CLASS_DEVICE_ATTR(frame_header, S_IRUGO,
-                        sn9c102_show_frame_header, NULL);
+static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, sn9c102_show_reg, sn9c102_store_reg);
+static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, sn9c102_show_val, sn9c102_store_val);
+static DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
+                  sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
+static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
+                  sn9c102_show_i2c_val, sn9c102_store_i2c_val);
+static DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green);
+static DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue);
+static DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red);
+static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL);
 
 
 static int sn9c102_create_sysfs(struct sn9c102_device* cam)
 {
-       struct class_device *classdev = &(cam->v4ldev->class_dev);
+       struct device *classdev = &(cam->v4ldev->class_dev);
        int err = 0;
 
-       if ((err = class_device_create_file(classdev, &class_device_attr_reg)))
+       if ((err = device_create_file(classdev, &dev_attr_reg)))
                goto err_out;
-       if ((err = class_device_create_file(classdev, &class_device_attr_val)))
+       if ((err = device_create_file(classdev, &dev_attr_val)))
                goto err_reg;
-       if ((err = class_device_create_file(classdev,
-                                           &class_device_attr_frame_header)))
+       if ((err = device_create_file(classdev, &dev_attr_frame_header)))
                goto err_val;
 
        if (cam->sensor.sysfs_ops) {
-               if ((err = class_device_create_file(classdev,
-                                                 &class_device_attr_i2c_reg)))
+               if ((err = device_create_file(classdev, &dev_attr_i2c_reg)))
                        goto err_frame_header;
-               if ((err = class_device_create_file(classdev,
-                                                 &class_device_attr_i2c_val)))
+               if ((err = device_create_file(classdev, &dev_attr_i2c_val)))
                        goto err_i2c_reg;
        }
 
        if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) {
-               if ((err = class_device_create_file(classdev,
-                                                   &class_device_attr_green)))
+               if ((err = device_create_file(classdev, &dev_attr_green)))
                        goto err_i2c_val;
        } else {
-               if ((err = class_device_create_file(classdev,
-                                                   &class_device_attr_blue)))
+               if ((err = device_create_file(classdev, &dev_attr_blue)))
                        goto err_i2c_val;
-               if ((err = class_device_create_file(classdev,
-                                                   &class_device_attr_red)))
+               if ((err = device_create_file(classdev, &dev_attr_red)))
                        goto err_blue;
        }
 
        return 0;
 
 err_blue:
-       class_device_remove_file(classdev, &class_device_attr_blue);
+       device_remove_file(classdev, &dev_attr_blue);
 err_i2c_val:
        if (cam->sensor.sysfs_ops)
-               class_device_remove_file(classdev, &class_device_attr_i2c_val);
+               device_remove_file(classdev, &dev_attr_i2c_val);
 err_i2c_reg:
        if (cam->sensor.sysfs_ops)
-               class_device_remove_file(classdev, &class_device_attr_i2c_reg);
+               device_remove_file(classdev, &dev_attr_i2c_reg);
 err_frame_header:
-       class_device_remove_file(classdev, &class_device_attr_frame_header);
+       device_remove_file(classdev, &dev_attr_frame_header);
 err_val:
-       class_device_remove_file(classdev, &class_device_attr_val);
+       device_remove_file(classdev, &dev_attr_val);
 err_reg:
-       class_device_remove_file(classdev, &class_device_attr_reg);
+       device_remove_file(classdev, &dev_attr_reg);
 err_out:
        return err;
 }
index 4dc5bc714b953044467a8b7020a65884767ed51b..9e009a7ab863d020a9fe01e42c4174027c5c8af3 100644 (file)
@@ -499,13 +499,14 @@ exit:
  *  sysfs
  ***************************************************************************/
 #define stv680_file(name, variable, field)                             \
-static ssize_t show_##name(struct class_device *class_dev, char *buf)  \
+static ssize_t show_##name(struct device *class_dev,                   \
+                          struct device_attribute *attr, char *buf)    \
 {                                                                      \
        struct video_device *vdev = to_video_device(class_dev);         \
        struct usb_stv *stv = video_get_drvdata(vdev);                  \
        return sprintf(buf, field, stv->variable);                      \
 }                                                                      \
-static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
+static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
 
 stv680_file(model, camera_name, "%s\n");
 stv680_file(in_use, user, "%d\n");
@@ -520,53 +521,53 @@ static int stv680_create_sysfs_files(struct video_device *vdev)
 {
        int rc;
 
-       rc = video_device_create_file(vdev, &class_device_attr_model);
+       rc = video_device_create_file(vdev, &dev_attr_model);
        if (rc) goto err;
-       rc = video_device_create_file(vdev, &class_device_attr_in_use);
+       rc = video_device_create_file(vdev, &dev_attr_in_use);
        if (rc) goto err_model;
-       rc = video_device_create_file(vdev, &class_device_attr_streaming);
+       rc = video_device_create_file(vdev, &dev_attr_streaming);
        if (rc) goto err_inuse;
-       rc = video_device_create_file(vdev, &class_device_attr_palette);
+       rc = video_device_create_file(vdev, &dev_attr_palette);
        if (rc) goto err_stream;
-       rc = video_device_create_file(vdev, &class_device_attr_frames_total);
+       rc = video_device_create_file(vdev, &dev_attr_frames_total);
        if (rc) goto err_pal;
-       rc = video_device_create_file(vdev, &class_device_attr_frames_read);
+       rc = video_device_create_file(vdev, &dev_attr_frames_read);
        if (rc) goto err_framtot;
-       rc = video_device_create_file(vdev, &class_device_attr_packets_dropped);
+       rc = video_device_create_file(vdev, &dev_attr_packets_dropped);
        if (rc) goto err_framread;
-       rc = video_device_create_file(vdev, &class_device_attr_decoding_errors);
+       rc = video_device_create_file(vdev, &dev_attr_decoding_errors);
        if (rc) goto err_dropped;
 
        return 0;
 
 err_dropped:
-       video_device_remove_file(vdev, &class_device_attr_packets_dropped);
+       video_device_remove_file(vdev, &dev_attr_packets_dropped);
 err_framread:
-       video_device_remove_file(vdev, &class_device_attr_frames_read);
+       video_device_remove_file(vdev, &dev_attr_frames_read);
 err_framtot:
-       video_device_remove_file(vdev, &class_device_attr_frames_total);
+       video_device_remove_file(vdev, &dev_attr_frames_total);
 err_pal:
-       video_device_remove_file(vdev, &class_device_attr_palette);
+       video_device_remove_file(vdev, &dev_attr_palette);
 err_stream:
-       video_device_remove_file(vdev, &class_device_attr_streaming);
+       video_device_remove_file(vdev, &dev_attr_streaming);
 err_inuse:
-       video_device_remove_file(vdev, &class_device_attr_in_use);
+       video_device_remove_file(vdev, &dev_attr_in_use);
 err_model:
-       video_device_remove_file(vdev, &class_device_attr_model);
+       video_device_remove_file(vdev, &dev_attr_model);
 err:
        return rc;
 }
 
 static void stv680_remove_sysfs_files(struct video_device *vdev)
 {
-       video_device_remove_file(vdev, &class_device_attr_model);
-       video_device_remove_file(vdev, &class_device_attr_in_use);
-       video_device_remove_file(vdev, &class_device_attr_streaming);
-       video_device_remove_file(vdev, &class_device_attr_palette);
-       video_device_remove_file(vdev, &class_device_attr_frames_total);
-       video_device_remove_file(vdev, &class_device_attr_frames_read);
-       video_device_remove_file(vdev, &class_device_attr_packets_dropped);
-       video_device_remove_file(vdev, &class_device_attr_decoding_errors);
+       video_device_remove_file(vdev, &dev_attr_model);
+       video_device_remove_file(vdev, &dev_attr_in_use);
+       video_device_remove_file(vdev, &dev_attr_streaming);
+       video_device_remove_file(vdev, &dev_attr_palette);
+       video_device_remove_file(vdev, &dev_attr_frames_total);
+       video_device_remove_file(vdev, &dev_attr_frames_read);
+       video_device_remove_file(vdev, &dev_attr_packets_dropped);
+       video_device_remove_file(vdev, &dev_attr_decoding_errors);
 }
 
 /********************************************************************
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
new file mode 100644 (file)
index 0000000..41cd6a0
--- /dev/null
@@ -0,0 +1,928 @@
+/*
+ * drivers/media/video/tcm825x.c
+ *
+ * TCM825X camera sensor driver.
+ *
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * Based on code from David Cohen <david.cohen@indt.org.br>
+ *
+ * This driver was based on ov9640 sensor driver from MontaVista
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/i2c.h>
+#include <media/v4l2-int-device.h>
+
+#include "tcm825x.h"
+
+/*
+ * The sensor has two fps modes: the lower one just gives half the fps
+ * at the same xclk than the high one.
+ */
+#define MAX_FPS 30
+#define MIN_FPS 8
+#define MAX_HALF_FPS (MAX_FPS / 2)
+#define HIGH_FPS_MODE_LOWER_LIMIT 14
+#define DEFAULT_FPS MAX_HALF_FPS
+
+struct tcm825x_sensor {
+       const struct tcm825x_platform_data *platform_data;
+       struct v4l2_int_device *v4l2_int_device;
+       struct i2c_client *i2c_client;
+       struct v4l2_pix_format pix;
+       struct v4l2_fract timeperframe;
+};
+
+/* list of image formats supported by TCM825X sensor */
+const static struct v4l2_fmtdesc tcm825x_formats[] = {
+       {
+               .description = "YUYV (YUV 4:2:2), packed",
+               .pixelformat = V4L2_PIX_FMT_UYVY,
+       }, {
+               /* Note:  V4L2 defines RGB565 as:
+                *
+                *      Byte 0                    Byte 1
+                *      g2 g1 g0 r4 r3 r2 r1 r0   b4 b3 b2 b1 b0 g5 g4 g3
+                *
+                * We interpret RGB565 as:
+                *
+                *      Byte 0                    Byte 1
+                *      g2 g1 g0 b4 b3 b2 b1 b0   r4 r3 r2 r1 r0 g5 g4 g3
+                */
+               .description = "RGB565, le",
+               .pixelformat = V4L2_PIX_FMT_RGB565,
+       },
+};
+
+#define TCM825X_NUM_CAPTURE_FORMATS    ARRAY_SIZE(tcm825x_formats)
+
+/*
+ * TCM825X register configuration for all combinations of pixel format and
+ * image size
+ */
+const static struct tcm825x_reg subqcif        =       { 0x20, TCM825X_PICSIZ };
+const static struct tcm825x_reg qcif   =       { 0x18, TCM825X_PICSIZ };
+const static struct tcm825x_reg cif    =       { 0x14, TCM825X_PICSIZ };
+const static struct tcm825x_reg qqvga  =       { 0x0c, TCM825X_PICSIZ };
+const static struct tcm825x_reg qvga   =       { 0x04, TCM825X_PICSIZ };
+const static struct tcm825x_reg vga    =       { 0x00, TCM825X_PICSIZ };
+
+const static struct tcm825x_reg yuv422 =       { 0x00, TCM825X_PICFMT };
+const static struct tcm825x_reg rgb565 =       { 0x02, TCM825X_PICFMT };
+
+/* Our own specific controls */
+#define V4L2_CID_ALC                           V4L2_CID_PRIVATE_BASE
+#define V4L2_CID_H_EDGE_EN                     V4L2_CID_PRIVATE_BASE + 1
+#define V4L2_CID_V_EDGE_EN                     V4L2_CID_PRIVATE_BASE + 2
+#define V4L2_CID_LENS                          V4L2_CID_PRIVATE_BASE + 3
+#define V4L2_CID_MAX_EXPOSURE_TIME             V4L2_CID_PRIVATE_BASE + 4
+#define V4L2_CID_LAST_PRIV                     V4L2_CID_MAX_EXPOSURE_TIME
+
+/*  Video controls  */
+static struct vcontrol {
+       struct v4l2_queryctrl qc;
+       u16 reg;
+       u16 start_bit;
+} video_control[] = {
+       {
+               {
+                       .id = V4L2_CID_GAIN,
+                       .type = V4L2_CTRL_TYPE_INTEGER,
+                       .name = "Gain",
+                       .minimum = 0,
+                       .maximum = 63,
+                       .step = 1,
+               },
+               .reg = TCM825X_AG,
+               .start_bit = 0,
+       },
+       {
+               {
+                       .id = V4L2_CID_RED_BALANCE,
+                       .type = V4L2_CTRL_TYPE_INTEGER,
+                       .name = "Red Balance",
+                       .minimum = 0,
+                       .maximum = 255,
+                       .step = 1,
+               },
+               .reg = TCM825X_MRG,
+               .start_bit = 0,
+       },
+       {
+               {
+                       .id = V4L2_CID_BLUE_BALANCE,
+                       .type = V4L2_CTRL_TYPE_INTEGER,
+                       .name = "Blue Balance",
+                       .minimum = 0,
+                       .maximum = 255,
+                       .step = 1,
+               },
+               .reg = TCM825X_MBG,
+               .start_bit = 0,
+       },
+       {
+               {
+                       .id = V4L2_CID_AUTO_WHITE_BALANCE,
+                       .type = V4L2_CTRL_TYPE_BOOLEAN,
+                       .name = "Auto White Balance",
+                       .minimum = 0,
+                       .maximum = 1,
+                       .step = 0,
+               },
+               .reg = TCM825X_AWBSW,
+               .start_bit = 7,
+       },
+       {
+               {
+                       .id = V4L2_CID_EXPOSURE,
+                       .type = V4L2_CTRL_TYPE_INTEGER,
+                       .name = "Exposure Time",
+                       .minimum = 0,
+                       .maximum = 0x1fff,
+                       .step = 1,
+               },
+               .reg = TCM825X_ESRSPD_U,
+               .start_bit = 0,
+       },
+       {
+               {
+                       .id = V4L2_CID_HFLIP,
+                       .type = V4L2_CTRL_TYPE_BOOLEAN,
+                       .name = "Mirror Image",
+                       .minimum = 0,
+                       .maximum = 1,
+                       .step = 0,
+               },
+               .reg = TCM825X_H_INV,
+               .start_bit = 6,
+       },
+       {
+               {
+                       .id = V4L2_CID_VFLIP,
+                       .type = V4L2_CTRL_TYPE_BOOLEAN,
+                       .name = "Vertical Flip",
+                       .minimum = 0,
+                       .maximum = 1,
+                       .step = 0,
+               },
+               .reg = TCM825X_V_INV,
+               .start_bit = 7,
+       },
+       /* Private controls */
+       {
+               {
+                       .id = V4L2_CID_ALC,
+                       .type = V4L2_CTRL_TYPE_BOOLEAN,
+                       .name = "Auto Luminance Control",
+                       .minimum = 0,
+                       .maximum = 1,
+                       .step = 0,
+               },
+               .reg = TCM825X_ALCSW,
+               .start_bit = 7,
+       },
+       {
+               {
+                       .id = V4L2_CID_H_EDGE_EN,
+                       .type = V4L2_CTRL_TYPE_INTEGER,
+                       .name = "Horizontal Edge Enhancement",
+                       .minimum = 0,
+                       .maximum = 0xff,
+                       .step = 1,
+               },
+               .reg = TCM825X_HDTG,
+               .start_bit = 0,
+       },
+       {
+               {
+                       .id = V4L2_CID_V_EDGE_EN,
+                       .type = V4L2_CTRL_TYPE_INTEGER,
+                       .name = "Vertical Edge Enhancement",
+                       .minimum = 0,
+                       .maximum = 0xff,
+                       .step = 1,
+               },
+               .reg = TCM825X_VDTG,
+               .start_bit = 0,
+       },
+       {
+               {
+                       .id = V4L2_CID_LENS,
+                       .type = V4L2_CTRL_TYPE_INTEGER,
+                       .name = "Lens Shading Compensation",
+                       .minimum = 0,
+                       .maximum = 0x3f,
+                       .step = 1,
+               },
+               .reg = TCM825X_LENS,
+               .start_bit = 0,
+       },
+       {
+               {
+                       .id = V4L2_CID_MAX_EXPOSURE_TIME,
+                       .type = V4L2_CTRL_TYPE_INTEGER,
+                       .name = "Maximum Exposure Time",
+                       .minimum = 0,
+                       .maximum = 0x3,
+                       .step = 1,
+               },
+               .reg = TCM825X_ESRLIM,
+               .start_bit = 5,
+       },
+};
+
+
+const static struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] =
+{ &subqcif, &qqvga, &qcif, &qvga, &cif, &vga };
+
+const static struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] =
+{ &yuv422, &rgb565 };
+
+/*
+ * Read a value from a register in an TCM825X sensor device.  The value is
+ * returned in 'val'.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tcm825x_read_reg(struct i2c_client *client, int reg)
+{
+       int err;
+       struct i2c_msg msg[2];
+       u8 reg_buf, data_buf = 0;
+
+       if (!client->adapter)
+               return -ENODEV;
+
+       msg[0].addr = client->addr;
+       msg[0].flags = 0;
+       msg[0].len = 1;
+       msg[0].buf = &reg_buf;
+       msg[1].addr = client->addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].len = 1;
+       msg[1].buf = &data_buf;
+
+       reg_buf = reg;
+
+       err = i2c_transfer(client->adapter, msg, 2);
+       if (err < 0)
+               return err;
+       return data_buf;
+}
+
+/*
+ * Write a value to a register in an TCM825X sensor device.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tcm825x_write_reg(struct i2c_client *client, u8 reg, u8 val)
+{
+       int err;
+       struct i2c_msg msg[1];
+       unsigned char data[2];
+
+       if (!client->adapter)
+               return -ENODEV;
+
+       msg->addr = client->addr;
+       msg->flags = 0;
+       msg->len = 2;
+       msg->buf = data;
+       data[0] = reg;
+       data[1] = val;
+       err = i2c_transfer(client->adapter, msg, 1);
+       if (err >= 0)
+               return 0;
+       return err;
+}
+
+static int __tcm825x_write_reg_mask(struct i2c_client *client,
+                                   u8 reg, u8 val, u8 mask)
+{
+       int rc;
+
+       /* need to do read - modify - write */
+       rc = tcm825x_read_reg(client, reg);
+       if (rc < 0)
+               return rc;
+
+       rc &= (~mask);  /* Clear the masked bits */
+       val &= mask;    /* Enforce mask on value */
+       val |= rc;
+
+       /* write the new value to the register */
+       rc = tcm825x_write_reg(client, reg, val);
+       if (rc)
+               return rc;
+
+       return 0;
+}
+
+#define tcm825x_write_reg_mask(client, regmask, val)                   \
+       __tcm825x_write_reg_mask(client, TCM825X_ADDR((regmask)), val,  \
+                                TCM825X_MASK((regmask)))
+
+
+/*
+ * Initialize a list of TCM825X registers.
+ * The list of registers is terminated by the pair of values
+ * { TCM825X_REG_TERM, TCM825X_VAL_TERM }.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+static int tcm825x_write_default_regs(struct i2c_client *client,
+                                     const struct tcm825x_reg *reglist)
+{
+       int err;
+       const struct tcm825x_reg *next = reglist;
+
+       while (!((next->reg == TCM825X_REG_TERM)
+                && (next->val == TCM825X_VAL_TERM))) {
+               err = tcm825x_write_reg(client, next->reg, next->val);
+               if (err) {
+                       dev_err(&client->dev, "register writing failed\n");
+                       return err;
+               }
+               next++;
+       }
+
+       return 0;
+}
+
+static struct vcontrol *find_vctrl(int id)
+{
+       int i;
+
+       if (id < V4L2_CID_BASE)
+               return NULL;
+
+       for (i = 0; i < ARRAY_SIZE(video_control); i++)
+               if (video_control[i].qc.id == id)
+                       return &video_control[i];
+
+       return NULL;
+}
+
+/*
+ * Find the best match for a requested image capture size.  The best match
+ * is chosen as the nearest match that has the same number or fewer pixels
+ * as the requested size, or the smallest image size if the requested size
+ * has fewer pixels than the smallest image.
+ */
+static enum image_size tcm825x_find_size(struct v4l2_int_device *s,
+                                        unsigned int width,
+                                        unsigned int height)
+{
+       enum image_size isize;
+       unsigned long pixels = width * height;
+       struct tcm825x_sensor *sensor = s->priv;
+
+       for (isize = subQCIF; isize < VGA; isize++) {
+               if (tcm825x_sizes[isize + 1].height
+                   * tcm825x_sizes[isize + 1].width > pixels) {
+                       dev_dbg(&sensor->i2c_client->dev, "size %d\n", isize);
+
+                       return isize;
+               }
+       }
+
+       dev_dbg(&sensor->i2c_client->dev, "format default VGA\n");
+
+       return VGA;
+}
+
+/*
+ * Configure the TCM825X for current image size, pixel format, and
+ * frame period. fper is the frame period (in seconds) expressed as a
+ * fraction. Returns zero if successful, or non-zero otherwise. The
+ * actual frame period is returned in fper.
+ */
+static int tcm825x_configure(struct v4l2_int_device *s)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+       struct v4l2_pix_format *pix = &sensor->pix;
+       enum image_size isize = tcm825x_find_size(s, pix->width, pix->height);
+       struct v4l2_fract *fper = &sensor->timeperframe;
+       enum pixel_format pfmt;
+       int err;
+       u32 tgt_fps;
+       u8 val;
+
+       /* common register initialization */
+       err = tcm825x_write_default_regs(
+               sensor->i2c_client, sensor->platform_data->default_regs());
+       if (err)
+               return err;
+
+       /* configure image size */
+       val = tcm825x_siz_reg[isize]->val;
+       dev_dbg(&sensor->i2c_client->dev,
+               "configuring image size %d\n", isize);
+       err = tcm825x_write_reg_mask(sensor->i2c_client,
+                                    tcm825x_siz_reg[isize]->reg, val);
+       if (err)
+               return err;
+
+       /* configure pixel format */
+       switch (pix->pixelformat) {
+       default:
+       case V4L2_PIX_FMT_RGB565:
+               pfmt = RGB565;
+               break;
+       case V4L2_PIX_FMT_UYVY:
+               pfmt = YUV422;
+               break;
+       }
+
+       dev_dbg(&sensor->i2c_client->dev,
+               "configuring pixel format %d\n", pfmt);
+       val = tcm825x_fmt_reg[pfmt]->val;
+
+       err = tcm825x_write_reg_mask(sensor->i2c_client,
+                                    tcm825x_fmt_reg[pfmt]->reg, val);
+       if (err)
+               return err;
+
+       /*
+        * For frame rate < 15, the FPS reg (addr 0x02, bit 7) must be
+        * set. Frame rate will be halved from the normal.
+        */
+       tgt_fps = fper->denominator / fper->numerator;
+       if (tgt_fps <= HIGH_FPS_MODE_LOWER_LIMIT) {
+               val = tcm825x_read_reg(sensor->i2c_client, 0x02);
+               val |= 0x80;
+               tcm825x_write_reg(sensor->i2c_client, 0x02, val);
+       }
+
+       return 0;
+}
+
+static int ioctl_queryctrl(struct v4l2_int_device *s,
+                               struct v4l2_queryctrl *qc)
+{
+       struct vcontrol *control;
+
+       control = find_vctrl(qc->id);
+
+       if (control == NULL)
+               return -EINVAL;
+
+       *qc = control->qc;
+
+       return 0;
+}
+
+static int ioctl_g_ctrl(struct v4l2_int_device *s,
+                            struct v4l2_control *vc)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+       struct i2c_client *client = sensor->i2c_client;
+       int val, r;
+       struct vcontrol *lvc;
+
+       /* exposure time is special, spread accross 2 registers */
+       if (vc->id == V4L2_CID_EXPOSURE) {
+               int val_lower, val_upper;
+
+               val_upper = tcm825x_read_reg(client,
+                                            TCM825X_ADDR(TCM825X_ESRSPD_U));
+               if (val_upper < 0)
+                       return val_upper;
+               val_lower = tcm825x_read_reg(client,
+                                            TCM825X_ADDR(TCM825X_ESRSPD_L));
+               if (val_lower < 0)
+                       return val_lower;
+
+               vc->value = ((val_upper & 0x1f) << 8) | (val_lower);
+               return 0;
+       }
+
+       lvc = find_vctrl(vc->id);
+       if (lvc == NULL)
+               return -EINVAL;
+
+       r = tcm825x_read_reg(client, TCM825X_ADDR(lvc->reg));
+       if (r < 0)
+               return r;
+       val = r & TCM825X_MASK(lvc->reg);
+       val >>= lvc->start_bit;
+
+       if (val < 0)
+               return val;
+
+       vc->value = val;
+       return 0;
+}
+
+static int ioctl_s_ctrl(struct v4l2_int_device *s,
+                            struct v4l2_control *vc)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+       struct i2c_client *client = sensor->i2c_client;
+       struct vcontrol *lvc;
+       int val = vc->value;
+
+       /* exposure time is special, spread accross 2 registers */
+       if (vc->id == V4L2_CID_EXPOSURE) {
+               int val_lower, val_upper;
+               val_lower = val & TCM825X_MASK(TCM825X_ESRSPD_L);
+               val_upper = (val >> 8) & TCM825X_MASK(TCM825X_ESRSPD_U);
+
+               if (tcm825x_write_reg_mask(client,
+                                          TCM825X_ESRSPD_U, val_upper))
+                       return -EIO;
+
+               if (tcm825x_write_reg_mask(client,
+                                          TCM825X_ESRSPD_L, val_lower))
+                       return -EIO;
+
+               return 0;
+       }
+
+       lvc = find_vctrl(vc->id);
+       if (lvc == NULL)
+               return -EINVAL;
+
+       val = val << lvc->start_bit;
+       if (tcm825x_write_reg_mask(client, lvc->reg, val))
+               return -EIO;
+
+       return 0;
+}
+
+static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
+                                  struct v4l2_fmtdesc *fmt)
+{
+       int index = fmt->index;
+
+       switch (fmt->type) {
+       case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+               if (index >= TCM825X_NUM_CAPTURE_FORMATS)
+                       return -EINVAL;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       fmt->flags = tcm825x_formats[index].flags;
+       strlcpy(fmt->description, tcm825x_formats[index].description,
+               sizeof(fmt->description));
+       fmt->pixelformat = tcm825x_formats[index].pixelformat;
+
+       return 0;
+}
+
+static int ioctl_try_fmt_cap(struct v4l2_int_device *s,
+                            struct v4l2_format *f)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+       enum image_size isize;
+       int ifmt;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+
+       isize = tcm825x_find_size(s, pix->width, pix->height);
+       dev_dbg(&sensor->i2c_client->dev, "isize = %d num_capture = %lu\n",
+               isize, (unsigned long)TCM825X_NUM_CAPTURE_FORMATS);
+
+       pix->width = tcm825x_sizes[isize].width;
+       pix->height = tcm825x_sizes[isize].height;
+
+       for (ifmt = 0; ifmt < TCM825X_NUM_CAPTURE_FORMATS; ifmt++)
+               if (pix->pixelformat == tcm825x_formats[ifmt].pixelformat)
+                       break;
+
+       if (ifmt == TCM825X_NUM_CAPTURE_FORMATS)
+               ifmt = 0;       /* Default = YUV 4:2:2 */
+
+       pix->pixelformat = tcm825x_formats[ifmt].pixelformat;
+       pix->field = V4L2_FIELD_NONE;
+       pix->bytesperline = pix->width * TCM825X_BYTES_PER_PIXEL;
+       pix->sizeimage = pix->bytesperline * pix->height;
+       pix->priv = 0;
+       dev_dbg(&sensor->i2c_client->dev, "format = 0x%08x\n",
+               pix->pixelformat);
+
+       switch (pix->pixelformat) {
+       case V4L2_PIX_FMT_UYVY:
+       default:
+               pix->colorspace = V4L2_COLORSPACE_JPEG;
+               break;
+       case V4L2_PIX_FMT_RGB565:
+               pix->colorspace = V4L2_COLORSPACE_SRGB;
+               break;
+       }
+
+       return 0;
+}
+
+static int ioctl_s_fmt_cap(struct v4l2_int_device *s,
+                               struct v4l2_format *f)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+       struct v4l2_pix_format *pix = &f->fmt.pix;
+       int rval;
+
+       rval = ioctl_try_fmt_cap(s, f);
+       if (rval)
+               return rval;
+
+       rval = tcm825x_configure(s);
+
+       sensor->pix = *pix;
+
+       return rval;
+}
+
+static int ioctl_g_fmt_cap(struct v4l2_int_device *s,
+                               struct v4l2_format *f)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+
+       f->fmt.pix = sensor->pix;
+
+       return 0;
+}
+
+static int ioctl_g_parm(struct v4l2_int_device *s,
+                            struct v4l2_streamparm *a)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+       struct v4l2_captureparm *cparm = &a->parm.capture;
+
+       if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       memset(a, 0, sizeof(*a));
+       a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+       cparm->capability = V4L2_CAP_TIMEPERFRAME;
+       cparm->timeperframe = sensor->timeperframe;
+
+       return 0;
+}
+
+static int ioctl_s_parm(struct v4l2_int_device *s,
+                            struct v4l2_streamparm *a)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+       struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+       u32 tgt_fps;    /* target frames per secound */
+       int rval;
+
+       if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       if ((timeperframe->numerator == 0)
+           || (timeperframe->denominator == 0)) {
+               timeperframe->denominator = DEFAULT_FPS;
+               timeperframe->numerator = 1;
+       }
+
+       tgt_fps = timeperframe->denominator / timeperframe->numerator;
+
+       if (tgt_fps > MAX_FPS) {
+               timeperframe->denominator = MAX_FPS;
+               timeperframe->numerator = 1;
+       } else if (tgt_fps < MIN_FPS) {
+               timeperframe->denominator = MIN_FPS;
+               timeperframe->numerator = 1;
+       }
+
+       sensor->timeperframe = *timeperframe;
+
+       rval = tcm825x_configure(s);
+
+       return rval;
+}
+
+static int ioctl_s_power(struct v4l2_int_device *s, int on)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+
+       return sensor->platform_data->power_set(on);
+}
+
+/*
+ * Given the image capture format in pix, the nominal frame period in
+ * timeperframe, calculate the required xclk frequency.
+ *
+ * TCM825X input frequency characteristics are:
+ *     Minimum 11.9 MHz, Typical 24.57 MHz and maximum 25/27 MHz
+ */
+
+static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+       struct v4l2_fract *timeperframe = &sensor->timeperframe;
+       u32 tgt_xclk;   /* target xclk */
+       u32 tgt_fps;    /* target frames per secound */
+       int rval;
+
+       rval = sensor->platform_data->ifparm(p);
+       if (rval)
+               return rval;
+
+       tgt_fps = timeperframe->denominator / timeperframe->numerator;
+
+       tgt_xclk = (tgt_fps <= HIGH_FPS_MODE_LOWER_LIMIT) ?
+               (2457 * tgt_fps) / MAX_HALF_FPS :
+               (2457 * tgt_fps) / MAX_FPS;
+       tgt_xclk *= 10000;
+
+       tgt_xclk = min(tgt_xclk, (u32)TCM825X_XCLK_MAX);
+       tgt_xclk = max(tgt_xclk, (u32)TCM825X_XCLK_MIN);
+
+       p->u.bt656.clock_curr = tgt_xclk;
+
+       return 0;
+}
+
+static int ioctl_g_needs_reset(struct v4l2_int_device *s, void *buf)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+
+       return sensor->platform_data->needs_reset(s, buf, &sensor->pix);
+}
+
+static int ioctl_reset(struct v4l2_int_device *s)
+{
+       return -EBUSY;
+}
+
+static int ioctl_init(struct v4l2_int_device *s)
+{
+       return tcm825x_configure(s);
+}
+
+static int ioctl_dev_exit(struct v4l2_int_device *s)
+{
+       return 0;
+}
+
+static int ioctl_dev_init(struct v4l2_int_device *s)
+{
+       struct tcm825x_sensor *sensor = s->priv;
+       int r;
+
+       r = tcm825x_read_reg(sensor->i2c_client, 0x01);
+       if (r < 0)
+               return r;
+       if (r == 0) {
+               dev_err(&sensor->i2c_client->dev, "device not detected\n");
+               return -EIO;
+       }
+       return 0;
+}
+
+static struct v4l2_int_ioctl_desc tcm825x_ioctl_desc[] = {
+       { vidioc_int_dev_init_num,
+         (v4l2_int_ioctl_func *)ioctl_dev_init },
+       { vidioc_int_dev_exit_num,
+         (v4l2_int_ioctl_func *)ioctl_dev_exit },
+       { vidioc_int_s_power_num,
+         (v4l2_int_ioctl_func *)ioctl_s_power },
+       { vidioc_int_g_ifparm_num,
+         (v4l2_int_ioctl_func *)ioctl_g_ifparm },
+       { vidioc_int_g_needs_reset_num,
+         (v4l2_int_ioctl_func *)ioctl_g_needs_reset },
+       { vidioc_int_reset_num,
+         (v4l2_int_ioctl_func *)ioctl_reset },
+       { vidioc_int_init_num,
+         (v4l2_int_ioctl_func *)ioctl_init },
+       { vidioc_int_enum_fmt_cap_num,
+         (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
+       { vidioc_int_try_fmt_cap_num,
+         (v4l2_int_ioctl_func *)ioctl_try_fmt_cap },
+       { vidioc_int_g_fmt_cap_num,
+         (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
+       { vidioc_int_s_fmt_cap_num,
+         (v4l2_int_ioctl_func *)ioctl_s_fmt_cap },
+       { vidioc_int_g_parm_num,
+         (v4l2_int_ioctl_func *)ioctl_g_parm },
+       { vidioc_int_s_parm_num,
+         (v4l2_int_ioctl_func *)ioctl_s_parm },
+       { vidioc_int_queryctrl_num,
+         (v4l2_int_ioctl_func *)ioctl_queryctrl },
+       { vidioc_int_g_ctrl_num,
+         (v4l2_int_ioctl_func *)ioctl_g_ctrl },
+       { vidioc_int_s_ctrl_num,
+         (v4l2_int_ioctl_func *)ioctl_s_ctrl },
+};
+
+static struct v4l2_int_slave tcm825x_slave = {
+       .ioctls = tcm825x_ioctl_desc,
+       .num_ioctls = ARRAY_SIZE(tcm825x_ioctl_desc),
+};
+
+static struct tcm825x_sensor tcm825x;
+
+static struct v4l2_int_device tcm825x_int_device = {
+       .module = THIS_MODULE,
+       .name = TCM825X_NAME,
+       .priv = &tcm825x,
+       .type = v4l2_int_type_slave,
+       .u = {
+               .slave = &tcm825x_slave,
+       },
+};
+
+static int tcm825x_probe(struct i2c_client *client)
+{
+       struct tcm825x_sensor *sensor = &tcm825x;
+       int rval;
+
+       if (i2c_get_clientdata(client))
+               return -EBUSY;
+
+       sensor->platform_data = client->dev.platform_data;
+
+       if (sensor->platform_data == NULL
+           && !sensor->platform_data->is_okay())
+               return -ENODEV;
+
+       sensor->v4l2_int_device = &tcm825x_int_device;
+
+       sensor->i2c_client = client;
+       i2c_set_clientdata(client, sensor);
+
+       /* Make the default capture format QVGA RGB565 */
+       sensor->pix.width = tcm825x_sizes[QVGA].width;
+       sensor->pix.height = tcm825x_sizes[QVGA].height;
+       sensor->pix.pixelformat = V4L2_PIX_FMT_RGB565;
+
+       rval = v4l2_int_device_register(sensor->v4l2_int_device);
+       if (rval)
+               i2c_set_clientdata(client, NULL);
+
+       return rval;
+}
+
+static int __exit tcm825x_remove(struct i2c_client *client)
+{
+       struct tcm825x_sensor *sensor = i2c_get_clientdata(client);
+
+       if (!client->adapter)
+               return -ENODEV; /* our client isn't attached */
+
+       v4l2_int_device_unregister(sensor->v4l2_int_device);
+       i2c_set_clientdata(client, NULL);
+
+       return 0;
+}
+
+static struct i2c_driver tcm825x_i2c_driver = {
+       .driver = {
+               .name = TCM825X_NAME,
+       },
+       .probe  = tcm825x_probe,
+       .remove = __exit_p(tcm825x_remove),
+};
+
+static struct tcm825x_sensor tcm825x = {
+       .timeperframe = {
+               .numerator   = 1,
+               .denominator = DEFAULT_FPS,
+       },
+};
+
+static int __init tcm825x_init(void)
+{
+       int rval;
+
+       rval = i2c_add_driver(&tcm825x_i2c_driver);
+       if (rval)
+               printk(KERN_INFO "%s: failed registering " TCM825X_NAME "\n",
+                      __FUNCTION__);
+
+       return rval;
+}
+
+static void __exit tcm825x_exit(void)
+{
+       i2c_del_driver(&tcm825x_i2c_driver);
+}
+
+/*
+ * FIXME: Menelaus isn't ready (?) at module_init stage, so use
+ * late_initcall for now.
+ */
+late_initcall(tcm825x_init);
+module_exit(tcm825x_exit);
+
+MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
+MODULE_DESCRIPTION("TCM825x camera sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tcm825x.h b/drivers/media/video/tcm825x.h
new file mode 100644 (file)
index 0000000..966765b
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * drivers/media/video/tcm825x.h
+ *
+ * Register definitions for the TCM825X CameraChip.
+ *
+ * Author: David Cohen (david.cohen@indt.org.br)
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ * This file was based on ov9640.h from MontaVista
+ */
+
+#ifndef TCM825X_H
+#define TCM825X_H
+
+#include <linux/videodev2.h>
+
+#include <media/v4l2-int-device.h>
+
+#define TCM825X_NAME "tcm825x"
+
+#define TCM825X_MASK(x)  x & 0x00ff
+#define TCM825X_ADDR(x) (x & 0xff00) >> 8
+
+/* The TCM825X I2C sensor chip has a fixed slave address of 0x3d. */
+#define TCM825X_I2C_ADDR       0x3d
+
+/*
+ * define register offsets for the TCM825X sensor chip
+ * OFFSET(8 bits) + MASK(8 bits)
+ * MASK bit 4 and 3 are used when the register uses more than one address
+ */
+#define TCM825X_FPS            0x0280
+#define TCM825X_ACF            0x0240
+#define TCM825X_DOUTBUF                0x020C
+#define TCM825X_DCLKP          0x0202
+#define TCM825X_ACFDET         0x0201
+#define TCM825X_DOUTSW         0x0380
+#define TCM825X_DATAHZ         0x0340
+#define TCM825X_PICSIZ         0x033c
+#define TCM825X_PICFMT         0x0302
+#define TCM825X_V_INV          0x0480
+#define TCM825X_H_INV          0x0440
+#define TCM825X_ESRLSW         0x0430
+#define TCM825X_V_LENGTH       0x040F
+#define TCM825X_ALCSW          0x0580
+#define TCM825X_ESRLIM         0x0560
+#define TCM825X_ESRSPD_U        0x051F
+#define TCM825X_ESRSPD_L        0x06FF
+#define TCM825X_AG             0x07FF
+#define TCM825X_ESRSPD2         0x06FF
+#define TCM825X_ALCMODE         0x0830
+#define TCM825X_ALCH            0x080F
+#define TCM825X_ALCL            0x09FF
+#define TCM825X_AWBSW           0x0A80
+#define TCM825X_MRG             0x0BFF
+#define TCM825X_MBG             0x0CFF
+#define TCM825X_GAMSW           0x0D80
+#define TCM825X_HDTG            0x0EFF
+#define TCM825X_VDTG            0x0FFF
+#define TCM825X_HDTCORE         0x10F0
+#define TCM825X_VDTCORE         0x100F
+#define TCM825X_CONT            0x11FF
+#define TCM825X_BRIGHT          0x12FF
+#define TCM825X_VHUE            0x137F
+#define TCM825X_UHUE            0x147F
+#define TCM825X_VGAIN           0x153F
+#define TCM825X_UGAIN           0x163F
+#define TCM825X_UVCORE          0x170F
+#define TCM825X_SATU            0x187F
+#define TCM825X_MHMODE          0x1980
+#define TCM825X_MHLPFSEL        0x1940
+#define TCM825X_YMODE           0x1930
+#define TCM825X_MIXHG           0x1907
+#define TCM825X_LENS            0x1A3F
+#define TCM825X_AGLIM           0x1BE0
+#define TCM825X_LENSRPOL        0x1B10
+#define TCM825X_LENSRGAIN       0x1B0F
+#define TCM825X_ES100S          0x1CFF
+#define TCM825X_ES120S          0x1DFF
+#define TCM825X_DMASK           0x1EC0
+#define TCM825X_CODESW          0x1E20
+#define TCM825X_CODESEL         0x1E10
+#define TCM825X_TESPIC          0x1E04
+#define TCM825X_PICSEL          0x1E03
+#define TCM825X_HNUM            0x20FF
+#define TCM825X_VOUTPH          0x287F
+#define TCM825X_ESROUT          0x327F
+#define TCM825X_ESROUT2         0x33FF
+#define TCM825X_AGOUT           0x34FF
+#define TCM825X_DGOUT           0x353F
+#define TCM825X_AGSLOW1         0x39C0
+#define TCM825X_FLLSMODE        0x3930
+#define TCM825X_FLLSLIM         0x390F
+#define TCM825X_DETSEL          0x3AF0
+#define TCM825X_ACDETNC         0x3A0F
+#define TCM825X_AGSLOW2         0x3BC0
+#define TCM825X_DG              0x3B3F
+#define TCM825X_REJHLEV         0x3CFF
+#define TCM825X_ALCLOCK         0x3D80
+#define TCM825X_FPSLNKSW        0x3D40
+#define TCM825X_ALCSPD          0x3D30
+#define TCM825X_REJH            0x3D03
+#define TCM825X_SHESRSW         0x3E80
+#define TCM825X_ESLIMSEL        0x3E40
+#define TCM825X_SHESRSPD        0x3E30
+#define TCM825X_ELSTEP          0x3E0C
+#define TCM825X_ELSTART         0x3E03
+#define TCM825X_AGMIN           0x3FFF
+#define TCM825X_PREGRG          0x423F
+#define TCM825X_PREGBG          0x433F
+#define TCM825X_PRERG           0x443F
+#define TCM825X_PREBG           0x453F
+#define TCM825X_MSKBR           0x477F
+#define TCM825X_MSKGR           0x487F
+#define TCM825X_MSKRB           0x497F
+#define TCM825X_MSKGB           0x4A7F
+#define TCM825X_MSKRG           0x4B7F
+#define TCM825X_MSKBG           0x4C7F
+#define TCM825X_HDTCSW          0x4D80
+#define TCM825X_VDTCSW          0x4D40
+#define TCM825X_DTCYL           0x4D3F
+#define TCM825X_HDTPSW          0x4E80
+#define TCM825X_VDTPSW          0x4E40
+#define TCM825X_DTCGAIN         0x4E3F
+#define TCM825X_DTLLIMSW        0x4F10
+#define TCM825X_DTLYLIM         0x4F0F
+#define TCM825X_YLCUTLMSK       0x5080
+#define TCM825X_YLCUTL          0x503F
+#define TCM825X_YLCUTHMSK       0x5180
+#define TCM825X_YLCUTH          0x513F
+#define TCM825X_UVSKNC          0x527F
+#define TCM825X_UVLJ            0x537F
+#define TCM825X_WBGMIN          0x54FF
+#define TCM825X_WBGMAX          0x55FF
+#define TCM825X_WBSPDUP         0x5603
+#define TCM825X_ALLAREA         0x5820
+#define TCM825X_WBLOCK          0x5810
+#define TCM825X_WB2SP           0x580F
+#define TCM825X_KIZUSW          0x5920
+#define TCM825X_PBRSW           0x5910
+#define TCM825X_ABCSW           0x5903
+#define TCM825X_PBDLV           0x5AFF
+#define TCM825X_PBC1LV          0x5BFF
+
+#define TCM825X_NUM_REGS       (TCM825X_ADDR(TCM825X_PBC1LV) + 1)
+
+#define TCM825X_BYTES_PER_PIXEL 2
+
+#define TCM825X_REG_TERM 0xff          /* terminating list entry for reg */
+#define TCM825X_VAL_TERM 0xff          /* terminating list entry for val */
+
+/* define a structure for tcm825x register initialization values */
+struct tcm825x_reg {
+       u8 val;
+       u16 reg;
+};
+
+enum image_size { subQCIF = 0, QQVGA, QCIF, QVGA, CIF, VGA };
+enum pixel_format { YUV422 = 0, RGB565 };
+#define NUM_IMAGE_SIZES 6
+#define NUM_PIXEL_FORMATS 2
+
+#define TCM825X_XCLK_MIN       11900000
+#define TCM825X_XCLK_MAX       25000000
+
+struct capture_size {
+       unsigned long width;
+       unsigned long height;
+};
+
+struct tcm825x_platform_data {
+       /* Is the sensor usable? Doesn't yet mean it's there, but you
+        * can try! */
+       int (*is_okay)(void);
+       /* Set power state, zero is off, non-zero is on. */
+       int (*power_set)(int power);
+       /* Default registers written after power-on or reset. */
+       const struct tcm825x_reg *(*default_regs)(void);
+       int (*needs_reset)(struct v4l2_int_device *s, void *buf,
+                          struct v4l2_pix_format *fmt);
+       int (*ifparm)(struct v4l2_ifparm *p);
+};
+
+/* Array of image sizes supported by TCM825X.  These must be ordered from
+ * smallest image size to largest.
+ */
+const static struct capture_size tcm825x_sizes[] = {
+       { 128,  96 }, /* subQCIF */
+       { 160, 120 }, /* QQVGA */
+       { 176, 144 }, /* QCIF */
+       { 320, 240 }, /* QVGA */
+       { 352, 288 }, /* CIF */
+       { 640, 480 }, /* VGA */
+};
+
+#endif /* ifndef TCM825X_H */
index 59cff5a3c59e106fb47cf243160ccdf62b2cafe3..0e5cf459d3ed615c70474d8064bc111000c92f0f 100644 (file)
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+   This "tda8290" module was split apart from the original "tuner" module.
 */
 
 #include <linux/i2c.h>
-#include <linux/videodev.h>
 #include <linux/delay.h>
-#include "tuner-driver.h"
+#include <linux/videodev.h>
+#include "tuner-i2c.h"
+#include "tda8290.h"
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+#define PREFIX "tda8290 "
 
 /* ---------------------------------------------------------------------- */
 
 struct tda8290_priv {
+       struct tuner_i2c_props i2c_props;
+
        unsigned char tda8290_easy_mode;
        unsigned char tda827x_lpsel;
        unsigned char tda827x_addr;
        unsigned char tda827x_ver;
        unsigned int sgIF;
+
+       u32 frequency;
+
+       unsigned int *lna_cfg;
+       int (*tuner_callback) (void *dev, int command,int arg);
 };
 
 /* ---------------------------------------------------------------------- */
@@ -79,20 +95,21 @@ static struct tda827x_data tda827x_analog[] = {
        { .lomax =     0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}  /* End      */
 };
 
-static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
+static void tda827x_set_analog_params(struct dvb_frontend *fe,
+                                     struct analog_parameters *params)
 {
        unsigned char tuner_reg[8];
        unsigned char reg2[2];
        u32 N;
        int i;
-       struct tuner *t = i2c_get_clientdata(c);
-       struct tda8290_priv *priv = t->priv;
+       struct tda8290_priv *priv = fe->tuner_priv;
        struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags = 0};
+       unsigned int freq = params->frequency;
 
-       if (t->mode == V4L2_TUNER_RADIO)
+       if (params->mode == V4L2_TUNER_RADIO)
                freq = freq / 1000;
 
-       N = freq + ifc;
+       N = freq + priv->sgIF;
        i = 0;
        while (tda827x_analog[i].lomax < N) {
                if(tda827x_analog[i + 1].lomax == 0)
@@ -114,54 +131,53 @@ static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
 
        msg.buf = tuner_reg;
        msg.len = 8;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        msg.buf= reg2;
        msg.len = 2;
        reg2[0] = 0x80;
        reg2[1] = 0;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        reg2[0] = 0x60;
        reg2[1] = 0xbf;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        reg2[0] = 0x30;
        reg2[1] = tuner_reg[4] + 0x80;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        msleep(1);
        reg2[0] = 0x30;
        reg2[1] = tuner_reg[4] + 4;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        msleep(1);
        reg2[0] = 0x30;
        reg2[1] = tuner_reg[4];
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        msleep(550);
        reg2[0] = 0x30;
        reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_analog[i].cp ;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        reg2[0] = 0x60;
        reg2[1] = 0x3f;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        reg2[0] = 0x80;
        reg2[1] = 0x08;   // Vsync en
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 }
 
-static void tda827x_agcf(struct i2c_client *c)
+static void tda827x_agcf(struct dvb_frontend *fe)
 {
-       struct tuner *t = i2c_get_clientdata(c);
-       struct tda8290_priv *priv = t->priv;
+       struct tda8290_priv *priv = fe->tuner_priv;
        unsigned char data[] = {0x80, 0x0c};
        struct i2c_msg msg = {.addr = priv->tda827x_addr, .buf = data,
                              .flags = 0, .len = 2};
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 }
 
 /* ---------------------------------------------------------------------- */
@@ -204,58 +220,64 @@ static struct tda827xa_data tda827xa_analog[] = {
        { .lomax =     0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}   /* End */
 };
 
-static void tda827xa_lna_gain(struct i2c_client *c, int high)
+static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
+                             struct analog_parameters *params)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct tda8290_priv *priv = fe->tuner_priv;
        unsigned char buf[] = {0x22, 0x01};
        int arg;
-       struct i2c_msg msg = {.addr = c->addr, .flags = 0, .buf = buf, .len = sizeof(buf)};
-       if (t->config) {
+       struct i2c_msg msg = {.addr = priv->i2c_props.addr, .flags = 0, .buf = buf, .len = sizeof(buf)};
+
+       if ((priv->lna_cfg == NULL)  || (priv->tuner_callback == NULL))
+           return;
+
+       if (*priv->lna_cfg) {
                if (high)
                        tuner_dbg("setting LNA to high gain\n");
                else
                        tuner_dbg("setting LNA to low gain\n");
        }
-       switch (t->config) {
+       switch (*priv->lna_cfg) {
        case 0: /* no LNA */
                break;
        case 1: /* switch is GPIO 0 of tda8290 */
        case 2:
                /* turn Vsync on */
-               if (t->std & V4L2_STD_MN)
+               if (params->std & V4L2_STD_MN)
                        arg = 1;
                else
                        arg = 0;
-               if (t->tuner_callback)
-                       t->tuner_callback(c->adapter->algo_data, 1, arg);
+               if (priv->tuner_callback)
+                       priv->tuner_callback(priv->i2c_props.adap->algo_data, 1, arg);
                buf[1] = high ? 0 : 1;
-               if (t->config == 2)
+               if (*priv->lna_cfg == 2)
                        buf[1] = high ? 1 : 0;
-               i2c_transfer(c->adapter, &msg, 1);
+               i2c_transfer(priv->i2c_props.adap, &msg, 1);
                break;
        case 3: /* switch with GPIO of saa713x */
-               if (t->tuner_callback)
-                       t->tuner_callback(c->adapter->algo_data, 0, high);
+               if (priv->tuner_callback)
+                       priv->tuner_callback(priv->i2c_props.adap->algo_data, 0, high);
                break;
        }
 }
 
-static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
+static void tda827xa_set_analog_params(struct dvb_frontend *fe,
+                                      struct analog_parameters *params)
 {
        unsigned char tuner_reg[11];
        u32 N;
        int i;
-       struct tuner *t = i2c_get_clientdata(c);
-       struct tda8290_priv *priv = t->priv;
+       struct tda8290_priv *priv = fe->tuner_priv;
        struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags = 0, .buf = tuner_reg};
+       unsigned int freq = params->frequency;
 
-       tda827xa_lna_gain( c, 1);
+       tda827xa_lna_gain(fe, 1, params);
        msleep(10);
 
-       if (t->mode == V4L2_TUNER_RADIO)
+       if (params->mode == V4L2_TUNER_RADIO)
                freq = freq / 1000;
 
-       N = freq + ifc;
+       N = freq + priv->sgIF;
        i = 0;
        while (tda827xa_analog[i].lomax < N) {
                if(tda827xa_analog[i + 1].lomax == 0)
@@ -278,7 +300,7 @@ static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
        tuner_reg[9] = 0x20;
        tuner_reg[10] = 0x00;
        msg.len = 11;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        tuner_reg[0] = 0x90;
        tuner_reg[1] = 0xff;
@@ -286,82 +308,131 @@ static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
        tuner_reg[3] = 0;
        tuner_reg[4] = 0x99 + (priv->tda827x_lpsel << 1);
        msg.len = 5;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        tuner_reg[0] = 0xa0;
        tuner_reg[1] = 0xc0;
        msg.len = 2;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        tuner_reg[0] = 0x30;
        tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        msg.flags = I2C_M_RD;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
        msg.flags = 0;
        tuner_reg[1] >>= 4;
        tuner_dbg("AGC2 gain is: %d\n", tuner_reg[1]);
        if (tuner_reg[1] < 1)
-               tda827xa_lna_gain( c, 0);
+               tda827xa_lna_gain(fe, 0, params);
 
        msleep(100);
        tuner_reg[0] = 0x60;
        tuner_reg[1] = 0x3c;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        msleep(163);
        tuner_reg[0] = 0x50;
        tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        tuner_reg[0] = 0x80;
        tuner_reg[1] = 0x28;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        tuner_reg[0] = 0xb0;
        tuner_reg[1] = 0x01;
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        tuner_reg[0] = 0xc0;
        tuner_reg[1] = 0x19 + (priv->tda827x_lpsel << 1);
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 }
 
-static void tda827xa_agcf(struct i2c_client *c)
+static void tda827xa_agcf(struct dvb_frontend *fe)
 {
-       struct tuner *t = i2c_get_clientdata(c);
-       struct tda8290_priv *priv = t->priv;
+       struct tda8290_priv *priv = fe->tuner_priv;
        unsigned char data[] = {0x80, 0x2c};
        struct i2c_msg msg = {.addr = priv->tda827x_addr, .buf = data,
                              .flags = 0, .len = 2};
-       i2c_transfer(c->adapter, &msg, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
 }
 
 /*---------------------------------------------------------------------*/
 
-static void tda8290_i2c_bridge(struct i2c_client *c, int close)
+static void tda8290_i2c_bridge(struct dvb_frontend *fe, int close)
 {
+       struct tda8290_priv *priv = fe->tuner_priv;
+
        unsigned char  enable[2] = { 0x21, 0xC0 };
        unsigned char disable[2] = { 0x21, 0x00 };
        unsigned char *msg;
        if(close) {
                msg = enable;
-               i2c_master_send(c, msg, 2);
+               tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
                /* let the bridge stabilize */
                msleep(20);
        } else {
                msg = disable;
-               i2c_master_send(c, msg, 2);
+               tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
        }
 }
 
 /*---------------------------------------------------------------------*/
 
-static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
+static void set_audio(struct dvb_frontend *fe,
+                     struct analog_parameters *params)
+{
+       struct tda8290_priv *priv = fe->tuner_priv;
+       char* mode;
+
+       priv->tda827x_lpsel = 0;
+       if (params->std & V4L2_STD_MN) {
+               priv->sgIF = 92;
+               priv->tda8290_easy_mode = 0x01;
+               priv->tda827x_lpsel = 1;
+               mode = "MN";
+       } else if (params->std & V4L2_STD_B) {
+               priv->sgIF = 108;
+               priv->tda8290_easy_mode = 0x02;
+               mode = "B";
+       } else if (params->std & V4L2_STD_GH) {
+               priv->sgIF = 124;
+               priv->tda8290_easy_mode = 0x04;
+               mode = "GH";
+       } else if (params->std & V4L2_STD_PAL_I) {
+               priv->sgIF = 124;
+               priv->tda8290_easy_mode = 0x08;
+               mode = "I";
+       } else if (params->std & V4L2_STD_DK) {
+               priv->sgIF = 124;
+               priv->tda8290_easy_mode = 0x10;
+               mode = "DK";
+       } else if (params->std & V4L2_STD_SECAM_L) {
+               priv->sgIF = 124;
+               priv->tda8290_easy_mode = 0x20;
+               mode = "L";
+       } else if (params->std & V4L2_STD_SECAM_LC) {
+               priv->sgIF = 20;
+               priv->tda8290_easy_mode = 0x40;
+               mode = "LC";
+       } else {
+               priv->sgIF = 124;
+               priv->tda8290_easy_mode = 0x10;
+               mode = "xx";
+       }
+
+       if (params->mode == V4L2_TUNER_RADIO)
+               priv->sgIF = 88; /* if frequency is 5.5 MHz */
+
+       tuner_dbg("setting tda8290 to system %s\n", mode);
+}
+
+static int tda8290_set_params(struct dvb_frontend *fe,
+                             struct analog_parameters *params)
 {
-       struct tuner *t = i2c_get_clientdata(c);
-       struct tda8290_priv *priv = t->priv;
+       struct tda8290_priv *priv = fe->tuner_priv;
        unsigned char soft_reset[]  = { 0x00, 0x00 };
        unsigned char easy_mode[]   = { 0x01, priv->tda8290_easy_mode };
        unsigned char expert_mode[] = { 0x01, 0x80 };
@@ -384,35 +455,38 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
                      pll_stat;
        int i;
 
-       tuner_dbg("tda827xa config is 0x%02x\n", t->config);
-       i2c_master_send(c, easy_mode, 2);
-       i2c_master_send(c, agc_out_on, 2);
-       i2c_master_send(c, soft_reset, 2);
+       set_audio(fe, params);
+
+       if (priv->lna_cfg)
+               tuner_dbg("tda827xa config is 0x%02x\n", *priv->lna_cfg);
+       tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2);
        msleep(1);
 
        expert_mode[1] = priv->tda8290_easy_mode + 0x80;
-       i2c_master_send(c, expert_mode, 2);
-       i2c_master_send(c, gainset_off, 2);
-       i2c_master_send(c, if_agc_spd, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2);
        if (priv->tda8290_easy_mode & 0x60)
-               i2c_master_send(c, adc_head_9, 2);
+               tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2);
        else
-               i2c_master_send(c, adc_head_6, 2);
-       i2c_master_send(c, pll_bw_nom, 2);
+               tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
 
-       tda8290_i2c_bridge(c, 1);
+       tda8290_i2c_bridge(fe, 1);
        if (priv->tda827x_ver != 0)
-               tda827xa_tune(c, ifc, freq);
+               tda827xa_set_analog_params(fe, params);
        else
-               tda827x_tune(c, ifc, freq);
+               tda827x_set_analog_params(fe, params);
        for (i = 0; i < 3; i++) {
-               i2c_master_send(c, &addr_pll_stat, 1);
-               i2c_master_recv(c, &pll_stat, 1);
+               tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
+               tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
                if (pll_stat & 0x80) {
-                       i2c_master_send(c, &addr_adc_sat, 1);
-                       i2c_master_recv(c, &adc_sat, 1);
-                       i2c_master_send(c, &addr_agc_stat, 1);
-                       i2c_master_recv(c, &agc_stat, 1);
+                       tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
+                       tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
+                       tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
+                       tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
                        tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
                        break;
                } else {
@@ -424,28 +498,28 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
        if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
                tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
                           agc_stat, adc_sat, pll_stat & 0x80);
-               i2c_master_send(c, gainset_2, 2);
+               tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2);
                msleep(100);
-               i2c_master_send(c, &addr_agc_stat, 1);
-               i2c_master_recv(c, &agc_stat, 1);
-               i2c_master_send(c, &addr_pll_stat, 1);
-               i2c_master_recv(c, &pll_stat, 1);
+               tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
+               tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
+               tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
+               tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
                if ((agc_stat > 115) || !(pll_stat & 0x80)) {
                        tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
                                   agc_stat, pll_stat & 0x80);
                        if (priv->tda827x_ver != 0)
-                               tda827xa_agcf(c);
+                               tda827xa_agcf(fe);
                        else
-                               tda827x_agcf(c);
+                               tda827x_agcf(fe);
                        msleep(100);
-                       i2c_master_send(c, &addr_agc_stat, 1);
-                       i2c_master_recv(c, &agc_stat, 1);
-                       i2c_master_send(c, &addr_pll_stat, 1);
-                       i2c_master_recv(c, &pll_stat, 1);
+                       tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
+                       tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
+                       tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
+                       tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
                        if((agc_stat > 115) || !(pll_stat & 0x80)) {
                                tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
-                               i2c_master_send(c, adc_head_12, 2);
-                               i2c_master_send(c, pll_bw_low, 2);
+                               tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2);
+                               tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_low, 2);
                                msleep(100);
                        }
                }
@@ -453,132 +527,106 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
 
        /* l/ l' deadlock? */
        if(priv->tda8290_easy_mode & 0x60) {
-               i2c_master_send(c, &addr_adc_sat, 1);
-               i2c_master_recv(c, &adc_sat, 1);
-               i2c_master_send(c, &addr_pll_stat, 1);
-               i2c_master_recv(c, &pll_stat, 1);
+               tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1);
+               tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1);
+               tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
+               tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
                if ((adc_sat > 20) || !(pll_stat & 0x80)) {
                        tuner_dbg("trying to resolve SECAM L deadlock\n");
-                       i2c_master_send(c, agc_rst_on, 2);
+                       tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2);
                        msleep(40);
-                       i2c_master_send(c, agc_rst_off, 2);
+                       tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_off, 2);
                }
        }
 
-       tda8290_i2c_bridge(c, 0);
-       i2c_master_send(c, if_agc_set, 2);
+       tda8290_i2c_bridge(fe, 0);
+       tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2);
+
+       priv->frequency = (V4L2_TUNER_RADIO == params->mode) ?
+               params->frequency * 125 / 2 : params->frequency * 62500;
+
        return 0;
 }
 
 /*---------------------------------------------------------------------*/
 
-static void set_audio(struct tuner *t)
+static int tda8290_has_signal(struct dvb_frontend *fe)
 {
-       struct tda8290_priv *priv = t->priv;
-       char* mode;
+       struct tda8290_priv *priv = fe->tuner_priv;
+       int ret;
 
-       priv->tda827x_lpsel = 0;
-       if (t->std & V4L2_STD_MN) {
-               priv->sgIF = 92;
-               priv->tda8290_easy_mode = 0x01;
-               priv->tda827x_lpsel = 1;
-               mode = "MN";
-       } else if (t->std & V4L2_STD_B) {
-               priv->sgIF = 108;
-               priv->tda8290_easy_mode = 0x02;
-               mode = "B";
-       } else if (t->std & V4L2_STD_GH) {
-               priv->sgIF = 124;
-               priv->tda8290_easy_mode = 0x04;
-               mode = "GH";
-       } else if (t->std & V4L2_STD_PAL_I) {
-               priv->sgIF = 124;
-               priv->tda8290_easy_mode = 0x08;
-               mode = "I";
-       } else if (t->std & V4L2_STD_DK) {
-               priv->sgIF = 124;
-               priv->tda8290_easy_mode = 0x10;
-               mode = "DK";
-       } else if (t->std & V4L2_STD_SECAM_L) {
-               priv->sgIF = 124;
-               priv->tda8290_easy_mode = 0x20;
-               mode = "L";
-       } else if (t->std & V4L2_STD_SECAM_LC) {
-               priv->sgIF = 20;
-               priv->tda8290_easy_mode = 0x40;
-               mode = "LC";
-       } else {
-               priv->sgIF = 124;
-               priv->tda8290_easy_mode = 0x10;
-               mode = "xx";
-       }
-       tuner_dbg("setting tda8290 to system %s\n", mode);
-}
+       unsigned char i2c_get_afc[1] = { 0x1B };
+       unsigned char afc = 0;
 
-static void set_tv_freq(struct i2c_client *c, unsigned int freq)
-{
-       struct tuner *t = i2c_get_clientdata(c);
-       struct tda8290_priv *priv = t->priv;
+       /* for now, report based on afc status */
+       tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc));
+       tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1);
+
+       ret = (afc & 0x80) ? 65535 : 0;
 
-       set_audio(t);
-       tda8290_tune(c, priv->sgIF, freq);
+       tuner_dbg("AFC status: %d\n", ret);
+
+       return ret;
 }
 
-static void set_radio_freq(struct i2c_client *c, unsigned int freq)
+static int tda8290_get_status(struct dvb_frontend *fe, u32 *status)
 {
-       /* if frequency is 5.5 MHz */
-       tda8290_tune(c, 88, freq);
+       *status = 0;
+
+       if (tda8290_has_signal(fe))
+               *status = TUNER_STATUS_LOCKED;
+
+       return 0;
 }
 
-static int has_signal(struct i2c_client *c)
+static int tda8290_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
 {
-       unsigned char i2c_get_afc[1] = { 0x1B };
-       unsigned char afc = 0;
+       *strength = tda8290_has_signal(fe);
 
-       i2c_master_send(c, i2c_get_afc, ARRAY_SIZE(i2c_get_afc));
-       i2c_master_recv(c, &afc, 1);
-       return (afc & 0x80)? 65535:0;
+       return 0;
 }
 
 /*---------------------------------------------------------------------*/
 
-static void standby(struct i2c_client *c)
+static int tda8290_standby(struct dvb_frontend *fe)
 {
-       struct tuner *t = i2c_get_clientdata(c);
-       struct tda8290_priv *priv = t->priv;
+       struct tda8290_priv *priv = fe->tuner_priv;
        unsigned char cb1[] = { 0x30, 0xD0 };
        unsigned char tda8290_standby[] = { 0x00, 0x02 };
        unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
        struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
 
-       tda8290_i2c_bridge(c, 1);
+       tda8290_i2c_bridge(fe, 1);
        if (priv->tda827x_ver != 0)
                cb1[1] = 0x90;
-       i2c_transfer(c->adapter, &msg, 1);
-       tda8290_i2c_bridge(c, 0);
-       i2c_master_send(c, tda8290_agc_tri, 2);
-       i2c_master_send(c, tda8290_standby, 2);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
+       tda8290_i2c_bridge(fe, 0);
+       tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2);
+
+       return 0;
 }
 
 
-static void tda8290_init_if(struct i2c_client *c)
+static void tda8290_init_if(struct dvb_frontend *fe)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct tda8290_priv *priv = fe->tuner_priv;
+
        unsigned char set_VS[] = { 0x30, 0x6F };
        unsigned char set_GP00_CF[] = { 0x20, 0x01 };
        unsigned char set_GP01_CF[] = { 0x20, 0x0B };
 
-       if ((t->config == 1) || (t->config == 2))
-               i2c_master_send(c, set_GP00_CF, 2);
+       if ((priv->lna_cfg) &&
+           ((*priv->lna_cfg == 1) || (*priv->lna_cfg == 2)))
+               tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2);
        else
-               i2c_master_send(c, set_GP01_CF, 2);
-       i2c_master_send(c, set_VS, 2);
+               tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2);
+       tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2);
 }
 
-static void tda8290_init_tuner(struct i2c_client *c)
+static void tda8290_init_tuner(struct dvb_frontend *fe)
 {
-       struct tuner *t = i2c_get_clientdata(c);
-       struct tda8290_priv *priv = t->priv;
+       struct tda8290_priv *priv = fe->tuner_priv;
        unsigned char tda8275_init[]  = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
                                          0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
        unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
@@ -588,33 +636,43 @@ static void tda8290_init_tuner(struct i2c_client *c)
        if (priv->tda827x_ver != 0)
                msg.buf = tda8275a_init;
 
-       tda8290_i2c_bridge(c, 1);
-       i2c_transfer(c->adapter, &msg, 1);
-       tda8290_i2c_bridge(c, 0);
+       tda8290_i2c_bridge(fe, 1);
+       i2c_transfer(priv->i2c_props.adap, &msg, 1);
+       tda8290_i2c_bridge(fe, 0);
 }
 
 /*---------------------------------------------------------------------*/
 
-static void tda8290_release(struct i2c_client *c)
+static int tda8290_release(struct dvb_frontend *fe)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
 
-       kfree(t->priv);
-       t->priv = NULL;
+       return 0;
 }
 
-static struct tuner_operations tda8290_tuner_ops = {
-       .set_tv_freq    = set_tv_freq,
-       .set_radio_freq = set_radio_freq,
-       .has_signal     = has_signal,
-       .standby        = standby,
-       .release        = tda8290_release,
+static int tda8290_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tda8290_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static struct dvb_tuner_ops tda8290_tuner_ops = {
+       .sleep             = tda8290_standby,
+       .set_analog_params = tda8290_set_params,
+       .release           = tda8290_release,
+       .get_frequency     = tda8290_get_frequency,
+       .get_status        = tda8290_get_status,
+       .get_rf_strength   = tda8290_get_rf_strength,
 };
 
-int tda8290_init(struct i2c_client *c)
+struct dvb_frontend *tda8290_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter* i2c_adap,
+                                   u8 i2c_addr,
+                                   struct tda8290_config *cfg)
 {
        struct tda8290_priv *priv = NULL;
-       struct tuner *t = i2c_get_clientdata(c);
        u8 data;
        int i, ret, tuners_found;
        u32 tuner_addrs;
@@ -622,16 +680,23 @@ int tda8290_init(struct i2c_client *c)
 
        priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL);
        if (priv == NULL)
-               return -ENOMEM;
-       t->priv = priv;
+               return NULL;
+       fe->tuner_priv = priv;
+
+       priv->i2c_props.addr = i2c_addr;
+       priv->i2c_props.adap = i2c_adap;
+       if (cfg) {
+               priv->lna_cfg        = cfg->lna_cfg;
+               priv->tuner_callback = cfg->tuner_callback;
+       }
 
-       tda8290_i2c_bridge(c, 1);
+       tda8290_i2c_bridge(fe, 1);
        /* probe for tuner chip */
        tuners_found = 0;
        tuner_addrs = 0;
        for (i=0x60; i<= 0x63; i++) {
                msg.addr = i;
-               ret = i2c_transfer(c->adapter, &msg, 1);
+               ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
                if (ret == 1) {
                        tuners_found++;
                        tuner_addrs = (tuner_addrs << 8) + i;
@@ -641,11 +706,11 @@ int tda8290_init(struct i2c_client *c)
           behind the bridge and we choose the highest address that doesn't
           give a response now
         */
-       tda8290_i2c_bridge(c, 0);
+       tda8290_i2c_bridge(fe, 0);
        if(tuners_found > 1)
                for (i = 0; i < tuners_found; i++) {
                        msg.addr = tuner_addrs  & 0xff;
-                       ret = i2c_transfer(c->adapter, &msg, 1);
+                       ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
                        if(ret == 1)
                                tuner_addrs = tuner_addrs >> 8;
                        else
@@ -653,40 +718,53 @@ int tda8290_init(struct i2c_client *c)
                }
        if (tuner_addrs == 0) {
                tuner_addrs = 0x61;
-               tuner_info ("could not clearly identify tuner address, defaulting to %x\n",
+               tuner_info("could not clearly identify tuner address, defaulting to %x\n",
                             tuner_addrs);
        } else {
                tuner_addrs = tuner_addrs & 0xff;
-               tuner_info ("setting tuner address to %x\n", tuner_addrs);
+               tuner_info("setting tuner address to %x\n", tuner_addrs);
        }
        priv->tda827x_addr = tuner_addrs;
        msg.addr = tuner_addrs;
 
-       tda8290_i2c_bridge(c, 1);
-       ret = i2c_transfer(c->adapter, &msg, 1);
+       tda8290_i2c_bridge(fe, 1);
+       ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
        if( ret != 1)
-               tuner_warn ("TDA827x access failed!\n");
+               tuner_warn("TDA827x access failed!\n");
+
+       memcpy(&fe->ops.tuner_ops, &tda8290_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
        if ((data & 0x3c) == 0) {
-               strlcpy(c->name, "tda8290+75", sizeof(c->name));
+               strlcpy(fe->ops.tuner_ops.info.name, "tda8290+75",
+                       sizeof(fe->ops.tuner_ops.info.name));
+               fe->ops.tuner_ops.info.frequency_min  =  55000000;
+               fe->ops.tuner_ops.info.frequency_max  = 860000000;
+               fe->ops.tuner_ops.info.frequency_step =    250000;
                priv->tda827x_ver = 0;
        } else {
-               strlcpy(c->name, "tda8290+75a", sizeof(c->name));
+               strlcpy(fe->ops.tuner_ops.info.name, "tda8290+75a",
+                       sizeof(fe->ops.tuner_ops.info.name));
+               fe->ops.tuner_ops.info.frequency_min  =  44000000;
+               fe->ops.tuner_ops.info.frequency_max  = 906000000;
+               fe->ops.tuner_ops.info.frequency_step =     62500;
                priv->tda827x_ver = 2;
        }
-       tuner_info("type set to %s\n", c->name);
-
-       memcpy(&t->ops, &tda8290_tuner_ops, sizeof(struct tuner_operations));
 
        priv->tda827x_lpsel = 0;
-       t->mode = V4L2_TUNER_ANALOG_TV;
 
-       tda8290_init_tuner(c);
-       tda8290_init_if(c);
-       return 0;
+       tda8290_init_tuner(fe);
+       tda8290_init_if(fe);
+       return fe;
 }
 
-int tda8290_probe(struct i2c_client *c)
+int tda8290_probe(struct i2c_adapter* i2c_adap, u8 i2c_addr)
 {
+       struct tuner_i2c_props i2c_props = {
+               .adap = i2c_adap,
+               .addr = i2c_addr
+       };
+
        unsigned char soft_reset[]   = { 0x00, 0x00 };
        unsigned char easy_mode_b[]  = { 0x01, 0x02 };
        unsigned char easy_mode_g[]  = { 0x01, 0x04 };
@@ -694,23 +772,30 @@ int tda8290_probe(struct i2c_client *c)
        unsigned char addr_dto_lsb = 0x07;
        unsigned char data;
 
-       i2c_master_send(c, easy_mode_b, 2);
-       i2c_master_send(c, soft_reset, 2);
-       i2c_master_send(c, &addr_dto_lsb, 1);
-       i2c_master_recv(c, &data, 1);
+       tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2);
+       tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
+       tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
+       tuner_i2c_xfer_recv(&i2c_props, &data, 1);
        if (data == 0) {
-               i2c_master_send(c, easy_mode_g, 2);
-               i2c_master_send(c, soft_reset, 2);
-               i2c_master_send(c, &addr_dto_lsb, 1);
-               i2c_master_recv(c, &data, 1);
+               tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2);
+               tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
+               tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
+               tuner_i2c_xfer_recv(&i2c_props, &data, 1);
                if (data == 0x7b) {
                        return 0;
                }
        }
-       i2c_master_send(c, restore_9886, 3);
+       tuner_i2c_xfer_send(&i2c_props, restore_9886, 3);
        return -1;
 }
 
+EXPORT_SYMBOL_GPL(tda8290_probe);
+EXPORT_SYMBOL_GPL(tda8290_attach);
+
+MODULE_DESCRIPTION("Philips TDA8290 + TDA8275 / TDA8275a tuner driver");
+MODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann");
+MODULE_LICENSE("GPL");
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tda8290.h b/drivers/media/video/tda8290.h
new file mode 100644 (file)
index 0000000..107b24b
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __TDA8290_H__
+#define __TDA8290_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+struct tda8290_config
+{
+       unsigned int *lna_cfg;
+       int (*tuner_callback) (void *dev, int command,int arg);
+};
+
+#if defined(CONFIG_TUNER_TDA8290) || (defined(CONFIG_TUNER_TDA8290_MODULE) && defined(MODULE))
+extern int tda8290_probe(struct i2c_adapter* i2c_adap, u8 i2c_addr);
+
+extern struct dvb_frontend *tda8290_attach(struct dvb_frontend *fe,
+                                          struct i2c_adapter* i2c_adap,
+                                          u8 i2c_addr,
+                                          struct tda8290_config *cfg);
+#else
+static inline int tda8290_probe(struct i2c_adapter* i2c_adap, u8 i2c_addr)
+{
+       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
+              __FUNCTION__);
+       return -EINVAL;
+}
+
+static inline struct dvb_frontend *tda8290_attach(struct dvb_frontend *fe,
+                                                 struct i2c_adapter* i2c_adap,
+                                                 u8 i2c_addr,
+                                                 struct tda8290_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+       return NULL;
+}
+#endif
+
+#endif /* __TDA8290_H__ */
index a8f773274fe3f8188f0e7131f86f27fa74d0a24d..be5387f11afb3de8d3c71da946b65d9ce5f8cd0c 100644 (file)
@@ -1,14 +1,12 @@
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 #include <linux/types.h>
-#include <linux/videodev.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-
+#include <linux/videodev.h>
 #include <media/v4l2-common.h>
 #include <media/tuner.h>
 #include "tuner-driver.h"
@@ -31,6 +29,8 @@
                        i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
 
 struct tda9887_priv {
+       struct tuner_i2c_props i2c_props;
+
        unsigned char      data[4];
 };
 
@@ -97,6 +97,8 @@ struct tvnorm {
 #define cAudioIF_6_5             0x03    // bit e0:1
 
 
+#define cVideoIFMask           0x1c    // bit e2:4
+/* Video IF selection in TV Mode (bit B3=0) */
 #define cVideoIF_58_75           0x00    // bit e2:4
 #define cVideoIF_45_75           0x04    // bit e2:4
 #define cVideoIF_38_90           0x08    // bit e2:4
@@ -106,6 +108,13 @@ struct tvnorm {
 #define cRadioIF_45_75           0x18    // bit e2:4
 #define cRadioIF_38_90           0x1C    // bit e2:4
 
+/* IF1 selection in Radio Mode (bit B3=1) */
+#define cRadioIF_33_30         0x00    // bit e2,4 (also 0x10,0x14)
+#define cRadioIF_41_30         0x04    // bit e2,4
+
+/* Output of AFC pin in radio mode when bit E7=1 */
+#define cRadioAGC_SIF          0x00    // bit e3
+#define cRadioAGC_FM           0x08    // bit e3
 
 #define cTunerGainNormal         0x00    // bit e5
 #define cTunerGainLow            0x20    // bit e5
@@ -487,9 +496,13 @@ static int tda9887_set_config(struct tuner *t, char *buf)
        if (t->tda9887_config & TDA9887_GATING_18)
                buf[3] &= ~cGating_36;
 
-       if (t->tda9887_config & TDA9887_GAIN_NORMAL) {
-               radio_stereo.e &= ~cTunerGainLow;
-               radio_mono.e &= ~cTunerGainLow;
+       if (t->mode == V4L2_TUNER_RADIO) {
+               if (t->tda9887_config & TDA9887_RIF_41_3) {
+                       buf[3] &= ~cVideoIFMask;
+                       buf[3] |= cRadioIF_41_30;
+               }
+               if (t->tda9887_config & TDA9887_GAIN_NORMAL)
+                       buf[3] &= ~cTunerGainLow;
        }
 
        return 0;
@@ -499,19 +512,19 @@ static int tda9887_set_config(struct tuner *t, char *buf)
 
 static int tda9887_status(struct tuner *t)
 {
+       struct tda9887_priv *priv = t->priv;
        unsigned char buf[1];
        int rc;
 
        memset(buf,0,sizeof(buf));
-       if (1 != (rc = i2c_master_recv(&t->i2c,buf,1)))
+       if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,buf,1)))
                tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
        dump_read_message(t, buf);
        return 0;
 }
 
-static void tda9887_configure(struct i2c_client *client)
+static void tda9887_configure(struct tuner *t)
 {
-       struct tuner *t = i2c_get_clientdata(client);
        struct tda9887_priv *priv = t->priv;
        int rc;
 
@@ -546,7 +559,7 @@ static void tda9887_configure(struct i2c_client *client)
        if (tuner_debug > 1)
                dump_write_message(t, priv->data);
 
-       if (4 != (rc = i2c_master_send(&t->i2c,priv->data,4)))
+       if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,priv->data,4)))
                tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
 
        if (tuner_debug > 2) {
@@ -557,16 +570,15 @@ static void tda9887_configure(struct i2c_client *client)
 
 /* ---------------------------------------------------------------------- */
 
-static void tda9887_tuner_status(struct i2c_client *client)
+static void tda9887_tuner_status(struct tuner *t)
 {
-       struct tuner *t = i2c_get_clientdata(client);
        struct tda9887_priv *priv = t->priv;
        tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", priv->data[1], priv->data[2], priv->data[3]);
 }
 
-static int tda9887_get_afc(struct i2c_client *client)
+static int tda9887_get_afc(struct tuner *t)
 {
-       struct tuner *t = i2c_get_clientdata(client);
+       struct tda9887_priv *priv = t->priv;
        static int AFC_BITS_2_kHz[] = {
                -12500,  -37500,  -62500,  -97500,
                -112500, -137500, -162500, -187500,
@@ -576,26 +588,24 @@ static int tda9887_get_afc(struct i2c_client *client)
        int afc=0;
        __u8 reg = 0;
 
-       if (1 == i2c_master_recv(&t->i2c,&reg,1))
+       if (1 == tuner_i2c_xfer_recv(&priv->i2c_props,&reg,1))
                afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
 
        return afc;
 }
 
-static void tda9887_standby(struct i2c_client *client)
+static void tda9887_standby(struct tuner *t)
 {
-       tda9887_configure(client);
+       tda9887_configure(t);
 }
 
-static void tda9887_set_freq(struct i2c_client *client, unsigned int freq)
+static void tda9887_set_freq(struct tuner *t, unsigned int freq)
 {
-       tda9887_configure(client);
+       tda9887_configure(t);
 }
 
-static void tda9887_release(struct i2c_client *c)
+static void tda9887_release(struct tuner *t)
 {
-       struct tuner *t = i2c_get_clientdata(c);
-
        kfree(t->priv);
        t->priv = NULL;
 }
@@ -609,17 +619,19 @@ static struct tuner_operations tda9887_tuner_ops = {
        .release        = tda9887_release,
 };
 
-int tda9887_tuner_init(struct i2c_client *c)
+int tda9887_tuner_init(struct tuner *t)
 {
        struct tda9887_priv *priv = NULL;
-       struct tuner *t = i2c_get_clientdata(c);
 
        priv = kzalloc(sizeof(struct tda9887_priv), GFP_KERNEL);
        if (priv == NULL)
                return -ENOMEM;
        t->priv = priv;
 
-       strlcpy(c->name, "tda9887", sizeof(c->name));
+       priv->i2c_props.addr = t->i2c.addr;
+       priv->i2c_props.adap = t->i2c.adapter;
+
+       strlcpy(t->i2c.name, "tda9887", sizeof(t->i2c.name));
 
        tda9887_info("tda988[5/6/7] found @ 0x%x (%s)\n", t->i2c.addr,
                                                t->i2c.driver->driver.name);
index ae105c2cd0ac74609ef8ce83967d2d938bf871b5..2150222a3860537aacb11ceebd2e6dc074f73a1f 100644 (file)
@@ -8,15 +8,23 @@
  */
 
 #include <linux/i2c.h>
-#include <linux/videodev.h>
 #include <linux/delay.h>
+#include <linux/videodev.h>
 #include <media/tuner.h>
-#include "tuner-driver.h"
+#include "tuner-i2c.h"
+#include "tea5761.h"
 
-#define PREFIX "TEA5761 "
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
 
-/* from tuner-core.c */
-extern int tuner_debug;
+#define PREFIX "tea5761 "
+
+struct tea5761_priv {
+       struct tuner_i2c_props i2c_props;
+
+       u32 frequency;
+};
 
 /*****************************************************************************/
 
@@ -114,13 +122,6 @@ extern int tuner_debug;
 
 /*****************************************************************************/
 
-static void set_tv_freq(struct i2c_client *c, unsigned int freq)
-{
-       struct tuner *t = i2c_get_clientdata(c);
-
-       tuner_warn("This tuner doesn't support TV freq.\n");
-}
-
 #define FREQ_OFFSET 0 /* for TEA5767, it is 700 to give the right freq */
 static void tea5761_status_dump(unsigned char *buffer)
 {
@@ -135,16 +136,18 @@ static void tea5761_status_dump(unsigned char *buffer)
 }
 
 /* Freq should be specifyed at 62.5 Hz */
-static void set_radio_freq(struct i2c_client *c, unsigned int frq)
+static int set_radio_freq(struct dvb_frontend *fe,
+                         struct analog_parameters *params)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct tea5761_priv *priv = fe->tuner_priv;
+       unsigned int frq = params->frequency;
        unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 };
        unsigned div;
        int rc;
 
-       tuner_dbg (PREFIX "radio freq counter %d\n", frq);
+       tuner_dbg("radio freq counter %d\n", frq);
 
-       if (t->mode == T_STANDBY) {
+       if (params->mode == T_STANDBY) {
                tuner_dbg("TEA5761 set to standby mode\n");
                buffer[5] |= TEA5761_TNCTRL_MU;
        } else {
@@ -152,10 +155,9 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
        }
 
 
-       if (t->audmode == V4L2_TUNER_MODE_MONO) {
+       if (params->audmode == V4L2_TUNER_MODE_MONO) {
                tuner_dbg("TEA5761 set to mono\n");
                buffer[5] |= TEA5761_TNCTRL_MST;
-;
        } else {
                tuner_dbg("TEA5761 set to stereo\n");
        }
@@ -164,80 +166,155 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
        buffer[1] = (div >> 8) & 0x3f;
        buffer[2] = div & 0xff;
 
-       if (tuner_debug)
+       if (debug)
                tea5761_status_dump(buffer);
 
-       if (7 != (rc = i2c_master_send(c, buffer, 7)))
+       if (7 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 7)))
                tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+
+       priv->frequency = frq * 125 / 2;
+
+       return 0;
 }
 
-static int tea5761_signal(struct i2c_client *c)
+static int tea5761_read_status(struct dvb_frontend *fe, char *buffer)
 {
-       unsigned char buffer[16];
+       struct tea5761_priv *priv = fe->tuner_priv;
        int rc;
-       struct tuner *t = i2c_get_clientdata(c);
 
-       memset(buffer, 0, sizeof(buffer));
-       if (16 != (rc = i2c_master_recv(c, buffer, 16)))
-               tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+       memset(buffer, 0, 16);
+       if (16 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 16))) {
+               tuner_warn("i2c i/o error: rc == %d (should be 16)\n", rc);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static inline int tea5761_signal(struct dvb_frontend *fe, const char *buffer)
+{
+       struct tea5761_priv *priv = fe->tuner_priv;
+
+       int signal = ((buffer[9] & TEA5761_TUNCHECK_LEV_MASK) << (13 - 4));
+
+       tuner_dbg("Signal strength: %d\n", signal);
+
+       return signal;
+}
+
+static inline int tea5761_stereo(struct dvb_frontend *fe, const char *buffer)
+{
+       struct tea5761_priv *priv = fe->tuner_priv;
+
+       int stereo = buffer[9] & TEA5761_TUNCHECK_STEREO;
 
-       return ((buffer[9] & TEA5761_TUNCHECK_LEV_MASK) << (13 - 4));
+       tuner_dbg("Radio ST GET = %02x\n", stereo);
+
+       return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
 }
 
-static int tea5761_stereo(struct i2c_client *c)
+static int tea5761_get_status(struct dvb_frontend *fe, u32 *status)
 {
        unsigned char buffer[16];
-       int rc;
-       struct tuner *t = i2c_get_clientdata(c);
 
-       memset(buffer, 0, sizeof(buffer));
-       if (16 != (rc = i2c_master_recv(c, buffer, 16)))
-               tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+       *status = 0;
+
+       if (0 == tea5761_read_status(fe, buffer)) {
+               if (tea5761_signal(fe, buffer))
+                       *status = TUNER_STATUS_LOCKED;
+               if (tea5761_stereo(fe, buffer))
+                       *status |= TUNER_STATUS_STEREO;
+       }
+
+       return 0;
+}
+
+static int tea5761_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       unsigned char buffer[16];
 
-       rc = buffer[9] & TEA5761_TUNCHECK_STEREO;
+       *strength = 0;
 
-       tuner_dbg("TEA5761 radio ST GET = %02x\n", rc);
+       if (0 == tea5761_read_status(fe, buffer))
+               *strength = tea5761_signal(fe, buffer);
 
-       return (rc ? V4L2_TUNER_SUB_STEREO : 0);
+       return 0;
 }
 
-int tea5761_autodetection(struct i2c_client *c)
+int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
 {
        unsigned char buffer[16];
        int rc;
-       struct tuner *t = i2c_get_clientdata(c);
+       struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr };
 
-       if (16 != (rc = i2c_master_recv(c, buffer, 16))) {
-               tuner_warn("it is not a TEA5761. Received %i chars.\n", rc);
+       if (16 != (rc = tuner_i2c_xfer_recv(&i2c, buffer, 16))) {
+               printk(KERN_WARNING "it is not a TEA5761. Received %i chars.\n", rc);
                return EINVAL;
        }
 
        if (!((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061))) {
-               tuner_warn("Manufacturer ID= 0x%02x, Chip ID = %02x%02x. It is not a TEA5761\n",buffer[13],buffer[14],buffer[15]);
+               printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x. It is not a TEA5761\n",buffer[13],buffer[14],buffer[15]);
                return EINVAL;
        }
-       tuner_warn("TEA5761 detected.\n");
+       printk(KERN_WARNING "TEA5761 detected.\n");
        return 0;
 }
 
-static struct tuner_operations tea5761_tuner_ops = {
-       .set_tv_freq    = set_tv_freq,
-       .set_radio_freq = set_radio_freq,
-       .has_signal     = tea5761_signal,
-       .is_stereo      = tea5761_stereo,
+static int tea5761_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int tea5761_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tea5761_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static struct dvb_tuner_ops tea5761_tuner_ops = {
+       .info = {
+               .name           = "tea5761", // Philips TEA5761HN FM Radio
+       },
+       .set_analog_params = set_radio_freq,
+       .release           = tea5761_release,
+       .get_frequency     = tea5761_get_frequency,
+       .get_status        = tea5761_get_status,
+       .get_rf_strength   = tea5761_get_rf_strength,
 };
 
-int tea5761_tuner_init(struct i2c_client *c)
+struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter* i2c_adap,
+                                   u8 i2c_addr)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct tea5761_priv *priv = NULL;
 
-       if (tea5761_autodetection(c) == EINVAL)
-               return EINVAL;
+       if (tea5761_autodetection(i2c_adap, i2c_addr) == EINVAL)
+               return NULL;
+
+       priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+       fe->tuner_priv = priv;
+
+       priv->i2c_props.addr = i2c_addr;
+       priv->i2c_props.adap = i2c_adap;
 
-       tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5761HN FM Radio");
-       strlcpy(c->name, "tea5761", sizeof(c->name));
+       memcpy(&fe->ops.tuner_ops, &tea5761_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
 
-       memcpy(&t->ops, &tea5761_tuner_ops, sizeof(struct tuner_operations));
+       tuner_info("type set to %s\n", "Philips TEA5761HN FM Radio");
 
-       return (0);
+       return fe;
 }
+
+
+EXPORT_SYMBOL_GPL(tea5761_attach);
+EXPORT_SYMBOL_GPL(tea5761_autodetection);
+
+MODULE_DESCRIPTION("Philips TEA5761 FM tuner driver");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tea5761.h b/drivers/media/video/tea5761.h
new file mode 100644 (file)
index 0000000..73a03b4
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __TEA5761_H__
+#define __TEA5761_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+#if defined(CONFIG_TUNER_TEA5761) || (defined(CONFIG_TUNER_TEA5761_MODULE) && defined(MODULE))
+extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
+
+extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
+                                          struct i2c_adapter* i2c_adap,
+                                          u8 i2c_addr);
+#else
+static inline int tea5761_autodetection(struct i2c_adapter* i2c_adap,
+                                       u8 i2c_addr)
+{
+       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
+              __FUNCTION__);
+       return -EINVAL;
+}
+
+static inline struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
+                                                  struct i2c_adapter* i2c_adap,
+                                                  u8 i2c_addr)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+       return NULL;
+}
+#endif
+
+#endif /* __TEA5761_H__ */
index 4985d47a508f7465b5840debe71e0324d71a3c6e..71df419df7bc85b7c867fc27f593a72b1ee5bae2 100644 (file)
  */
 
 #include <linux/i2c.h>
-#include <linux/videodev.h>
 #include <linux/delay.h>
-#include "tuner-driver.h"
+#include <linux/videodev.h>
+#include "tuner-i2c.h"
+#include "tea5767.h"
 
-#define PREFIX "TEA5767 "
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
 
-/* from tuner-core.c */
-extern int tuner_debug;
+#define PREFIX "tea5767 "
+
+struct tea5767_priv {
+       struct tuner_i2c_props i2c_props;
+
+       u32 frequency;
+};
 
 /*****************************************************************************/
 
@@ -129,13 +137,6 @@ enum tea5767_xtal_freq {
 
 /*****************************************************************************/
 
-static void set_tv_freq(struct i2c_client *c, unsigned int freq)
-{
-       struct tuner *t = i2c_get_clientdata(c);
-
-       tuner_warn("This tuner doesn't support TV freq.\n");
-}
-
 static void tea5767_status_dump(unsigned char *buffer)
 {
        unsigned int div, frq;
@@ -190,14 +191,16 @@ static void tea5767_status_dump(unsigned char *buffer)
 }
 
 /* Freq should be specifyed at 62.5 Hz */
-static void set_radio_freq(struct i2c_client *c, unsigned int frq)
+static int set_radio_freq(struct dvb_frontend *fe,
+                         struct analog_parameters *params)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct tea5767_priv *priv = fe->tuner_priv;
+       unsigned int frq = params->frequency;
        unsigned char buffer[5];
        unsigned div;
        int rc;
 
-       tuner_dbg (PREFIX "radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000);
+       tuner_dbg("radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000);
 
        /* Rounds freq to next decimal value - for 62.5 KHz step */
        /* frq = 20*(frq/16)+radio_frq[frq%16]; */
@@ -207,7 +210,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
                    TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND;
        buffer[4] = 0;
 
-       if (t->audmode == V4L2_TUNER_MODE_MONO) {
+       if (params->audmode == V4L2_TUNER_MODE_MONO) {
                tuner_dbg("TEA5767 set to mono\n");
                buffer[2] |= TEA5767_MONO;
        } else {
@@ -217,26 +220,26 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
        /* Should be replaced */
        switch (TEA5767_HIGH_LO_32768) {
        case TEA5767_HIGH_LO_13MHz:
-               tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
+               tuner_dbg("radio HIGH LO inject xtal @ 13 MHz\n");
                buffer[2] |= TEA5767_HIGH_LO_INJECT;
                buffer[4] |= TEA5767_PLLREF_ENABLE;
                div = (frq * (4000 / 16) + 700000 + 225000 + 25000) / 50000;
                break;
        case TEA5767_LOW_LO_13MHz:
-               tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
+               tuner_dbg("radio LOW LO inject xtal @ 13 MHz\n");
 
                buffer[4] |= TEA5767_PLLREF_ENABLE;
                div = (frq * (4000 / 16) - 700000 - 225000 + 25000) / 50000;
                break;
        case TEA5767_LOW_LO_32768:
-               tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
+               tuner_dbg("radio LOW LO inject xtal @ 32,768 MHz\n");
                buffer[3] |= TEA5767_XTAL_32768;
                /* const 700=4000*175 Khz - to adjust freq to right value */
                div = ((frq * (4000 / 16) - 700000 - 225000) + 16384) >> 15;
                break;
        case TEA5767_HIGH_LO_32768:
        default:
-               tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n");
+               tuner_dbg("radio HIGH LO inject xtal @ 32,768 MHz\n");
 
                buffer[2] |= TEA5767_HIGH_LO_INJECT;
                buffer[3] |= TEA5767_XTAL_32768;
@@ -246,51 +249,89 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq)
        buffer[0] = (div >> 8) & 0x3f;
        buffer[1] = div & 0xff;
 
-       if (5 != (rc = i2c_master_send(c, buffer, 5)))
+       if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
                tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
 
-       if (tuner_debug) {
-               if (5 != (rc = i2c_master_recv(c, buffer, 5)))
+       if (debug) {
+               if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5)))
                        tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
                else
                        tea5767_status_dump(buffer);
        }
+
+       priv->frequency = frq * 125 / 2;
+
+       return 0;
 }
 
-static int tea5767_signal(struct i2c_client *c)
+static int tea5767_read_status(struct dvb_frontend *fe, char *buffer)
 {
-       unsigned char buffer[5];
+       struct tea5767_priv *priv = fe->tuner_priv;
        int rc;
-       struct tuner *t = i2c_get_clientdata(c);
 
-       memset(buffer, 0, sizeof(buffer));
-       if (5 != (rc = i2c_master_recv(c, buffer, 5)))
+       memset(buffer, 0, 5);
+       if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5))) {
                tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+               return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static inline int tea5767_signal(struct dvb_frontend *fe, const char *buffer)
+{
+       struct tea5767_priv *priv = fe->tuner_priv;
+
+       int signal = ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
+
+       tuner_dbg("Signal strength: %d\n", signal);
+
+       return signal;
+}
+
+static inline int tea5767_stereo(struct dvb_frontend *fe, const char *buffer)
+{
+       struct tea5767_priv *priv = fe->tuner_priv;
+
+       int stereo = buffer[2] & TEA5767_STEREO_MASK;
+
+       tuner_dbg("Radio ST GET = %02x\n", stereo);
 
-       return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
+       return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
 }
 
-static int tea5767_stereo(struct i2c_client *c)
+static int tea5767_get_status(struct dvb_frontend *fe, u32 *status)
 {
        unsigned char buffer[5];
-       int rc;
-       struct tuner *t = i2c_get_clientdata(c);
 
-       memset(buffer, 0, sizeof(buffer));
-       if (5 != (rc = i2c_master_recv(c, buffer, 5)))
-               tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+       *status = 0;
+
+       if (0 == tea5767_read_status(fe, buffer)) {
+               if (tea5767_signal(fe, buffer))
+                       *status = TUNER_STATUS_LOCKED;
+               if (tea5767_stereo(fe, buffer))
+                       *status |= TUNER_STATUS_STEREO;
+       }
+
+       return 0;
+}
 
-       rc = buffer[2] & TEA5767_STEREO_MASK;
+static int tea5767_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       unsigned char buffer[5];
 
-       tuner_dbg("TEA5767 radio ST GET = %02x\n", rc);
+       *strength = 0;
 
-       return ((buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO : 0);
+       if (0 == tea5767_read_status(fe, buffer))
+               *strength = tea5767_signal(fe, buffer);
+
+       return 0;
 }
 
-static void tea5767_standby(struct i2c_client *c)
+static int tea5767_standby(struct dvb_frontend *fe)
 {
        unsigned char buffer[5];
-       struct tuner *t = i2c_get_clientdata(c);
+       struct tea5767_priv *priv = fe->tuner_priv;
        unsigned div, rc;
 
        div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */
@@ -301,25 +342,27 @@ static void tea5767_standby(struct i2c_client *c)
                    TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY;
        buffer[4] = 0;
 
-       if (5 != (rc = i2c_master_send(c, buffer, 5)))
+       if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
                tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+
+       return 0;
 }
 
-int tea5767_autodetection(struct i2c_client *c)
+int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
 {
+       struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr };
        unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
        int rc;
-       struct tuner *t = i2c_get_clientdata(c);
 
-       if ((rc = i2c_master_recv(c, buffer, 7))< 5) {
-               tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc);
+       if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) {
+               printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc);
                return EINVAL;
        }
 
        /* If all bytes are the same then it's a TV tuner and not a tea5767 */
        if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
            buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
-               tuner_warn("All bytes are equal. It is not a TEA5767\n");
+               printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n");
                return EINVAL;
        }
 
@@ -329,36 +372,74 @@ int tea5767_autodetection(struct i2c_client *c)
         *  Byte 5: bit 7:0 : == 0
         */
        if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
-               tuner_warn("Chip ID is not zero. It is not a TEA5767\n");
+               printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n");
                return EINVAL;
        }
 
        /* It seems that tea5767 returns 0xff after the 5th byte */
        if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) {
-               tuner_warn("Returned more than 5 bytes. It is not a TEA5767\n");
+               printk(KERN_WARNING "Returned more than 5 bytes. It is not a TEA5767\n");
                return EINVAL;
        }
 
-       tuner_warn("TEA5767 detected.\n");
+       printk(KERN_WARNING "TEA5767 detected.\n");
        return 0;
 }
 
-static struct tuner_operations tea5767_tuner_ops = {
-       .set_tv_freq    = set_tv_freq,
-       .set_radio_freq = set_radio_freq,
-       .has_signal     = tea5767_signal,
-       .is_stereo      = tea5767_stereo,
-       .standby        = tea5767_standby,
+static int tea5767_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int tea5767_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tea5767_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static struct dvb_tuner_ops tea5767_tuner_ops = {
+       .info = {
+               .name           = "tea5767", // Philips TEA5767HN FM Radio
+       },
+
+       .set_analog_params = set_radio_freq,
+       .sleep             = tea5767_standby,
+       .release           = tea5767_release,
+       .get_frequency     = tea5767_get_frequency,
+       .get_status        = tea5767_get_status,
+       .get_rf_strength   = tea5767_get_rf_strength,
 };
 
-int tea5767_tuner_init(struct i2c_client *c)
+struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
+                                   struct i2c_adapter* i2c_adap,
+                                   u8 i2c_addr)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct tea5767_priv *priv = NULL;
+
+       priv = kzalloc(sizeof(struct tea5767_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+       fe->tuner_priv = priv;
+
+       priv->i2c_props.addr = i2c_addr;
+       priv->i2c_props.adap = i2c_adap;
 
-       tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio");
-       strlcpy(c->name, "tea5767", sizeof(c->name));
+       memcpy(&fe->ops.tuner_ops, &tea5767_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
 
-       memcpy(&t->ops, &tea5767_tuner_ops, sizeof(struct tuner_operations));
+       tuner_info("type set to %s\n", "Philips TEA5767HN FM Radio");
 
-       return (0);
+       return fe;
 }
+
+
+EXPORT_SYMBOL_GPL(tea5767_attach);
+EXPORT_SYMBOL_GPL(tea5767_autodetection);
+
+MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tea5767.h b/drivers/media/video/tea5767.h
new file mode 100644 (file)
index 0000000..5d78281
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __TEA5767_H__
+#define __TEA5767_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+#if defined(CONFIG_TUNER_TEA5767) || (defined(CONFIG_TUNER_TEA5767_MODULE) && defined(MODULE))
+extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
+
+extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
+                                          struct i2c_adapter* i2c_adap,
+                                          u8 i2c_addr);
+#else
+static inline int tea5767_autodetection(struct i2c_adapter* i2c_adap,
+                                       u8 i2c_addr)
+{
+       printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
+              __FUNCTION__);
+       return -EINVAL;
+}
+
+static inline struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
+                                                  struct i2c_adapter* i2c_adap,
+                                                  u8 i2c_addr)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+       return NULL;
+}
+#endif
+
+#endif /* __TEA5767_H__ */
index e646465464a1e8c7e29a63823fac88fa14b478b1..94843086cda90f41f32e2b876b23b0e63908abb9 100644 (file)
@@ -5,7 +5,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/poll.h>
 #include <linux/i2c.h>
 #include <linux/types.h>
-#include <linux/videodev.h>
 #include <linux/init.h>
-
+#include <linux/videodev.h>
 #include <media/tuner.h>
+#include <media/tuner-types.h>
 #include <media/v4l2-common.h>
 #include "tuner-driver.h"
+#include "mt20xx.h"
+#include "tda8290.h"
+#include "tea5761.h"
+#include "tea5767.h"
+#include "tuner-simple.h"
 
 #define UNSET (-1U)
 
@@ -72,6 +76,51 @@ static struct i2c_client client_template;
 
 /* ---------------------------------------------------------------------- */
 
+static void fe_set_freq(struct tuner *t, unsigned int freq)
+{
+       struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
+
+       struct analog_parameters params = {
+               .frequency = freq,
+               .mode      = t->mode,
+               .audmode   = t->audmode,
+               .std       = t->std
+       };
+
+       if (NULL == fe_tuner_ops->set_analog_params) {
+               tuner_warn("Tuner frontend module has no way to set freq\n");
+               return;
+       }
+       fe_tuner_ops->set_analog_params(&t->fe, &params);
+}
+
+static void fe_release(struct tuner *t)
+{
+       struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
+
+       if (fe_tuner_ops->release)
+               fe_tuner_ops->release(&t->fe);
+}
+
+static void fe_standby(struct tuner *t)
+{
+       struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
+
+       if (fe_tuner_ops->sleep)
+               fe_tuner_ops->sleep(&t->fe);
+}
+
+static int fe_has_signal(struct tuner *t)
+{
+       struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
+       u16 strength;
+
+       if (fe_tuner_ops->get_rf_strength)
+               fe_tuner_ops->get_rf_strength(&t->fe, &strength);
+
+       return strength;
+}
+
 /* Set tuner frequency,  freq in Units of 62.5kHz = 1/16MHz */
 static void set_tv_freq(struct i2c_client *c, unsigned int freq)
 {
@@ -96,7 +145,7 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
                else
                        freq = tv_range[1] * 16;
        }
-       t->ops.set_tv_freq(c, freq);
+       t->ops.set_tv_freq(t, freq);
 }
 
 static void set_radio_freq(struct i2c_client *c, unsigned int freq)
@@ -123,7 +172,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
                        freq = radio_range[1] * 16000;
        }
 
-       t->ops.set_radio_freq(c, freq);
+       t->ops.set_radio_freq(t, freq);
 }
 
 static void set_freq(struct i2c_client *c, unsigned long freq)
@@ -147,11 +196,51 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
        }
 }
 
+static void tuner_i2c_address_check(struct tuner *t)
+{
+       if ((t->type == UNSET || t->type == TUNER_ABSENT) ||
+           ((t->i2c.addr < 0x64) || (t->i2c.addr > 0x6f)))
+               return;
+
+       tuner_warn("====================== WARNING! ======================\n");
+       tuner_warn("Support for tuners in i2c address range 0x64 thru 0x6f\n");
+       tuner_warn("will soon be dropped. This message indicates that your\n");
+       tuner_warn("hardware has a %s tuner at i2c address 0x%02x.\n",
+                  t->i2c.name, t->i2c.addr);
+       tuner_warn("To ensure continued support for your device, please\n");
+       tuner_warn("send a copy of this message, along with full dmesg\n");
+       tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n");
+       tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n");
+       tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n",
+                  t->i2c.adapter->name, t->i2c.addr, t->type,
+                  tuners[t->type].name);
+       tuner_warn("====================== WARNING! ======================\n");
+}
+
+static void attach_tda8290(struct tuner *t)
+{
+       struct tda8290_config cfg = {
+               .lna_cfg        = &t->config,
+               .tuner_callback = t->tuner_callback
+       };
+       tda8290_attach(&t->fe, t->i2c.adapter, t->i2c.addr, &cfg);
+}
+
+static void attach_simple_tuner(struct tuner *t)
+{
+       struct simple_tuner_config cfg = {
+               .type = t->type,
+               .tun  = &tuners[t->type]
+       };
+       simple_tuner_attach(&t->fe, t->i2c.adapter, t->i2c.addr, &cfg);
+}
+
 static void set_type(struct i2c_client *c, unsigned int type,
                     unsigned int new_mode_mask, unsigned int new_config,
                     int (*tuner_callback) (void *dev, int command,int arg))
 {
        struct tuner *t = i2c_get_clientdata(c);
+       struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
        unsigned char buffer[4];
 
        if (type == UNSET || type == TUNER_ABSENT) {
@@ -180,7 +269,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
 
        /* discard private data, in case set_type() was previously called */
        if (t->ops.release)
-               t->ops.release(c);
+               t->ops.release(t);
        else {
                kfree(t->priv);
                t->priv = NULL;
@@ -188,13 +277,15 @@ static void set_type(struct i2c_client *c, unsigned int type,
 
        switch (t->type) {
        case TUNER_MT2032:
-               microtune_init(c);
+               microtune_attach(&t->fe, t->i2c.adapter, t->i2c.addr);
                break;
        case TUNER_PHILIPS_TDA8290:
-               tda8290_init(c);
+       {
+               attach_tda8290(t);
                break;
+       }
        case TUNER_TEA5767:
-               if (tea5767_tuner_init(c) == EINVAL) {
+               if (tea5767_attach(&t->fe, t->i2c.adapter, t->i2c.addr) == NULL) {
                        t->type = TUNER_ABSENT;
                        t->mode_mask = T_UNINITIALIZED;
                        return;
@@ -203,7 +294,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
                break;
 #ifdef CONFIG_TUNER_TEA5761
        case TUNER_TEA5761:
-               if (tea5761_tuner_init(c) == EINVAL) {
+               if (tea5761_attach(&t->fe, t->i2c.adapter, t->i2c.addr) == NULL) {
                        t->type = TUNER_ABSENT;
                        t->mode_mask = T_UNINITIALIZED;
                        return;
@@ -221,7 +312,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
                buffer[2] = 0x86;
                buffer[3] = 0x54;
                i2c_master_send(c, buffer, 4);
-               default_tuner_init(c);
+               attach_simple_tuner(t);
                break;
        case TUNER_PHILIPS_TD1316:
                buffer[0] = 0x0b;
@@ -229,16 +320,28 @@ static void set_type(struct i2c_client *c, unsigned int type,
                buffer[2] = 0x86;
                buffer[3] = 0xa4;
                i2c_master_send(c,buffer,4);
-               default_tuner_init(c);
+               attach_simple_tuner(t);
                break;
        case TUNER_TDA9887:
-               tda9887_tuner_init(c);
+               tda9887_tuner_init(t);
                break;
        default:
-               default_tuner_init(c);
+               attach_simple_tuner(t);
                break;
        }
 
+       if (fe_tuner_ops->set_analog_params) {
+               strlcpy(t->i2c.name, fe_tuner_ops->info.name, sizeof(t->i2c.name));
+
+               t->ops.set_tv_freq    = fe_set_freq;
+               t->ops.set_radio_freq = fe_set_freq;
+               t->ops.standby        = fe_standby;
+               t->ops.release        = fe_release;
+               t->ops.has_signal     = fe_has_signal;
+       }
+
+       tuner_info("type set to %s\n", t->i2c.name);
+
        if (t->mode_mask == T_UNINITIALIZED)
                t->mode_mask = new_mode_mask;
 
@@ -246,6 +349,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
        tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
                  c->adapter->name, c->driver->driver.name, c->addr << 1, type,
                  t->mode_mask);
+       tuner_i2c_address_check(t);
 }
 
 /*
@@ -406,10 +510,10 @@ static int tuner_fixup_std(struct tuner *t)
        return 0;
 }
 
-static void tuner_status(struct i2c_client *client)
+static void tuner_status(struct tuner *t)
 {
-       struct tuner *t = i2c_get_clientdata(client);
        unsigned long freq, freq_fraction;
+       struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
        const char *p;
 
        switch (t->mode) {
@@ -430,11 +534,20 @@ static void tuner_status(struct i2c_client *client)
        tuner_info("Standard:        0x%08lx\n", (unsigned long)t->std);
        if (t->mode != V4L2_TUNER_RADIO)
               return;
+       if (fe_tuner_ops->get_status) {
+               u32 tuner_status;
+
+               fe_tuner_ops->get_status(&t->fe, &tuner_status);
+               if (tuner_status & TUNER_STATUS_LOCKED)
+                       tuner_info("Tuner is locked.\n");
+               if (tuner_status & TUNER_STATUS_STEREO)
+                       tuner_info("Stereo:          yes\n");
+       }
        if (t->ops.has_signal) {
-               tuner_info("Signal strength: %d\n", t->ops.has_signal(client));
+               tuner_info("Signal strength: %d\n", t->ops.has_signal(t));
        }
        if (t->ops.is_stereo) {
-               tuner_info("Stereo:          %s\n", t->ops.is_stereo(client) ? "yes" : "no");
+               tuner_info("Stereo:          %s\n", t->ops.is_stereo(t) ? "yes" : "no");
        }
 }
 
@@ -483,7 +596,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
                switch (addr) {
 #ifdef CONFIG_TUNER_TEA5761
                case 0x10:
-                       if (tea5761_autodetection(&t->i2c) != EINVAL) {
+                       if (tea5761_autodetection(t->i2c.adapter, t->i2c.addr) != EINVAL) {
                                t->type = TUNER_TEA5761;
                                t->mode_mask = T_RADIO;
                                t->mode = T_STANDBY;
@@ -500,7 +613,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
                case 0x4b:
                        /* If chip is not tda8290, don't register.
                           since it can be tda9887*/
-                       if (tda8290_probe(&t->i2c) == 0) {
+                       if (tda8290_probe(t->i2c.adapter, t->i2c.addr) == 0) {
                                tuner_dbg("chip at addr %x is a tda8290\n", addr);
                        } else {
                                /* Default is being tda9887 */
@@ -511,7 +624,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
                        }
                        break;
                case 0x60:
-                       if (tea5767_autodetection(&t->i2c) != EINVAL) {
+                       if (tea5767_autodetection(t->i2c.adapter, t->i2c.addr) != EINVAL) {
                                t->type = TUNER_TEA5767;
                                t->mode_mask = T_RADIO;
                                t->mode = T_STANDBY;
@@ -548,6 +661,28 @@ static int tuner_probe(struct i2c_adapter *adap)
                normal_i2c[1] = I2C_CLIENT_END;
        }
 
+       /* HACK: Ignore 0x6b and 0x6f on cx88 boards.
+        * FusionHDTV5 RT Gold has an ir receiver at 0x6b
+        * and an RTC at 0x6f which can get corrupted if probed.
+        */
+       if ((adap->id == I2C_HW_B_CX2388x) ||
+           (adap->id == I2C_HW_B_CX23885)) {
+               unsigned int i = 0;
+
+               while (i < I2C_CLIENT_MAX_OPTS && ignore[i] != I2C_CLIENT_END)
+                       i += 2;
+               if (i + 4 < I2C_CLIENT_MAX_OPTS) {
+                       ignore[i+0] = adap->nr;
+                       ignore[i+1] = 0x6b;
+                       ignore[i+2] = adap->nr;
+                       ignore[i+3] = 0x6f;
+                       ignore[i+4] = I2C_CLIENT_END;
+               } else
+                       printk(KERN_WARNING "tuner: "
+                              "too many options specified "
+                              "in i2c probe ignore list!\n");
+       }
+
        default_mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
 
        if (adap->class & I2C_CLASS_TV_ANALOG)
@@ -568,7 +703,7 @@ static int tuner_detach(struct i2c_client *client)
        }
 
        if (t->ops.release)
-               t->ops.release(client);
+               t->ops.release(t);
        else {
                kfree(t->priv);
        }
@@ -593,7 +728,7 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode,
        if (check_mode(t, cmd) == EINVAL) {
                t->mode = T_STANDBY;
                if (t->ops.standby)
-                       t->ops.standby (client);
+                       t->ops.standby(t);
                return EINVAL;
        }
        return 0;
@@ -615,6 +750,7 @@ static inline int check_v4l2(struct tuner *t)
 static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
        struct tuner *t = i2c_get_clientdata(client);
+       struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
 
        if (tuner_debug>1)
                v4l_i2c_print_ioctl(&(t->i2c),cmd);
@@ -642,7 +778,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                        return 0;
                t->mode = T_STANDBY;
                if (t->ops.standby)
-                       t->ops.standby (client);
+                       t->ops.standby(t);
                break;
 #ifdef CONFIG_VIDEO_V4L1
        case VIDIOCSAUDIO:
@@ -701,16 +837,27 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                                return 0;
 
                        if (V4L2_TUNER_RADIO == t->mode) {
-                               if (t->ops.has_signal)
-                                       vt->signal = t->ops.has_signal(client);
-                               if (t->ops.is_stereo) {
-                                       if (t->ops.is_stereo(client))
-                                               vt->flags |=
-                                                   VIDEO_TUNER_STEREO_ON;
+                               if (fe_tuner_ops->get_status) {
+                                       u32 tuner_status;
+
+                                       fe_tuner_ops->get_status(&t->fe, &tuner_status);
+                                       if (tuner_status & TUNER_STATUS_STEREO)
+                                               vt->flags |= VIDEO_TUNER_STEREO_ON;
                                        else
-                                               vt->flags &=
-                                                   ~VIDEO_TUNER_STEREO_ON;
+                                               vt->flags &= ~VIDEO_TUNER_STEREO_ON;
+                               } else {
+                                       if (t->ops.is_stereo) {
+                                               if (t->ops.is_stereo(t))
+                                                       vt->flags |=
+                                                               VIDEO_TUNER_STEREO_ON;
+                                               else
+                                                       vt->flags &=
+                                                               ~VIDEO_TUNER_STEREO_ON;
+                                       }
                                }
+                               if (t->ops.has_signal)
+                                       vt->signal = t->ops.has_signal(t);
+
                                vt->flags |= VIDEO_TUNER_LOW;   /* Allow freqs at 62.5 Hz */
 
                                vt->rangelow = radio_range[0] * 16000;
@@ -732,9 +879,17 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                        if (check_v4l2(t) == EINVAL)
                                return 0;
 
-                       if (V4L2_TUNER_RADIO == t->mode && t->ops.is_stereo)
-                               va->mode = t->ops.is_stereo(client)
-                                   ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
+                       if (V4L2_TUNER_RADIO == t->mode) {
+                               if (fe_tuner_ops->get_status) {
+                                       u32 tuner_status;
+
+                                       fe_tuner_ops->get_status(&t->fe, &tuner_status);
+                                       va->mode = (tuner_status & TUNER_STATUS_STEREO)
+                                           ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
+                               } else if (t->ops.is_stereo)
+                                       va->mode = t->ops.is_stereo(t)
+                                           ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
+                       }
                        return 0;
                }
 #endif
@@ -785,6 +940,15 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                                return 0;
                        switch_v4l2();
                        f->type = t->mode;
+                       if (fe_tuner_ops->get_frequency) {
+                               u32 abs_freq;
+
+                               fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
+                               f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
+                                       (abs_freq * 2 + 125/2) / 125 :
+                                       (abs_freq + 62500/2) / 62500;
+                               break;
+                       }
                        f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
                                t->radio_freq : t->tv_freq;
                        break;
@@ -799,7 +963,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
 
                        tuner->type = t->mode;
                        if (t->ops.get_afc)
-                               tuner->afc=t->ops.get_afc(client);
+                               tuner->afc=t->ops.get_afc(t);
                        if (t->mode == V4L2_TUNER_ANALOG_TV)
                                tuner->capability |= V4L2_TUNER_CAP_NORM;
                        if (t->mode != V4L2_TUNER_RADIO) {
@@ -809,16 +973,22 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                        }
 
                        /* radio mode */
-                       if (t->ops.has_signal)
-                               tuner->signal = t->ops.has_signal(client);
-
                        tuner->rxsubchans =
                                V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-                       if (t->ops.is_stereo) {
-                               tuner->rxsubchans = t->ops.is_stereo(client) ?
+                       if (fe_tuner_ops->get_status) {
+                               u32 tuner_status;
+
+                               fe_tuner_ops->get_status(&t->fe, &tuner_status);
+                               tuner->rxsubchans = (tuner_status & TUNER_STATUS_STEREO) ?
                                        V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
+                       } else {
+                               if (t->ops.is_stereo) {
+                                       tuner->rxsubchans = t->ops.is_stereo(t) ?
+                                               V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
+                               }
                        }
-
+                       if (t->ops.has_signal)
+                               tuner->signal = t->ops.has_signal(t);
                        tuner->capability |=
                            V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
                        tuner->audmode = t->audmode;
@@ -844,7 +1014,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                }
        case VIDIOC_LOG_STATUS:
                if (t->ops.tuner_status)
-                       t->ops.tuner_status(client);
+                       t->ops.tuner_status(t);
                break;
        }
 
index 0334a9125077939d859989649491487e90391f42..28a10da76d12958b790973cf51e0e2592d9f85bf 100644 (file)
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#ifndef __TUNER_HW_H__
-#define __TUNER_HW_H__
+#ifndef __TUNER_DRIVER_H__
+#define __TUNER_DRIVER_H__
 
 #include <linux/videodev2.h>
 #include <linux/i2c.h>
+#include "tuner-i2c.h"
+#include "dvb_frontend.h"
 
 extern unsigned const int tuner_count;
 
+struct tuner;
+
 struct tuner_operations {
-       void (*set_tv_freq)(struct i2c_client *c, unsigned int freq);
-       void (*set_radio_freq)(struct i2c_client *c, unsigned int freq);
-       int  (*has_signal)(struct i2c_client *c);
-       int  (*is_stereo)(struct i2c_client *c);
-       int  (*get_afc)(struct i2c_client *c);
-       void (*tuner_status)(struct i2c_client *c);
-       void (*standby)(struct i2c_client *c);
-       void (*release)(struct i2c_client *c);
+       void (*set_tv_freq)(struct tuner *t, unsigned int freq);
+       void (*set_radio_freq)(struct tuner *t, unsigned int freq);
+       int  (*has_signal)(struct tuner *t);
+       int  (*is_stereo)(struct tuner *t);
+       int  (*get_afc)(struct tuner *t);
+       void (*tuner_status)(struct tuner *t);
+       void (*standby)(struct tuner *t);
+       void (*release)(struct tuner *t);
 };
 
 struct tuner {
@@ -49,13 +53,14 @@ struct tuner {
 
        unsigned int tv_freq;   /* keep track of the current settings */
        unsigned int radio_freq;
-       u16          last_div;
        unsigned int audmode;
        v4l2_std_id  std;
 
        int          using_v4l2;
        void *priv;
 
+       struct dvb_frontend fe;
+
        /* used by tda9887 */
        unsigned int       tda9887_config;
 
@@ -67,20 +72,7 @@ struct tuner {
 
 /* ------------------------------------------------------------------------ */
 
-extern int default_tuner_init(struct i2c_client *c);
-
-extern int tda9887_tuner_init(struct i2c_client *c);
-
-extern int microtune_init(struct i2c_client *c);
-
-extern int tda8290_init(struct i2c_client *c);
-extern int tda8290_probe(struct i2c_client *c);
-
-extern int tea5761_tuner_init(struct i2c_client *c);
-extern int tea5761_autodetection(struct i2c_client *c);
-
-extern int tea5767_autodetection(struct i2c_client *c);
-extern int tea5767_tuner_init(struct i2c_client *c);
+extern int tda9887_tuner_init(struct tuner *t);
 
 /* ------------------------------------------------------------------------ */
 
@@ -96,7 +88,7 @@ extern int tea5767_tuner_init(struct i2c_client *c);
                printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \
                        i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
 
-#endif /* __TUNER_HW_H__ */
+#endif /* __TUNER_DRIVER_H__ */
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/media/video/tuner-i2c.h b/drivers/media/video/tuner-i2c.h
new file mode 100644 (file)
index 0000000..159019e
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+    tuner-i2c.h - i2c interface for different tuners
+
+    Copyright (C) 2007 Michael Krufky (mkrufky@linuxtv.org)
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __TUNER_I2C_H__
+#define __TUNER_I2C_H__
+
+#include <linux/i2c.h>
+
+struct tuner_i2c_props {
+       u8 addr;
+       struct i2c_adapter *adap;
+};
+
+static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len)
+{
+       struct i2c_msg msg = { .addr = props->addr, .flags = 0,
+                              .buf = buf, .len = len };
+       int ret = i2c_transfer(props->adap, &msg, 1);
+
+       return (ret == 1) ? len : ret;
+}
+
+static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props, char *buf, int len)
+{
+       struct i2c_msg msg = { .addr = props->addr, .flags = I2C_M_RD,
+                              .buf = buf, .len = len };
+       int ret = i2c_transfer(props->adap, &msg, 1);
+
+       return (ret == 1) ? len : ret;
+}
+
+#ifndef __TUNER_DRIVER_H__
+#define tuner_warn(fmt, arg...) do {\
+       printk(KERN_WARNING PREFIX "%d-%04x: " fmt, \
+                       i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr , ##arg); } while (0)
+#define tuner_info(fmt, arg...) do {\
+       printk(KERN_INFO PREFIX "%d-%04x: " fmt, \
+                       i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr , ##arg); } while (0)
+#define tuner_dbg(fmt, arg...) do {\
+       if ((debug)) \
+               printk(KERN_DEBUG PREFIX "%d-%04x: " fmt, \
+                       i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr , ##arg); } while (0)
+#endif /* __TUNER_DRIVER_H__ */
+
+#endif /* __TUNER_I2C_H__ */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
index 2d57e8bc0db3467e406d184d80647582abf2c0c8..7b93d3b1f4c6aa540ced10abdfdaa2fd4198cae1 100644 (file)
@@ -1,7 +1,8 @@
 /*
- *
  * i2c tv tuner chip device driver
  * controls all those simple 4-control-bytes style tuners.
+ *
+ * This "tuner-simple" module was split apart from the original "tuner" module.
  */
 #include <linux/delay.h>
 #include <linux/i2c.h>
@@ -9,7 +10,14 @@
 #include <media/tuner.h>
 #include <media/v4l2-common.h>
 #include <media/tuner-types.h>
-#include "tuner-driver.h"
+#include "tuner-i2c.h"
+#include "tuner-simple.h"
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable verbose debug messages");
+
+#define PREFIX "tuner-simple "
 
 static int offset = 0;
 module_param(offset, int, 0664);
@@ -82,59 +90,102 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner");
 #define TUNER_PLL_LOCKED   0x40
 #define TUNER_STEREO_MK3   0x04
 
+struct tuner_simple_priv {
+       u16 last_div;
+       struct tuner_i2c_props i2c_props;
+
+       unsigned int type;
+       struct tunertype *tun;
+
+       u32 frequency;
+};
+
 /* ---------------------------------------------------------------------- */
 
-static int tuner_getstatus(struct i2c_client *c)
+static int tuner_read_status(struct dvb_frontend *fe)
 {
+       struct tuner_simple_priv *priv = fe->tuner_priv;
        unsigned char byte;
 
-       if (1 != i2c_master_recv(c,&byte,1))
+       if (1 != tuner_i2c_xfer_recv(&priv->i2c_props,&byte,1))
                return 0;
 
        return byte;
 }
 
-static int tuner_signal(struct i2c_client *c)
+static inline int tuner_signal(const int status)
 {
-       return (tuner_getstatus(c) & TUNER_SIGNAL) << 13;
+       return (status & TUNER_SIGNAL) << 13;
 }
 
-static int tuner_stereo(struct i2c_client *c)
+static inline int tuner_stereo(const int type, const int status)
 {
-       int stereo, status;
-       struct tuner *t = i2c_get_clientdata(c);
-
-       status = tuner_getstatus (c);
-
-       switch (t->type) {
+       switch (type) {
                case TUNER_PHILIPS_FM1216ME_MK3:
                case TUNER_PHILIPS_FM1236_MK3:
                case TUNER_PHILIPS_FM1256_IH3:
                case TUNER_LG_NTSC_TAPE:
-                       stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
-                       break;
+                       return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
                default:
-                       stereo = status & TUNER_STEREO;
+                       return status & TUNER_STEREO;
        }
+}
+
+static inline int tuner_islocked(const int status)
+{
+       return (status & TUNER_FL);
+}
 
-       return stereo;
+static inline int tuner_afcstatus(const int status)
+{
+       return (status & TUNER_AFC) - 2;
 }
 
 
+static int simple_get_status(struct dvb_frontend *fe, u32 *status)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       int tuner_status = tuner_read_status(fe);
+
+       *status = 0;
+
+       if (tuner_islocked(tuner_status))
+               *status = TUNER_STATUS_LOCKED;
+       if (tuner_stereo(priv->type, tuner_status))
+               *status |= TUNER_STATUS_STEREO;
+
+       tuner_dbg("AFC Status: %d\n", tuner_afcstatus(tuner_status));
+
+       return 0;
+}
+
+static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       int signal = tuner_signal(tuner_read_status(fe));
+
+       *strength = signal;
+
+       tuner_dbg("Signal strength: %d\n", signal);
+
+       return 0;
+}
+
 /* ---------------------------------------------------------------------- */
 
-static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
+static int simple_set_tv_freq(struct dvb_frontend *fe,
+                             struct analog_parameters *params)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct tuner_simple_priv *priv = fe->tuner_priv;
        u8 config, cb, tuneraddr;
        u16 div;
        struct tunertype *tun;
        u8 buffer[4];
        int rc, IFPCoff, i, j;
        enum param_type desired_type;
-       struct tuner_params *params;
+       struct tuner_params *t_params;
 
-       tun = &tuners[t->type];
+       tun = priv->tun;
 
        /* IFPCoff = Video Intermediate Frequency - Vif:
                940  =16*58.75  NTSC/J (Japan)
@@ -148,14 +199,14 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                171.2=16*10.70  FM Radio (at set_radio_freq)
        */
 
-       if (t->std == V4L2_STD_NTSC_M_JP) {
+       if (params->std == V4L2_STD_NTSC_M_JP) {
                IFPCoff      = 940;
                desired_type = TUNER_PARAM_TYPE_NTSC;
-       } else if ((t->std & V4L2_STD_MN) &&
-                 !(t->std & ~V4L2_STD_MN)) {
+       } else if ((params->std & V4L2_STD_MN) &&
+                 !(params->std & ~V4L2_STD_MN)) {
                IFPCoff      = 732;
                desired_type = TUNER_PARAM_TYPE_NTSC;
-       } else if (t->std == V4L2_STD_SECAM_LC) {
+       } else if (params->std == V4L2_STD_SECAM_LC) {
                IFPCoff      = 543;
                desired_type = TUNER_PARAM_TYPE_SECAM;
        } else {
@@ -168,49 +219,49 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                        continue;
                break;
        }
-       /* use default tuner_params if desired_type not available */
+       /* use default tuner_t_params if desired_type not available */
        if (desired_type != tun->params[j].type) {
-               tuner_dbg("IFPCoff = %d: tuner_params undefined for tuner %d\n",
-                         IFPCoff,t->type);
+               tuner_dbg("IFPCoff = %d: tuner_t_params undefined for tuner %d\n",
+                         IFPCoff, priv->type);
                j = 0;
        }
-       params = &tun->params[j];
+       t_params = &tun->params[j];
 
-       for (i = 0; i < params->count; i++) {
-               if (freq > params->ranges[i].limit)
+       for (i = 0; i < t_params->count; i++) {
+               if (params->frequency > t_params->ranges[i].limit)
                        continue;
                break;
        }
-       if (i == params->count) {
+       if (i == t_params->count) {
                tuner_dbg("TV frequency out of range (%d > %d)",
-                               freq, params->ranges[i - 1].limit);
-               freq = params->ranges[--i].limit;
+                               params->frequency, t_params->ranges[i - 1].limit);
+               params->frequency = t_params->ranges[--i].limit;
        }
-       config = params->ranges[i].config;
-       cb     = params->ranges[i].cb;
+       config = t_params->ranges[i].config;
+       cb     = t_params->ranges[i].cb;
        /*  i == 0 -> VHF_LO
         *  i == 1 -> VHF_HI
         *  i == 2 -> UHF     */
        tuner_dbg("tv: param %d, range %d\n",j,i);
 
-       div=freq + IFPCoff + offset;
+       div=params->frequency + IFPCoff + offset;
 
        tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n",
-                                       freq / 16, freq % 16 * 100 / 16,
+                                       params->frequency / 16, params->frequency % 16 * 100 / 16,
                                        IFPCoff / 16, IFPCoff % 16 * 100 / 16,
                                        offset / 16, offset % 16 * 100 / 16,
                                        div);
 
        /* tv norm specific stuff for multi-norm tuners */
-       switch (t->type) {
+       switch (priv->type) {
        case TUNER_PHILIPS_SECAM: // FI1216MF
                /* 0x01 -> ??? no change ??? */
                /* 0x02 -> PAL BDGHI / SECAM L */
                /* 0x04 -> ??? PAL others / SECAM others ??? */
                cb &= ~0x03;
-               if (t->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM
+               if (params->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM
                        cb |= PHILIPS_MF_SET_STD_L;
-               else if (t->std & V4L2_STD_SECAM_LC)
+               else if (params->std & V4L2_STD_SECAM_LC)
                        cb |= PHILIPS_MF_SET_STD_LC;
                else /* V4L2_STD_B|V4L2_STD_GH */
                        cb |= PHILIPS_MF_SET_STD_BG;
@@ -219,16 +270,16 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
        case TUNER_TEMIC_4046FM5:
                cb &= ~0x0f;
 
-               if (t->std & V4L2_STD_PAL_BG) {
+               if (params->std & V4L2_STD_PAL_BG) {
                        cb |= TEMIC_SET_PAL_BG;
 
-               } else if (t->std & V4L2_STD_PAL_I) {
+               } else if (params->std & V4L2_STD_PAL_I) {
                        cb |= TEMIC_SET_PAL_I;
 
-               } else if (t->std & V4L2_STD_PAL_DK) {
+               } else if (params->std & V4L2_STD_PAL_DK) {
                        cb |= TEMIC_SET_PAL_DK;
 
-               } else if (t->std & V4L2_STD_SECAM_L) {
+               } else if (params->std & V4L2_STD_SECAM_L) {
                        cb |= TEMIC_SET_PAL_L;
 
                }
@@ -237,13 +288,13 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
        case TUNER_PHILIPS_FQ1216ME:
                cb &= ~0x0f;
 
-               if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
+               if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
                        cb |= PHILIPS_SET_PAL_BGDK;
 
-               } else if (t->std & V4L2_STD_PAL_I) {
+               } else if (params->std & V4L2_STD_PAL_I) {
                        cb |= PHILIPS_SET_PAL_I;
 
-               } else if (t->std & V4L2_STD_SECAM_L) {
+               } else if (params->std & V4L2_STD_SECAM_L) {
                        cb |= PHILIPS_SET_PAL_L;
 
                }
@@ -255,7 +306,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                /* 0x02 -> NTSC antenna input 1 */
                /* 0x03 -> NTSC antenna input 2 */
                cb &= ~0x03;
-               if (!(t->std & V4L2_STD_ATSC))
+               if (!(params->std & V4L2_STD_ATSC))
                        cb |= 2;
                /* FIXME: input */
                break;
@@ -275,23 +326,23 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                buffer[2] = 0x17;
                buffer[3] = 0x00;
                cb &= ~0x40;
-               if (t->std & V4L2_STD_ATSC) {
+               if (params->std & V4L2_STD_ATSC) {
                        cb |= 0x40;
                        buffer[1] = 0x04;
                }
                /* set to the correct mode (analog or digital) */
-               tuneraddr = c->addr;
-               c->addr = 0x0a;
-               if (2 != (rc = i2c_master_send(c,&buffer[0],2)))
+               tuneraddr = priv->i2c_props.addr;
+               priv->i2c_props.addr = 0x0a;
+               if (2 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,&buffer[0],2)))
                        tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
-               if (2 != (rc = i2c_master_send(c,&buffer[2],2)))
+               if (2 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,&buffer[2],2)))
                        tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
-               c->addr = tuneraddr;
+               priv->i2c_props.addr = tuneraddr;
                /* FIXME: input */
                break;
        }
 
-       if (params->cb_first_if_lower_freq && div < t->last_div) {
+       if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
                buffer[0] = config;
                buffer[1] = cb;
                buffer[2] = (div>>8) & 0x7f;
@@ -302,53 +353,53 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                buffer[2] = config;
                buffer[3] = cb;
        }
-       t->last_div = div;
-       if (params->has_tda9887) {
+       priv->last_div = div;
+       if (t_params->has_tda9887) {
                int config = 0;
-               int is_secam_l = (t->std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) &&
-                       !(t->std & ~(V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC));
+               int is_secam_l = (params->std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) &&
+                       !(params->std & ~(V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC));
 
-               if (t->std == V4L2_STD_SECAM_LC) {
-                       if (params->port1_active ^ params->port1_invert_for_secam_lc)
+               if (params->std == V4L2_STD_SECAM_LC) {
+                       if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc)
                                config |= TDA9887_PORT1_ACTIVE;
-                       if (params->port2_active ^ params->port2_invert_for_secam_lc)
+                       if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc)
                                config |= TDA9887_PORT2_ACTIVE;
                }
                else {
-                       if (params->port1_active)
+                       if (t_params->port1_active)
                                config |= TDA9887_PORT1_ACTIVE;
-                       if (params->port2_active)
+                       if (t_params->port2_active)
                                config |= TDA9887_PORT2_ACTIVE;
                }
-               if (params->intercarrier_mode)
+               if (t_params->intercarrier_mode)
                        config |= TDA9887_INTERCARRIER;
                if (is_secam_l) {
-                       if (i == 0 && params->default_top_secam_low)
-                               config |= TDA9887_TOP(params->default_top_secam_low);
-                       else if (i == 1 && params->default_top_secam_mid)
-                               config |= TDA9887_TOP(params->default_top_secam_mid);
-                       else if (params->default_top_secam_high)
-                               config |= TDA9887_TOP(params->default_top_secam_high);
+                       if (i == 0 && t_params->default_top_secam_low)
+                               config |= TDA9887_TOP(t_params->default_top_secam_low);
+                       else if (i == 1 && t_params->default_top_secam_mid)
+                               config |= TDA9887_TOP(t_params->default_top_secam_mid);
+                       else if (t_params->default_top_secam_high)
+                               config |= TDA9887_TOP(t_params->default_top_secam_high);
                }
                else {
-                       if (i == 0 && params->default_top_low)
-                               config |= TDA9887_TOP(params->default_top_low);
-                       else if (i == 1 && params->default_top_mid)
-                               config |= TDA9887_TOP(params->default_top_mid);
-                       else if (params->default_top_high)
-                               config |= TDA9887_TOP(params->default_top_high);
+                       if (i == 0 && t_params->default_top_low)
+                               config |= TDA9887_TOP(t_params->default_top_low);
+                       else if (i == 1 && t_params->default_top_mid)
+                               config |= TDA9887_TOP(t_params->default_top_mid);
+                       else if (t_params->default_top_high)
+                               config |= TDA9887_TOP(t_params->default_top_high);
                }
-               if (params->default_pll_gating_18)
+               if (t_params->default_pll_gating_18)
                        config |= TDA9887_GATING_18;
-               i2c_clients_command(c->adapter, TDA9887_SET_CONFIG, &config);
+               i2c_clients_command(priv->i2c_props.adap, TDA9887_SET_CONFIG, &config);
        }
        tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
                  buffer[0],buffer[1],buffer[2],buffer[3]);
 
-       if (4 != (rc = i2c_master_send(c,buffer,4)))
+       if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4)))
                tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
 
-       switch (t->type) {
+       switch (priv->type) {
        case TUNER_LG_TDVS_H06XF:
                /* Set the Auxiliary Byte. */
                buffer[0] = buffer[2];
@@ -357,7 +408,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                buffer[1] = 0x20;
                tuner_dbg("tv 0x%02x 0x%02x\n",buffer[0],buffer[1]);
 
-               if (2 != (rc = i2c_master_send(c,buffer,2)))
+               if (2 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,2)))
                        tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
                break;
        case TUNER_MICROTUNE_4042FI5:
@@ -369,8 +420,8 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                /* Wait until the PLL locks */
                for (;;) {
                        if (time_after(jiffies,timeout))
-                               return;
-                       if (1 != (rc = i2c_master_recv(c,&status_byte,1))) {
+                               return 0;
+                       if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,&status_byte,1))) {
                                tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc);
                                break;
                        }
@@ -388,68 +439,86 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
                          buffer[0],buffer[1],buffer[2],buffer[3]);
 
-               if (4 != (rc = i2c_master_send(c,buffer,4)))
+               if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4)))
                        tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
                break;
        }
        }
+       return 0;
 }
 
-static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
+static int simple_set_radio_freq(struct dvb_frontend *fe,
+                                struct analog_parameters *params)
 {
        struct tunertype *tun;
-       struct tuner *t = i2c_get_clientdata(c);
+       struct tuner_simple_priv *priv = fe->tuner_priv;
        u8 buffer[4];
        u16 div;
        int rc, j;
-       enum param_type desired_type = TUNER_PARAM_TYPE_RADIO;
-       struct tuner_params *params;
+       struct tuner_params *t_params;
+       unsigned int freq = params->frequency;
 
-       tun = &tuners[t->type];
+       tun = priv->tun;
 
-       for (j = 0; j < tun->count-1; j++) {
-               if (desired_type != tun->params[j].type)
-                       continue;
+       for (j = tun->count-1; j > 0; j--)
+               if (tun->params[j].type == TUNER_PARAM_TYPE_RADIO)
+                       break;
+       /* default t_params (j=0) will be used if desired type wasn't found */
+       t_params = &tun->params[j];
+
+       /* Select Radio 1st IF used */
+       switch (t_params->radio_if) {
+       case 0: /* 10.7 MHz */
+               freq += (unsigned int)(10.7*16000);
+               break;
+       case 1: /* 33.3 MHz */
+               freq += (unsigned int)(33.3*16000);
                break;
+       case 2: /* 41.3 MHz */
+               freq += (unsigned int)(41.3*16000);
+               break;
+       default:
+               tuner_warn("Unsupported radio_if value %d\n", t_params->radio_if);
+               return 0;
        }
-       /* use default tuner_params if desired_type not available */
-       if (desired_type != tun->params[j].type)
-               j = 0;
-
-       div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */
-       params = &tun->params[j];
-       buffer[2] = (params->ranges[0].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
 
-       switch (t->type) {
+       /* Bandswitch byte */
+       switch (priv->type) {
        case TUNER_TENA_9533_DI:
        case TUNER_YMEC_TVF_5533MF:
-               tuner_dbg ("This tuner doesn't have FM. Most cards has a TEA5767 for FM\n");
-               return;
+               tuner_dbg("This tuner doesn't have FM. Most cards have a TEA5767 for FM\n");
+               return 0;
        case TUNER_PHILIPS_FM1216ME_MK3:
        case TUNER_PHILIPS_FM1236_MK3:
        case TUNER_PHILIPS_FMD1216ME_MK3:
        case TUNER_LG_NTSC_TAPE:
+       case TUNER_PHILIPS_FM1256_IH3:
                buffer[3] = 0x19;
                break;
        case TUNER_TNF_5335MF:
                buffer[3] = 0x11;
                break;
-       case TUNER_PHILIPS_FM1256_IH3:
-               div = (20 * freq) / 16000 + (int)(33.3 * 20);  /* IF 33.3 MHz */
-               buffer[3] = 0x19;
-               break;
        case TUNER_LG_PAL_FM:
                buffer[3] = 0xa5;
                break;
-       case TUNER_MICROTUNE_4049FM5:
-               div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */
-               buffer[3] = 0xa4;
+       case TUNER_THOMSON_DTT761X:
+               buffer[3] = 0x39;
                break;
+       case TUNER_MICROTUNE_4049FM5:
        default:
                buffer[3] = 0xa4;
                break;
        }
-       if (params->cb_first_if_lower_freq && div < t->last_div) {
+
+       buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) |
+                   TUNER_RATIO_SELECT_50; /* 50 kHz step */
+
+       /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps
+          freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) =
+          freq * (1/800) */
+       div = (freq + 400) / 800;
+
+       if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
                buffer[0] = buffer[2];
                buffer[1] = buffer[3];
                buffer[2] = (div>>8) & 0x7f;
@@ -461,46 +530,108 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
 
        tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
               buffer[0],buffer[1],buffer[2],buffer[3]);
-       t->last_div = div;
+       priv->last_div = div;
 
-       if (params->has_tda9887) {
+       if (t_params->has_tda9887) {
                int config = 0;
-               if (params->port1_active && !params->port1_fm_high_sensitivity)
+               if (t_params->port1_active && !t_params->port1_fm_high_sensitivity)
                        config |= TDA9887_PORT1_ACTIVE;
-               if (params->port2_active && !params->port2_fm_high_sensitivity)
+               if (t_params->port2_active && !t_params->port2_fm_high_sensitivity)
                        config |= TDA9887_PORT2_ACTIVE;
-               if (params->intercarrier_mode)
+               if (t_params->intercarrier_mode)
                        config |= TDA9887_INTERCARRIER;
-/*             if (params->port1_set_for_fm_mono)
+/*             if (t_params->port1_set_for_fm_mono)
                        config &= ~TDA9887_PORT1_ACTIVE;*/
-               if (params->fm_gain_normal)
+               if (t_params->fm_gain_normal)
                        config |= TDA9887_GAIN_NORMAL;
-               i2c_clients_command(c->adapter, TDA9887_SET_CONFIG, &config);
+               if (t_params->radio_if == 2)
+                       config |= TDA9887_RIF_41_3;
+               i2c_clients_command(priv->i2c_props.adap, TDA9887_SET_CONFIG, &config);
        }
-       if (4 != (rc = i2c_master_send(c,buffer,4)))
+       if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,buffer,4)))
                tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
+
+       return 0;
 }
 
-static struct tuner_operations simple_tuner_ops = {
-       .set_tv_freq    = default_set_tv_freq,
-       .set_radio_freq = default_set_radio_freq,
-       .has_signal     = tuner_signal,
-       .is_stereo      = tuner_stereo,
+static int simple_set_params(struct dvb_frontend *fe,
+                            struct analog_parameters *params)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       int ret = -EINVAL;
+
+       switch (params->mode) {
+       case V4L2_TUNER_RADIO:
+               ret = simple_set_radio_freq(fe, params);
+               priv->frequency = params->frequency * 125 / 2;
+               break;
+       case V4L2_TUNER_ANALOG_TV:
+       case V4L2_TUNER_DIGITAL_TV:
+               ret = simple_set_tv_freq(fe, params);
+               priv->frequency = params->frequency * 62500;
+               break;
+       }
+
+       return ret;
+}
+
+
+static int simple_release(struct dvb_frontend *fe)
+{
+       kfree(fe->tuner_priv);
+       fe->tuner_priv = NULL;
+
+       return 0;
+}
+
+static int simple_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct tuner_simple_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static struct dvb_tuner_ops simple_tuner_ops = {
+       .set_analog_params = simple_set_params,
+       .release           = simple_release,
+       .get_frequency     = simple_get_frequency,
+       .get_status        = simple_get_status,
+       .get_rf_strength   = simple_get_rf_strength,
 };
 
-int default_tuner_init(struct i2c_client *c)
+struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
+                                        struct i2c_adapter *i2c_adap,
+                                        u8 i2c_addr,
+                                        struct simple_tuner_config *cfg)
 {
-       struct tuner *t = i2c_get_clientdata(c);
+       struct tuner_simple_priv *priv = NULL;
 
-       tuner_info("type set to %d (%s)\n",
-                  t->type, tuners[t->type].name);
-       strlcpy(c->name, tuners[t->type].name, sizeof(c->name));
+       priv = kzalloc(sizeof(struct tuner_simple_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+       fe->tuner_priv = priv;
 
-       memcpy(&t->ops, &simple_tuner_ops, sizeof(struct tuner_operations));
+       priv->i2c_props.addr = i2c_addr;
+       priv->i2c_props.adap = i2c_adap;
+       priv->type = cfg->type;
+       priv->tun  = cfg->tun;
 
-       return 0;
+       memcpy(&fe->ops.tuner_ops, &simple_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+       tuner_info("type set to %d (%s)\n", cfg->type, cfg->tun->name);
+
+       strlcpy(fe->ops.tuner_ops.info.name, cfg->tun->name, sizeof(fe->ops.tuner_ops.info.name));
+
+       return fe;
 }
 
+
+EXPORT_SYMBOL_GPL(simple_tuner_attach);
+
+MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver");
+MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
+MODULE_LICENSE("GPL");
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tuner-simple.h b/drivers/media/video/tuner-simple.h
new file mode 100644 (file)
index 0000000..9089939
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __TUNER_SIMPLE_H__
+#define __TUNER_SIMPLE_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+struct simple_tuner_config
+{
+       /* chip type */
+       unsigned int type;
+       struct tunertype *tun;
+};
+
+#if defined(CONFIG_TUNER_SIMPLE) || (defined(CONFIG_TUNER_SIMPLE_MODULE) && defined(MODULE))
+extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
+                                               struct i2c_adapter *i2c_adap,
+                                               u8 i2c_addr,
+                                               struct simple_tuner_config *cfg);
+#else
+static inline struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
+                                                      struct i2c_adapter *i2c_adap,
+                                                      u8 i2c_addr,
+                                                      struct simple_tuner_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+       return NULL;
+}
+#endif
+
+#endif /* __TUNER_SIMPLE_H__ */
index 417f642b435985bae6937070cc9fb83d55a2f2b1..c6a7934bd5a678f9287c6963344f9e3d1e7c216e 100644 (file)
@@ -652,6 +652,7 @@ static struct tuner_params tuner_microtune_4049_fm5_params[] = {
                .port1_invert_for_secam_lc = 1,
                .default_pll_gating_18 = 1,
                .fm_gain_normal=1,
+               .radio_if = 1, /* 33.3 MHz */
        },
 };
 
@@ -670,6 +671,9 @@ static struct tuner_params tuner_panasonic_vp27_params[] = {
                .count  = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges),
                .has_tda9887 = 1,
                .intercarrier_mode = 1,
+               .default_top_low = -3,
+               .default_top_mid = -3,
+               .default_top_high = -3,
        },
 };
 
@@ -730,6 +734,7 @@ static struct tuner_params tuner_philips_fm1256_ih3_params[] = {
                .type   = TUNER_PARAM_TYPE_PAL,
                .ranges = tuner_fm1236_mk3_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
+               .radio_if = 1, /* 33.3 MHz */
        },
 };
 
@@ -856,6 +861,9 @@ static struct tuner_params tuner_thomson_dtt761x_params[] = {
                .type   = TUNER_PARAM_TYPE_NTSC,
                .ranges = tuner_thomson_dtt761x_ntsc_ranges,
                .count  = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges),
+               .has_tda9887 = 1,
+               .fm_gain_normal = 1,
+               .radio_if = 2, /* 41.3 MHz */
        },
 };
 
index cffb011590e3bb0418561ba0e54646d9e85bd1d5..a19cdcc17ef7b9ded8ea55010401b6618356da7a 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
index fdc3def437b134214181344564d3b2eaae45e61f..4b2c4034f5b375be96b3d348f0eb7f4e1b94cfae 100644 (file)
@@ -30,7 +30,6 @@
 
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
index 3ae5a9cd2e28f1388f526acacdd0bb00e79cd7e5..9fa5b702e0736ddfc99b26177bae0c547aefd70d 100644 (file)
@@ -2,7 +2,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/timer.h>
@@ -238,13 +237,10 @@ static const struct file_operations tvmixer_fops = {
 
 static int tvmixer_adapters(struct i2c_adapter *adap)
 {
-       struct list_head  *item;
        struct i2c_client *client;
 
-       list_for_each(item,&adap->clients) {
-               client = list_entry(item, struct i2c_client, list);
+       list_for_each_entry(client, &adap->clients, list)
                tvmixer_clients(client);
-       }
        return 0;
 }
 
index 5b1e346df20684c7df22d3c9a6b9b1357974cc51..c7d5f9ed22d7add7a5997caad00cb050377204d0 100644 (file)
@@ -45,7 +45,6 @@
 #include <media/tuner.h>
 #include <media/audiochip.h>
 
-#include <linux/moduleparam.h>
 #include <linux/workqueue.h>
 
 #ifdef CONFIG_KMOD
index 025be555194f4eac8dc6f174325abfb3c08693b4..c66aef63916f5b246a1948642966f12f21b00465 100644 (file)
@@ -134,8 +134,6 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
                addr = (msg->addr << 1);
                if (flags & I2C_M_RD)
                        addr |= 1;
-               if (flags & I2C_M_REV_DIR_ADDR)
-                       addr ^= 1;
 
                add[0] = addr;
                if (flags & I2C_M_RD)
@@ -192,7 +190,7 @@ static int algo_control(struct i2c_adapter *adapter, unsigned int cmd, unsigned
 
 static u32 functionality(struct i2c_adapter *adap)
 {
-       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
+       return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
 }
 
 
index 0cb006f2943da5abfb08bc604a25097f18b4665b..e2f3c01cfa134c2290507d3de9d806554bbc69a6 100644 (file)
@@ -68,7 +68,6 @@
 #include <media/tuner.h>
 #include <media/audiochip.h>
 
-#include <linux/moduleparam.h>
 #include <linux/workqueue.h>
 
 #ifdef CONFIG_KMOD
@@ -183,20 +182,22 @@ MODULE_ALIAS(DRIVER_ALIAS);
 
 #define YES_NO(x) ((x) ? "Yes" : "No")
 
-static inline struct usb_usbvision *cd_to_usbvision(struct class_device *cd)
+static inline struct usb_usbvision *cd_to_usbvision(struct device *cd)
 {
        struct video_device *vdev =
                container_of(cd, struct video_device, class_dev);
        return video_get_drvdata(vdev);
 }
 
-static ssize_t show_version(struct class_device *cd, char *buf)
+static ssize_t show_version(struct device *cd,
+                           struct device_attribute *attr, char *buf)
 {
        return sprintf(buf, "%s\n", USBVISION_VERSION_STRING);
 }
-static CLASS_DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
+static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
 
-static ssize_t show_model(struct class_device *cd, char *buf)
+static ssize_t show_model(struct device *cd,
+                         struct device_attribute *attr, char *buf)
 {
        struct video_device *vdev =
                container_of(cd, struct video_device, class_dev);
@@ -204,9 +205,10 @@ static ssize_t show_model(struct class_device *cd, char *buf)
        return sprintf(buf, "%s\n",
                       usbvision_device_data[usbvision->DevModel].ModelString);
 }
-static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
+static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
 
-static ssize_t show_hue(struct class_device *cd, char *buf)
+static ssize_t show_hue(struct device *cd,
+                       struct device_attribute *attr, char *buf)
 {
        struct video_device *vdev =
                container_of(cd, struct video_device, class_dev);
@@ -218,9 +220,10 @@ static ssize_t show_hue(struct class_device *cd, char *buf)
                call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
        return sprintf(buf, "%d\n", ctrl.value);
 }
-static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
+static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
 
-static ssize_t show_contrast(struct class_device *cd, char *buf)
+static ssize_t show_contrast(struct device *cd,
+                            struct device_attribute *attr, char *buf)
 {
        struct video_device *vdev =
                container_of(cd, struct video_device, class_dev);
@@ -232,9 +235,10 @@ static ssize_t show_contrast(struct class_device *cd, char *buf)
                call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
        return sprintf(buf, "%d\n", ctrl.value);
 }
-static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
+static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
 
-static ssize_t show_brightness(struct class_device *cd, char *buf)
+static ssize_t show_brightness(struct device *cd,
+                              struct device_attribute *attr, char *buf)
 {
        struct video_device *vdev =
                container_of(cd, struct video_device, class_dev);
@@ -246,9 +250,10 @@ static ssize_t show_brightness(struct class_device *cd, char *buf)
                call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
        return sprintf(buf, "%d\n", ctrl.value);
 }
-static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
+static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
 
-static ssize_t show_saturation(struct class_device *cd, char *buf)
+static ssize_t show_saturation(struct device *cd,
+                              struct device_attribute *attr, char *buf)
 {
        struct video_device *vdev =
                container_of(cd, struct video_device, class_dev);
@@ -260,9 +265,10 @@ static ssize_t show_saturation(struct class_device *cd, char *buf)
                call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
        return sprintf(buf, "%d\n", ctrl.value);
 }
-static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
+static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
 
-static ssize_t show_streaming(struct class_device *cd, char *buf)
+static ssize_t show_streaming(struct device *cd,
+                             struct device_attribute *attr, char *buf)
 {
        struct video_device *vdev =
                container_of(cd, struct video_device, class_dev);
@@ -270,9 +276,10 @@ static ssize_t show_streaming(struct class_device *cd, char *buf)
        return sprintf(buf, "%s\n",
                       YES_NO(usbvision->streaming==Stream_On?1:0));
 }
-static CLASS_DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL);
+static DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL);
 
-static ssize_t show_compression(struct class_device *cd, char *buf)
+static ssize_t show_compression(struct device *cd,
+                               struct device_attribute *attr, char *buf)
 {
        struct video_device *vdev =
                container_of(cd, struct video_device, class_dev);
@@ -280,16 +287,17 @@ static ssize_t show_compression(struct class_device *cd, char *buf)
        return sprintf(buf, "%s\n",
                       YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS));
 }
-static CLASS_DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL);
+static DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL);
 
-static ssize_t show_device_bridge(struct class_device *cd, char *buf)
+static ssize_t show_device_bridge(struct device *cd,
+                                 struct device_attribute *attr, char *buf)
 {
        struct video_device *vdev =
                container_of(cd, struct video_device, class_dev);
        struct usb_usbvision *usbvision = video_get_drvdata(vdev);
        return sprintf(buf, "%d\n", usbvision->bridgeType);
 }
-static CLASS_DEVICE_ATTR(bridge, S_IRUGO, show_device_bridge, NULL);
+static DEVICE_ATTR(bridge, S_IRUGO, show_device_bridge, NULL);
 
 static void usbvision_create_sysfs(struct video_device *vdev)
 {
@@ -297,40 +305,40 @@ static void usbvision_create_sysfs(struct video_device *vdev)
        if (!vdev)
                return;
        do {
-               res=class_device_create_file(&vdev->class_dev,
-                                            &class_device_attr_version);
+               res = device_create_file(&vdev->class_dev,
+                                        &dev_attr_version);
                if (res<0)
                        break;
-               res=class_device_create_file(&vdev->class_dev,
-                                            &class_device_attr_model);
+               res = device_create_file(&vdev->class_dev,
+                                        &dev_attr_model);
                if (res<0)
                        break;
-               res=class_device_create_file(&vdev->class_dev,
-                                            &class_device_attr_hue);
+               res = device_create_file(&vdev->class_dev,
+                                        &dev_attr_hue);
                if (res<0)
                        break;
-               res=class_device_create_file(&vdev->class_dev,
-                                            &class_device_attr_contrast);
+               res = device_create_file(&vdev->class_dev,
+                                        &dev_attr_contrast);
                if (res<0)
                        break;
-               res=class_device_create_file(&vdev->class_dev,
-                                            &class_device_attr_brightness);
+               res = device_create_file(&vdev->class_dev,
+                                        &dev_attr_brightness);
                if (res<0)
                        break;
-               res=class_device_create_file(&vdev->class_dev,
-                                            &class_device_attr_saturation);
+               res = device_create_file(&vdev->class_dev,
+                                        &dev_attr_saturation);
                if (res<0)
                        break;
-               res=class_device_create_file(&vdev->class_dev,
-                                            &class_device_attr_streaming);
+               res = device_create_file(&vdev->class_dev,
+                                        &dev_attr_streaming);
                if (res<0)
                        break;
-               res=class_device_create_file(&vdev->class_dev,
-                                            &class_device_attr_compression);
+               res = device_create_file(&vdev->class_dev,
+                                        &dev_attr_compression);
                if (res<0)
                        break;
-               res=class_device_create_file(&vdev->class_dev,
-                                            &class_device_attr_bridge);
+               res = device_create_file(&vdev->class_dev,
+                                        &dev_attr_bridge);
                if (res>=0)
                        return;
        } while (0);
@@ -341,24 +349,24 @@ static void usbvision_create_sysfs(struct video_device *vdev)
 static void usbvision_remove_sysfs(struct video_device *vdev)
 {
        if (vdev) {
-               class_device_remove_file(&vdev->class_dev,
-                                        &class_device_attr_version);
-               class_device_remove_file(&vdev->class_dev,
-                                        &class_device_attr_model);
-               class_device_remove_file(&vdev->class_dev,
-                                        &class_device_attr_hue);
-               class_device_remove_file(&vdev->class_dev,
-                                        &class_device_attr_contrast);
-               class_device_remove_file(&vdev->class_dev,
-                                        &class_device_attr_brightness);
-               class_device_remove_file(&vdev->class_dev,
-                                        &class_device_attr_saturation);
-               class_device_remove_file(&vdev->class_dev,
-                                        &class_device_attr_streaming);
-               class_device_remove_file(&vdev->class_dev,
-                                        &class_device_attr_compression);
-               class_device_remove_file(&vdev->class_dev,
-                                        &class_device_attr_bridge);
+               device_remove_file(&vdev->class_dev,
+                                        &dev_attr_version);
+               device_remove_file(&vdev->class_dev,
+                                        &dev_attr_model);
+               device_remove_file(&vdev->class_dev,
+                                        &dev_attr_hue);
+               device_remove_file(&vdev->class_dev,
+                                        &dev_attr_contrast);
+               device_remove_file(&vdev->class_dev,
+                                        &dev_attr_brightness);
+               device_remove_file(&vdev->class_dev,
+                                        &dev_attr_saturation);
+               device_remove_file(&vdev->class_dev,
+                                        &dev_attr_streaming);
+               device_remove_file(&vdev->class_dev,
+                                        &dev_attr_compression);
+               device_remove_file(&vdev->class_dev,
+                                        &dev_attr_bridge);
        }
 }
 
index ede8543818bfdfef8bdb3fa0bb86c0869cbf637a..9eac65f34bff815515d36577872424f89dbcd692 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
index d2915d3530ead3d53499188504435cc884d643c1..c3440b280d208456d6d50980f8949ae423aba493 100644 (file)
 #include <linux/kmod.h>
 #endif
 
-#if defined(CONFIG_UST) || defined(CONFIG_UST_MODULE)
-#include <linux/ust.h>
-#endif
-
-
 #include <linux/videodev.h>
 
 MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
@@ -716,6 +711,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
        case V4L2_CID_AUDIO_MUTE:
        case V4L2_CID_AUDIO_LOUDNESS:
        case V4L2_CID_MPEG_AUDIO_MUTE:
+       case V4L2_CID_MPEG_VIDEO_MUTE:
        case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
        case V4L2_CID_MPEG_VIDEO_PULLDOWN:
                qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
diff --git a/drivers/media/video/v4l2-int-device.c b/drivers/media/video/v4l2-int-device.c
new file mode 100644 (file)
index 0000000..8b4ef53
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * drivers/media/video/v4l2-int-device.c
+ *
+ * V4L2 internal ioctl interface.
+ *
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/sort.h>
+#include <linux/string.h>
+
+#include <media/v4l2-int-device.h>
+
+static DEFINE_MUTEX(mutex);
+static LIST_HEAD(int_list);
+
+static void v4l2_int_device_try_attach_all(void)
+{
+       struct v4l2_int_device *m, *s;
+
+       list_for_each_entry(m, &int_list, head) {
+               if (m->type != v4l2_int_type_master)
+                       continue;
+
+               list_for_each_entry(s, &int_list, head) {
+                       if (s->type != v4l2_int_type_slave)
+                               continue;
+
+                       /* Slave is connected? */
+                       if (s->u.slave->master)
+                               continue;
+
+                       /* Slave wants to attach to master? */
+                       if (s->u.slave->attach_to[0] != 0
+                           && strncmp(m->name, s->u.slave->attach_to,
+                                      V4L2NAMESIZE))
+                               continue;
+
+                       if (!try_module_get(m->module))
+                               continue;
+
+                       if (m->u.master->attach(m, s)) {
+                               module_put(m->module);
+                               continue;
+                       }
+
+                       s->u.slave->master = m;
+               }
+       }
+}
+
+static int ioctl_sort_cmp(const void *a, const void *b)
+{
+       const struct v4l2_int_ioctl_desc *d1 = a, *d2 = b;
+
+       if (d1->num > d2->num)
+               return 1;
+
+       if (d1->num < d2->num)
+               return -1;
+
+       return 0;
+}
+
+int v4l2_int_device_register(struct v4l2_int_device *d)
+{
+       if (d->type == v4l2_int_type_slave)
+               sort(d->u.slave->ioctls, d->u.slave->num_ioctls,
+                    sizeof(struct v4l2_int_ioctl_desc),
+                    &ioctl_sort_cmp, NULL);
+       mutex_lock(&mutex);
+       list_add(&d->head, &int_list);
+       v4l2_int_device_try_attach_all();
+       mutex_unlock(&mutex);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_int_device_register);
+
+void v4l2_int_device_unregister(struct v4l2_int_device *d)
+{
+       mutex_lock(&mutex);
+       list_del(&d->head);
+       if (d->type == v4l2_int_type_slave
+           && d->u.slave->master != NULL) {
+               d->u.slave->master->u.master->detach(d);
+               module_put(d->u.slave->master->module);
+               d->u.slave->master = NULL;
+       }
+       mutex_unlock(&mutex);
+}
+EXPORT_SYMBOL_GPL(v4l2_int_device_unregister);
+
+/* Adapted from search_extable in extable.c. */
+static v4l2_int_ioctl_func *find_ioctl(struct v4l2_int_slave *slave, int cmd,
+                                      v4l2_int_ioctl_func *no_such_ioctl)
+{
+       const struct v4l2_int_ioctl_desc *first = slave->ioctls;
+       const struct v4l2_int_ioctl_desc *last =
+               first + slave->num_ioctls - 1;
+
+       while (first <= last) {
+               const struct v4l2_int_ioctl_desc *mid;
+
+               mid = (last - first) / 2 + first;
+
+               if (mid->num < cmd)
+                       first = mid + 1;
+               else if (mid->num > cmd)
+                       last = mid - 1;
+               else
+                       return mid->func;
+       }
+
+       return no_such_ioctl;
+}
+
+static int no_such_ioctl_0(struct v4l2_int_device *d)
+{
+       return -ENOIOCTLCMD;
+}
+
+int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd)
+{
+       return ((v4l2_int_ioctl_func_0 *)
+               find_ioctl(d->u.slave, cmd,
+                          (v4l2_int_ioctl_func *)no_such_ioctl_0))(d);
+}
+
+static int no_such_ioctl_1(struct v4l2_int_device *d, void *arg)
+{
+       return -ENOIOCTLCMD;
+}
+
+int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg)
+{
+       return ((v4l2_int_ioctl_func_1 *)
+               find_ioctl(d->u.slave, cmd,
+                          (v4l2_int_ioctl_func *)no_such_ioctl_1))(d, arg);
+}
similarity index 52%
rename from drivers/media/video/video-buf.c
rename to drivers/media/video/videobuf-core.c
index a32dfbe0585af96de2c9acc126e5fd0e6fb1edd8..c606332512b60e9edf01382591da8206eb64497e 100644 (file)
 /*
+ * generic helper functions for handling video4linux capture buffers
  *
- * generic helper functions for video4linux capture buffers, to handle
- * memory management and PCI DMA.
- * Right now, bttv, saa7134, saa7146 and cx88 use it.
+ * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
  *
- * The functions expect the hardware being able to scatter gatter
- * (i.e. the buffers are not linear in physical memory, but fragmented
- * into PAGE_SIZE chunks).  They also assume the driver does not need
- * to touch the video data.
- *
- * device specific map/unmap/sync stuff now are mapped as operations
- * to allow its usage by USB and virtual devices.
- *
- * (c) 2001-2004 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
- * (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>
+ * Highly based on video-buf written originally by:
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
+ * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org>
  * (c) 2006 Ted Walther and John Sokol
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation; either version 2
  */
 
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/vmalloc.h>
-#include <linux/pagemap.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/interrupt.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
 
-#include <media/video-buf.h>
+#include <media/videobuf-core.h>
 
-#define MAGIC_DMABUF 0x19721112
-#define MAGIC_BUFFER 0x20040302
+#define MAGIC_BUFFER 0x20070728
 #define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \
        { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); }
 
 static int debug = 0;
 module_param(debug, int, 0644);
 
-MODULE_DESCRIPTION("helper module to manage video4linux pci dma buffers");
-MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
+MODULE_DESCRIPTION("helper module to manage video4linux buffers");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
 MODULE_LICENSE("GPL");
 
 #define dprintk(level, fmt, arg...)    if (debug >= level) \
        printk(KERN_DEBUG "vbuf: " fmt , ## arg)
 
-struct scatterlist*
-videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
-{
-       struct scatterlist *sglist;
-       struct page *pg;
-       int i;
-
-       sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
-       if (NULL == sglist)
-               return NULL;
-       for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
-               pg = vmalloc_to_page(virt);
-               if (NULL == pg)
-                       goto err;
-               BUG_ON(PageHighMem(pg));
-               sglist[i].page   = pg;
-               sglist[i].length = PAGE_SIZE;
-       }
-       return sglist;
-
- err:
-       kfree(sglist);
-       return NULL;
-}
-
-struct scatterlist*
-videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
-{
-       struct scatterlist *sglist;
-       int i = 0;
-
-       if (NULL == pages[0])
-               return NULL;
-       sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
-       if (NULL == sglist)
-               return NULL;
-
-       if (NULL == pages[0])
-               goto nopage;
-       if (PageHighMem(pages[0]))
-               /* DMA to highmem pages might not work */
-               goto highmem;
-       sglist[0].page   = pages[0];
-       sglist[0].offset = offset;
-       sglist[0].length = PAGE_SIZE - offset;
-       for (i = 1; i < nr_pages; i++) {
-               if (NULL == pages[i])
-                       goto nopage;
-               if (PageHighMem(pages[i]))
-                       goto highmem;
-               sglist[i].page   = pages[i];
-               sglist[i].length = PAGE_SIZE;
-       }
-       return sglist;
-
- nopage:
-       dprintk(2,"sgl: oops - no page\n");
-       kfree(sglist);
-       return NULL;
-
- highmem:
-       dprintk(2,"sgl: oops - highmem page\n");
-       kfree(sglist);
-       return NULL;
-}
-
 /* --------------------------------------------------------------------- */
 
-void videobuf_dma_init(struct videobuf_dmabuf *dma)
-{
-       memset(dma,0,sizeof(*dma));
-       dma->magic = MAGIC_DMABUF;
-}
+#define CALL(q, f, arg...)                                             \
+       ( (q->int_ops->f)? q->int_ops->f(arg) : 0)
 
-int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
-                          unsigned long data, unsigned long size)
+void* videobuf_alloc(struct videobuf_queue* q)
 {
-       unsigned long first,last;
-       int err, rw = 0;
-
-       dma->direction = direction;
-       switch (dma->direction) {
-       case PCI_DMA_FROMDEVICE: rw = READ;  break;
-       case PCI_DMA_TODEVICE:   rw = WRITE; break;
-       default:                 BUG();
-       }
-
-       first = (data          & PAGE_MASK) >> PAGE_SHIFT;
-       last  = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT;
-       dma->offset   = data & ~PAGE_MASK;
-       dma->nr_pages = last-first+1;
-       dma->pages = kmalloc(dma->nr_pages * sizeof(struct page*),
-                            GFP_KERNEL);
-       if (NULL == dma->pages)
-               return -ENOMEM;
-       dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n",
-               data,size,dma->nr_pages);
-
-       dma->varea = (void *) data;
-
-       down_read(&current->mm->mmap_sem);
-       err = get_user_pages(current,current->mm,
-                            data & PAGE_MASK, dma->nr_pages,
-                            rw == READ, 1, /* force */
-                            dma->pages, NULL);
-       up_read(&current->mm->mmap_sem);
-       if (err != dma->nr_pages) {
-               dma->nr_pages = (err >= 0) ? err : 0;
-               dprintk(1,"get_user_pages: err=%d [%d]\n",err,dma->nr_pages);
-               return err < 0 ? err : -EINVAL;
-       }
-       return 0;
-}
-
-int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
-                            int nr_pages)
-{
-       dprintk(1,"init kernel [%d pages]\n",nr_pages);
-       dma->direction = direction;
-       dma->vmalloc = vmalloc_32(nr_pages << PAGE_SHIFT);
-       if (NULL == dma->vmalloc) {
-               dprintk(1,"vmalloc_32(%d pages) failed\n",nr_pages);
-               return -ENOMEM;
-       }
-       dprintk(1,"vmalloc is at addr 0x%08lx, size=%d\n",
-                               (unsigned long)dma->vmalloc,
-                               nr_pages << PAGE_SHIFT);
-       memset(dma->vmalloc,0,nr_pages << PAGE_SHIFT);
-       dma->nr_pages = nr_pages;
-       return 0;
-}
-
-int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
-                             dma_addr_t addr, int nr_pages)
-{
-       dprintk(1,"init overlay [%d pages @ bus 0x%lx]\n",
-               nr_pages,(unsigned long)addr);
-       dma->direction = direction;
-       if (0 == addr)
-               return -EINVAL;
-
-       dma->bus_addr = addr;
-       dma->nr_pages = nr_pages;
-       return 0;
-}
-
-int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma)
-{
-       void                   *dev=q->dev;
-
-       MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
-       BUG_ON(0 == dma->nr_pages);
-
-       if (dma->pages) {
-               dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
-                                                  dma->offset);
-       }
-       if (dma->vmalloc) {
-               dma->sglist = videobuf_vmalloc_to_sg
-                                               (dma->vmalloc,dma->nr_pages);
-       }
-       if (dma->bus_addr) {
-               dma->sglist = kmalloc(sizeof(struct scatterlist), GFP_KERNEL);
-               if (NULL != dma->sglist) {
-                       dma->sglen  = 1;
-                       sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK;
-                       dma->sglist[0].offset           = dma->bus_addr & ~PAGE_MASK;
-                       sg_dma_len(&dma->sglist[0])     = dma->nr_pages * PAGE_SIZE;
-               }
-       }
-       if (NULL == dma->sglist) {
-               dprintk(1,"scatterlist is NULL\n");
-               return -ENOMEM;
-       }
-       if (!dma->bus_addr) {
-               if (q->ops->vb_map_sg) {
-                       dma->sglen = q->ops->vb_map_sg(dev,dma->sglist,
-                                       dma->nr_pages, dma->direction);
-               }
-               if (0 == dma->sglen) {
-                       printk(KERN_WARNING
-                              "%s: videobuf_map_sg failed\n",__FUNCTION__);
-                       kfree(dma->sglist);
-                       dma->sglist = NULL;
-                       dma->sglen = 0;
-                       return -EIO;
-               }
-       }
-       return 0;
-}
-
-int videobuf_dma_sync(struct videobuf_queue* q,struct videobuf_dmabuf *dma)
-{
-       void                   *dev=q->dev;
-
-       MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
-       BUG_ON(!dma->sglen);
-
-       if (!dma->bus_addr && q->ops->vb_dma_sync_sg)
-               q->ops->vb_dma_sync_sg(dev,dma->sglist,dma->nr_pages,
-                                                       dma->direction);
-
-       return 0;
-}
-
-int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma)
-{
-       void                   *dev=q->dev;
-
-       MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
-       if (!dma->sglen)
-               return 0;
-
-       if (!dma->bus_addr && q->ops->vb_unmap_sg)
-                       q->ops->vb_unmap_sg(dev,dma->sglist,dma->nr_pages,
-                                                       dma->direction);
-       kfree(dma->sglist);
-       dma->sglist = NULL;
-       dma->sglen = 0;
-       return 0;
-}
-
-int videobuf_dma_free(struct videobuf_dmabuf *dma)
-{
-       MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
-       BUG_ON(dma->sglen);
-
-       if (dma->pages) {
-               int i;
-               for (i=0; i < dma->nr_pages; i++)
-                       page_cache_release(dma->pages[i]);
-               kfree(dma->pages);
-               dma->pages = NULL;
-       }
+       struct videobuf_buffer *vb;
 
-       vfree(dma->vmalloc);
-       dma->vmalloc = NULL;
-       dma->varea = NULL;
+       BUG_ON (q->msize<sizeof(*vb));
 
-       if (dma->bus_addr) {
-               dma->bus_addr = 0;
+       if (!q->int_ops || !q->int_ops->alloc) {
+               printk(KERN_ERR "No specific ops defined!\n");
+               BUG();
        }
-       dma->direction = PCI_DMA_NONE;
-       return 0;
-}
-
-/* --------------------------------------------------------------------- */
 
-void* videobuf_alloc(unsigned int size)
-{
-       struct videobuf_buffer *vb;
+       vb = q->int_ops->alloc(q->msize);
 
-       vb = kzalloc(size,GFP_KERNEL);
        if (NULL != vb) {
-               videobuf_dma_init(&vb->dma);
                init_waitqueue_head(&vb->done);
                vb->magic     = MAGIC_BUFFER;
        }
+
        return vb;
 }
 
@@ -338,127 +88,65 @@ int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr)
        return retval;
 }
 
-int
-videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
-               struct v4l2_framebuffer *fbuf)
+int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
+                   struct v4l2_framebuffer *fbuf)
 {
-       int err,pages;
-       dma_addr_t bus;
-
        MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
-       switch (vb->memory) {
-       case V4L2_MEMORY_MMAP:
-       case V4L2_MEMORY_USERPTR:
-               if (0 == vb->baddr) {
-                       /* no userspace addr -- kernel bounce buffer */
-                       pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
-                       err = videobuf_dma_init_kernel(&vb->dma,PCI_DMA_FROMDEVICE,
-                                                      pages);
-                       if (0 != err)
-                               return err;
-               } else {
-                       /* dma directly to userspace */
-                       err = videobuf_dma_init_user(&vb->dma,PCI_DMA_FROMDEVICE,
-                                                    vb->baddr,vb->bsize);
-                       if (0 != err)
-                               return err;
-               }
-               break;
-       case V4L2_MEMORY_OVERLAY:
-               if (NULL == fbuf)
-                       return -EINVAL;
-               /* FIXME: need sanity checks for vb->boff */
-               /*
-                * Using a double cast to avoid compiler warnings when
-                * building for PAE. Compiler doesn't like direct casting
-                * of a 32 bit ptr to 64 bit integer.
-                */
-               bus   = (dma_addr_t)(unsigned long)fbuf->base + vb->boff;
-               pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
-               err = videobuf_dma_init_overlay(&vb->dma,PCI_DMA_FROMDEVICE,
-                                               bus, pages);
-               if (0 != err)
-                       return err;
-               break;
-       default:
-               BUG();
-       }
-       err = videobuf_dma_map(q,&vb->dma);
-       if (0 != err)
-               return err;
-
-       return 0;
-}
-
-/* --------------------------------------------------------------------- */
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
 
-void videobuf_queue_pci(struct videobuf_queue* q)
-{
-       /* If not specified, defaults to PCI map sg */
-       if (!q->ops->vb_map_sg)
-               q->ops->vb_map_sg=(vb_map_sg_t *)pci_map_sg;
-
-       if (!q->ops->vb_dma_sync_sg)
-               q->ops->vb_dma_sync_sg=(vb_map_sg_t *)pci_dma_sync_sg_for_cpu;
-       if (!q->ops->vb_unmap_sg)
-               q->ops->vb_unmap_sg=(vb_map_sg_t *)pci_unmap_sg;
-}
-
-int videobuf_pci_dma_map(struct pci_dev *pci,struct videobuf_dmabuf *dma)
-{
-       struct videobuf_queue q;
-       struct videobuf_queue_ops qops;
+       /* FIXME: This is required to avoid OOPS on some cases, since mmap_mapper()
+          method should be called before _iolock.
+          On some cases, the mmap_mapper() is called only after scheduling.
 
-       q.dev=pci;
-       qops.vb_map_sg=(vb_map_sg_t *)pci_map_sg;
-       qops.vb_unmap_sg=(vb_map_sg_t *)pci_unmap_sg;
-       q.ops = &qops;
+          However, this way is just too dirty! Better to wait for some event.
+        */
+       schedule_timeout(HZ);
 
-       return (videobuf_dma_map(&q,dma));
+       return CALL(q,iolock,q,vb,fbuf);
 }
 
-int videobuf_pci_dma_unmap(struct pci_dev *pci,struct videobuf_dmabuf *dma)
-{
-       struct videobuf_queue q;
-       struct videobuf_queue_ops qops;
-
-       q.dev=pci;
-       qops.vb_map_sg=(vb_map_sg_t *)pci_map_sg;
-       qops.vb_unmap_sg=(vb_map_sg_t *)pci_unmap_sg;
-       q.ops = &qops;
+/* --------------------------------------------------------------------- */
 
-       return (videobuf_dma_unmap(&q,dma));
-}
 
-void videobuf_queue_init(struct videobuf_queue* q,
+void videobuf_queue_core_init(struct videobuf_queue* q,
                         struct videobuf_queue_ops *ops,
                         void *dev,
                         spinlock_t *irqlock,
                         enum v4l2_buf_type type,
                         enum v4l2_field field,
                         unsigned int msize,
-                        void *priv)
+                        void *priv,
+                        struct videobuf_qtype_ops *int_ops)
 {
        memset(q,0,sizeof(*q));
-       q->irqlock = irqlock;
-       q->dev     = dev;
-       q->type    = type;
-       q->field   = field;
-       q->msize   = msize;
-       q->ops     = ops;
+       q->irqlock   = irqlock;
+       q->dev       = dev;
+       q->type      = type;
+       q->field     = field;
+       q->msize     = msize;
+       q->ops       = ops;
        q->priv_data = priv;
+       q->int_ops   = int_ops;
 
-       videobuf_queue_pci(q);
+       /* All buffer operations are mandatory */
+       BUG_ON (!q->ops->buf_setup);
+       BUG_ON (!q->ops->buf_prepare);
+       BUG_ON (!q->ops->buf_queue);
+       BUG_ON (!q->ops->buf_release);
+
+       /* Having implementations for abstract methods are mandatory */
+       BUG_ON (!q->int_ops);
 
        mutex_init(&q->lock);
        INIT_LIST_HEAD(&q->stream);
 }
 
-int
-videobuf_queue_is_busy(struct videobuf_queue *q)
+int videobuf_queue_is_busy(struct videobuf_queue *q)
 {
        int i;
 
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
        if (q->streaming) {
                dprintk(1,"busy: streaming active\n");
                return 1;
@@ -490,8 +178,7 @@ videobuf_queue_is_busy(struct videobuf_queue *q)
        return 0;
 }
 
-void
-videobuf_queue_cancel(struct videobuf_queue *q)
+void videobuf_queue_cancel(struct videobuf_queue *q)
 {
        unsigned long flags=0;
        int i;
@@ -521,8 +208,7 @@ videobuf_queue_cancel(struct videobuf_queue *q)
 
 /* --------------------------------------------------------------------- */
 
-enum v4l2_field
-videobuf_next_field(struct videobuf_queue *q)
+enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
 {
        enum v4l2_field field = q->field;
 
@@ -540,11 +226,11 @@ videobuf_next_field(struct videobuf_queue *q)
        return field;
 }
 
-void
-videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb,
-               enum v4l2_buf_type type)
+static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
+                           struct videobuf_buffer *vb, enum v4l2_buf_type type)
 {
        MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
 
        b->index    = vb->i;
        b->type     = type;
@@ -595,8 +281,7 @@ videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb,
        b->sequence  = vb->field_count >> 1;
 }
 
-int
-videobuf_reqbufs(struct videobuf_queue *q,
+int videobuf_reqbufs(struct videobuf_queue *q,
                 struct v4l2_requestbuffers *req)
 {
        unsigned int size,count;
@@ -617,16 +302,18 @@ videobuf_reqbufs(struct videobuf_queue *q,
                return -EINVAL;
        }
 
+       mutex_lock(&q->lock);
        if (q->streaming) {
                dprintk(1,"reqbufs: streaming already exists\n");
-               return -EBUSY;
+               retval = -EBUSY;
+               goto done;
        }
        if (!list_empty(&q->stream)) {
                dprintk(1,"reqbufs: stream running\n");
-               return -EBUSY;
+               retval = -EBUSY;
+               goto done;
        }
 
-       mutex_lock(&q->lock);
        count = req->count;
        if (count > VIDEO_MAX_FRAME)
                count = VIDEO_MAX_FRAME;
@@ -642,15 +329,14 @@ videobuf_reqbufs(struct videobuf_queue *q,
                goto done;
        }
 
-       req->count = count;
+       req->count = retval;
 
  done:
        mutex_unlock(&q->lock);
        return retval;
 }
 
-int
-videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
+int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
 {
        if (unlikely(b->type != q->type)) {
                dprintk(1,"querybuf: Wrong type.\n");
@@ -664,12 +350,11 @@ videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
                dprintk(1,"querybuf: buffer is null.\n");
                return -EINVAL;
        }
-       videobuf_status(b,q->bufs[b->index],q->type);
+       videobuf_status(q,b,q->bufs[b->index],q->type);
        return 0;
 }
 
-int
-videobuf_qbuf(struct videobuf_queue *q,
+int videobuf_qbuf(struct videobuf_queue *q,
              struct v4l2_buffer *b)
 {
        struct videobuf_buffer *buf;
@@ -677,6 +362,11 @@ videobuf_qbuf(struct videobuf_queue *q,
        unsigned long flags=0;
        int retval;
 
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
+       if (b->memory == V4L2_MEMORY_MMAP)
+               down_read(&current->mm->mmap_sem);
+
        mutex_lock(&q->lock);
        retval = -EBUSY;
        if (q->reading) {
@@ -762,16 +452,21 @@ videobuf_qbuf(struct videobuf_queue *q,
 
  done:
        mutex_unlock(&q->lock);
+
+       if (b->memory == V4L2_MEMORY_MMAP)
+               up_read(&current->mm->mmap_sem);
+
        return retval;
 }
 
-int
-videobuf_dqbuf(struct videobuf_queue *q,
+int videobuf_dqbuf(struct videobuf_queue *q,
               struct v4l2_buffer *b, int nonblocking)
 {
        struct videobuf_buffer *buf;
        int retval;
 
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
        mutex_lock(&q->lock);
        retval = -EBUSY;
        if (q->reading) {
@@ -797,12 +492,12 @@ videobuf_dqbuf(struct videobuf_queue *q,
        case STATE_ERROR:
                dprintk(1,"dqbuf: state is error\n");
                retval = -EIO;
-               videobuf_dma_sync(q,&buf->dma);
+               CALL(q,sync,q, buf);
                buf->state = STATE_IDLE;
                break;
        case STATE_DONE:
                dprintk(1,"dqbuf: state is done\n");
-               videobuf_dma_sync(q,&buf->dma);
+               CALL(q,sync,q, buf);
                buf->state = STATE_IDLE;
                break;
        default:
@@ -812,7 +507,7 @@ videobuf_dqbuf(struct videobuf_queue *q,
        }
        list_del(&buf->stream);
        memset(b,0,sizeof(*b));
-       videobuf_status(b,buf,q->type);
+       videobuf_status(q,b,buf,q->type);
 
  done:
        mutex_unlock(&q->lock);
@@ -822,7 +517,6 @@ videobuf_dqbuf(struct videobuf_queue *q,
 int videobuf_streamon(struct videobuf_queue *q)
 {
        struct videobuf_buffer *buf;
-       struct list_head *list;
        unsigned long flags=0;
        int retval;
 
@@ -836,11 +530,9 @@ int videobuf_streamon(struct videobuf_queue *q)
        q->streaming = 1;
        if (q->irqlock)
                spin_lock_irqsave(q->irqlock,flags);
-       list_for_each(list,&q->stream) {
-               buf = list_entry(list, struct videobuf_buffer, stream);
+       list_for_each_entry(buf, &q->stream, stream)
                if (buf->state == STATE_PREPARED)
                        q->ops->buf_queue(q,buf);
-       }
        if (q->irqlock)
                spin_unlock_irqrestore(q->irqlock,flags);
 
@@ -865,22 +557,25 @@ int videobuf_streamoff(struct videobuf_queue *q)
        return retval;
 }
 
-static ssize_t
-videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
-                      size_t count, loff_t *ppos)
+static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
+                                     char __user *data,
+                                     size_t count, loff_t *ppos)
 {
        enum v4l2_field field;
        unsigned long flags=0;
        int retval;
 
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
        /* setup stuff */
-       q->read_buf = videobuf_alloc(q->msize);
+       q->read_buf = videobuf_alloc(q);
        if (NULL == q->read_buf)
                return -ENOMEM;
 
        q->read_buf->memory = V4L2_MEMORY_USERPTR;
        q->read_buf->baddr  = (unsigned long)data;
        q->read_buf->bsize  = count;
+
        field = videobuf_next_field(q);
        retval = q->ops->buf_prepare(q,q->read_buf,field);
        if (0 != retval)
@@ -894,7 +589,7 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
                spin_unlock_irqrestore(q->irqlock,flags);
        retval = videobuf_waiton(q->read_buf,0,0);
        if (0 == retval) {
-               videobuf_dma_sync(q,&q->read_buf->dma);
+               CALL(q,sync,q,q->read_buf);
                if (STATE_ERROR == q->read_buf->state)
                        retval = -EIO;
                else
@@ -915,13 +610,16 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
 {
        enum v4l2_field field;
        unsigned long flags=0;
-       unsigned size, nbufs, bytes;
+       unsigned size, nbufs;
        int retval;
 
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
        mutex_lock(&q->lock);
 
        nbufs = 1; size = 0;
        q->ops->buf_setup(q,&nbufs,&size);
+
        if (NULL == q->read_buf  &&
            count >= size        &&
            !nonblocking) {
@@ -935,7 +633,8 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
        if (NULL == q->read_buf) {
                /* need to capture a new frame */
                retval = -ENOMEM;
-               q->read_buf = videobuf_alloc(q->msize);
+               q->read_buf = videobuf_alloc(q);
+
                dprintk(1,"video alloc=0x%p\n", q->read_buf);
                if (NULL == q->read_buf)
                        goto done;
@@ -943,6 +642,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
                q->read_buf->bsize = count; /* preferred size */
                field = videobuf_next_field(q);
                retval = q->ops->buf_prepare(q,q->read_buf,field);
+
                if (0 != retval) {
                        kfree (q->read_buf);
                        q->read_buf = NULL;
@@ -950,6 +650,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
                }
                if (q->irqlock)
                        spin_lock_irqsave(q->irqlock,flags);
+
                q->ops->buf_queue(q,q->read_buf);
                if (q->irqlock)
                        spin_unlock_irqrestore(q->irqlock,flags);
@@ -960,7 +661,8 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
        retval = videobuf_waiton(q->read_buf, nonblocking, 1);
        if (0 != retval)
                goto done;
-       videobuf_dma_sync(q,&q->read_buf->dma);
+
+       CALL(q,sync,q,q->read_buf);
 
        if (STATE_ERROR == q->read_buf->state) {
                /* catch I/O errors */
@@ -971,16 +673,12 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
                goto done;
        }
 
-       /* copy to userspace */
-       bytes = count;
-       if (bytes > q->read_buf->size - q->read_off)
-               bytes = q->read_buf->size - q->read_off;
-       retval = -EFAULT;
-       if (copy_to_user(data, q->read_buf->dma.vmalloc+q->read_off, bytes))
+       /* Copy to userspace */
+       retval=CALL(q,copy_to_user,q,data,count,nonblocking);
+       if (retval<0)
                goto done;
 
-       retval = bytes;
-       q->read_off += bytes;
+       q->read_off += retval;
        if (q->read_off == q->read_buf->size) {
                /* all data copied, cleanup */
                q->ops->buf_release(q,q->read_buf);
@@ -997,7 +695,7 @@ int videobuf_read_start(struct videobuf_queue *q)
 {
        enum v4l2_field field;
        unsigned long flags=0;
-       int count = 0, size = 0;
+       unsigned int count = 0, size = 0;
        int err, i;
 
        q->ops->buf_setup(q,&count,&size);
@@ -1008,8 +706,11 @@ int videobuf_read_start(struct videobuf_queue *q)
        size = PAGE_ALIGN(size);
 
        err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR);
-       if (err)
+       if (err < 0)
                return err;
+
+       count = err;
+
        for (i = 0; i < count; i++) {
                field = videobuf_next_field(q);
                err = q->ops->buf_prepare(q,q->bufs[i],field);
@@ -1048,10 +749,11 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
                             char __user *data, size_t count, loff_t *ppos,
                             int vbihack, int nonblocking)
 {
-       unsigned int *fc, bytes;
-       int err, retval;
+       int rc, retval;
        unsigned long flags=0;
 
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
        dprintk(2,"%s\n",__FUNCTION__);
        mutex_lock(&q->lock);
        retval = -EBUSY;
@@ -1073,39 +775,23 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
                        list_del(&q->read_buf->stream);
                        q->read_off = 0;
                }
-               err = videobuf_waiton(q->read_buf, nonblocking, 1);
-               if (err < 0) {
+               rc = videobuf_waiton(q->read_buf, nonblocking, 1);
+               if (rc < 0) {
                        if (0 == retval)
-                               retval = err;
+                               retval = rc;
                        break;
                }
 
                if (q->read_buf->state == STATE_DONE) {
-                       if (vbihack) {
-                               /* dirty, undocumented hack -- pass the frame counter
-                                * within the last four bytes of each vbi data block.
-                                * We need that one to maintain backward compatibility
-                                * to all vbi decoding software out there ... */
-                               fc  = (unsigned int*)q->read_buf->dma.vmalloc;
-                               fc += (q->read_buf->size>>2) -1;
-                               *fc = q->read_buf->field_count >> 1;
-                               dprintk(1,"vbihack: %d\n",*fc);
-                       }
-
-                       /* copy stuff */
-                       bytes = count;
-                       if (bytes > q->read_buf->size - q->read_off)
-                               bytes = q->read_buf->size - q->read_off;
-                       if (copy_to_user(data + retval,
-                                        q->read_buf->dma.vmalloc + q->read_off,
-                                        bytes)) {
-                               if (0 == retval)
-                                       retval = -EFAULT;
+                       rc = CALL (q,copy_stream, q, data + retval, count,
+                                       retval, vbihack, nonblocking);
+                       if (rc < 0) {
+                               retval = rc;
                                break;
                        }
-                       count       -= bytes;
-                       retval      += bytes;
-                       q->read_off += bytes;
+                       retval      += rc;
+                       count       -= rc;
+                       q->read_off += rc;
                } else {
                        /* some error */
                        q->read_off = q->read_buf->size;
@@ -1172,81 +858,6 @@ unsigned int videobuf_poll_stream(struct file *file,
        return rc;
 }
 
-/* --------------------------------------------------------------------- */
-
-static void
-videobuf_vm_open(struct vm_area_struct *vma)
-{
-       struct videobuf_mapping *map = vma->vm_private_data;
-
-       dprintk(2,"vm_open %p [count=%d,vma=%08lx-%08lx]\n",map,
-               map->count,vma->vm_start,vma->vm_end);
-       map->count++;
-}
-
-static void
-videobuf_vm_close(struct vm_area_struct *vma)
-{
-       struct videobuf_mapping *map = vma->vm_private_data;
-       struct videobuf_queue *q = map->q;
-       int i;
-
-       dprintk(2,"vm_close %p [count=%d,vma=%08lx-%08lx]\n",map,
-               map->count,vma->vm_start,vma->vm_end);
-
-       map->count--;
-       if (0 == map->count) {
-               dprintk(1,"munmap %p q=%p\n",map,q);
-               mutex_lock(&q->lock);
-               for (i = 0; i < VIDEO_MAX_FRAME; i++) {
-                       if (NULL == q->bufs[i])
-                               continue;
-                       if (q->bufs[i])
-                               ;
-                       if (q->bufs[i]->map != map)
-                               continue;
-                       q->bufs[i]->map   = NULL;
-                       q->bufs[i]->baddr = 0;
-                       q->ops->buf_release(q,q->bufs[i]);
-               }
-               mutex_unlock(&q->lock);
-               kfree(map);
-       }
-       return;
-}
-
-/*
- * Get a anonymous page for the mapping.  Make sure we can DMA to that
- * memory location with 32bit PCI devices (i.e. don't use highmem for
- * now ...).  Bounce buffers don't work very well for the data rates
- * video capture has.
- */
-static struct page*
-videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
-                  int *type)
-{
-       struct page *page;
-
-       dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n",
-               vaddr,vma->vm_start,vma->vm_end);
-       if (vaddr > vma->vm_end)
-               return NOPAGE_SIGBUS;
-       page = alloc_page(GFP_USER | __GFP_DMA32);
-       if (!page)
-               return NOPAGE_OOM;
-       clear_user_page(page_address(page), vaddr, page);
-       if (type)
-               *type = VM_FAULT_MINOR;
-       return page;
-}
-
-static struct vm_operations_struct videobuf_vm_ops =
-{
-       .open     = videobuf_vm_open,
-       .close    = videobuf_vm_close,
-       .nopage   = videobuf_vm_nopage,
-};
-
 int videobuf_mmap_setup(struct videobuf_queue *q,
                        unsigned int bcount, unsigned int bsize,
                        enum v4l2_memory memory)
@@ -1254,12 +865,19 @@ int videobuf_mmap_setup(struct videobuf_queue *q,
        unsigned int i;
        int err;
 
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
        err = videobuf_mmap_free(q);
        if (0 != err)
                return err;
 
+       /* Allocate and initialize buffers */
        for (i = 0; i < bcount; i++) {
-               q->bufs[i] = videobuf_alloc(q->msize);
+               q->bufs[i] = videobuf_alloc(q);
+
+               if (q->bufs[i] == NULL)
+                       break;
+
                q->bufs[i]->i      = i;
                q->bufs[i]->input  = UNSET;
                q->bufs[i]->memory = memory;
@@ -1274,18 +892,30 @@ int videobuf_mmap_setup(struct videobuf_queue *q,
                        break;
                }
        }
+
+       if (!i)
+               return -ENOMEM;
+
        dprintk(1,"mmap setup: %d buffers, %d bytes each\n",
-               bcount,bsize);
-       return 0;
+               i, bsize);
+
+       return i;
 }
 
 int videobuf_mmap_free(struct videobuf_queue *q)
 {
        int i;
+       int rc;
+
+       if (!q)
+               return 0;
+
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
+       rc  = CALL(q,mmap_free,q);
+       if (rc<0)
+               return rc;
 
-       for (i = 0; i < VIDEO_MAX_FRAME; i++)
-               if (q->bufs[i] && q->bufs[i]->map)
-                       return -EBUSY;
        for (i = 0; i < VIDEO_MAX_FRAME; i++) {
                if (NULL == q->bufs[i])
                        continue;
@@ -1293,118 +923,69 @@ int videobuf_mmap_free(struct videobuf_queue *q)
                kfree(q->bufs[i]);
                q->bufs[i] = NULL;
        }
-       return 0;
+
+       return rc;
 }
 
 int videobuf_mmap_mapper(struct videobuf_queue *q,
                         struct vm_area_struct *vma)
 {
-       struct videobuf_mapping *map;
-       unsigned int first,last,size,i;
        int retval;
 
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
        mutex_lock(&q->lock);
-       retval = -EINVAL;
-       if (!(vma->vm_flags & VM_WRITE)) {
-               dprintk(1,"mmap app bug: PROT_WRITE please\n");
-               goto done;
-       }
-       if (!(vma->vm_flags & VM_SHARED)) {
-               dprintk(1,"mmap app bug: MAP_SHARED please\n");
-               goto done;
-       }
+       retval=CALL(q,mmap_mapper,q,vma);
+       mutex_unlock(&q->lock);
 
-       /* look for first buffer to map */
-       for (first = 0; first < VIDEO_MAX_FRAME; first++) {
-               if (NULL == q->bufs[first])
-                       continue;
-               if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
-                       continue;
-               if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
-                       break;
-       }
-       if (VIDEO_MAX_FRAME == first) {
-               dprintk(1,"mmap app bug: offset invalid [offset=0x%lx]\n",
-                       (vma->vm_pgoff << PAGE_SHIFT));
-               goto done;
-       }
+       return retval;
+}
 
-       /* look for last buffer to map */
-       for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) {
-               if (NULL == q->bufs[last])
-                       continue;
-               if (V4L2_MEMORY_MMAP != q->bufs[last]->memory)
-                       continue;
-               if (q->bufs[last]->map) {
-                       retval = -EBUSY;
-                       goto done;
-               }
-               size += q->bufs[last]->bsize;
-               if (size == (vma->vm_end - vma->vm_start))
-                       break;
-       }
-       if (VIDEO_MAX_FRAME == last) {
-               dprintk(1,"mmap app bug: size invalid [size=0x%lx]\n",
-                       (vma->vm_end - vma->vm_start));
-               goto done;
-       }
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+int videobuf_cgmbuf(struct videobuf_queue *q,
+                   struct video_mbuf *mbuf, int count)
+{
+       struct v4l2_requestbuffers req;
+       int rc,i;
 
-       /* create mapping + update buffer list */
-       retval = -ENOMEM;
-       map = kmalloc(sizeof(struct videobuf_mapping),GFP_KERNEL);
-       if (NULL == map)
-               goto done;
-       for (size = 0, i = first; i <= last; size += q->bufs[i++]->bsize) {
-               q->bufs[i]->map   = map;
-               q->bufs[i]->baddr = vma->vm_start + size;
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
+       memset(&req,0,sizeof(req));
+       req.type   = q->type;
+       req.count  = count;
+       req.memory = V4L2_MEMORY_MMAP;
+       rc = videobuf_reqbufs(q,&req);
+       if (rc < 0)
+               return rc;
+
+       mbuf->frames = req.count;
+       mbuf->size   = 0;
+       for (i = 0; i < mbuf->frames; i++) {
+               mbuf->offsets[i]  = q->bufs[i]->boff;
+               mbuf->size       += q->bufs[i]->bsize;
        }
-       map->count    = 1;
-       map->start    = vma->vm_start;
-       map->end      = vma->vm_end;
-       map->q        = q;
-       vma->vm_ops   = &videobuf_vm_ops;
-       vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
-       vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
-       vma->vm_private_data = map;
-       dprintk(1,"mmap %p: q=%p %08lx-%08lx pgoff %08lx bufs %d-%d\n",
-               map,q,vma->vm_start,vma->vm_end,vma->vm_pgoff,first,last);
-       retval = 0;
 
- done:
-       mutex_unlock(&q->lock);
-       return retval;
+       return 0;
 }
+#endif
 
 /* --------------------------------------------------------------------- */
 
-EXPORT_SYMBOL_GPL(videobuf_vmalloc_to_sg);
-
-EXPORT_SYMBOL_GPL(videobuf_dma_init);
-EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
-EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
-EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay);
-EXPORT_SYMBOL_GPL(videobuf_dma_map);
-EXPORT_SYMBOL_GPL(videobuf_dma_sync);
-EXPORT_SYMBOL_GPL(videobuf_dma_unmap);
-EXPORT_SYMBOL_GPL(videobuf_dma_free);
-
-EXPORT_SYMBOL_GPL(videobuf_pci_dma_map);
-EXPORT_SYMBOL_GPL(videobuf_pci_dma_unmap);
-
-EXPORT_SYMBOL_GPL(videobuf_alloc);
 EXPORT_SYMBOL_GPL(videobuf_waiton);
 EXPORT_SYMBOL_GPL(videobuf_iolock);
 
-EXPORT_SYMBOL_GPL(videobuf_queue_init);
+EXPORT_SYMBOL_GPL(videobuf_alloc);
+
+EXPORT_SYMBOL_GPL(videobuf_queue_core_init);
 EXPORT_SYMBOL_GPL(videobuf_queue_cancel);
 EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
 
 EXPORT_SYMBOL_GPL(videobuf_next_field);
-EXPORT_SYMBOL_GPL(videobuf_status);
 EXPORT_SYMBOL_GPL(videobuf_reqbufs);
 EXPORT_SYMBOL_GPL(videobuf_querybuf);
 EXPORT_SYMBOL_GPL(videobuf_qbuf);
 EXPORT_SYMBOL_GPL(videobuf_dqbuf);
+EXPORT_SYMBOL_GPL(videobuf_cgmbuf);
 EXPORT_SYMBOL_GPL(videobuf_streamon);
 EXPORT_SYMBOL_GPL(videobuf_streamoff);
 
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
new file mode 100644 (file)
index 0000000..8bb7fdd
--- /dev/null
@@ -0,0 +1,726 @@
+/*
+ * helper functions for PCI DMA video4linux capture buffers
+ *
+ * The functions expect the hardware being able to scatter gatter
+ * (i.e. the buffers are not linear in physical memory, but fragmented
+ * into PAGE_SIZE chunks).  They also assume the driver does not need
+ * to touch the video data.
+ *
+ * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
+ *
+ * Highly based on video-buf written originally by:
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
+ * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org>
+ * (c) 2006 Ted Walther and John Sokol
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <media/videobuf-dma-sg.h>
+
+#define MAGIC_DMABUF 0x19721112
+#define MAGIC_SG_MEM 0x17890714
+
+#define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \
+       { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); }
+
+static int debug = 0;
+module_param(debug, int, 0644);
+
+MODULE_DESCRIPTION("helper module to manage video4linux pci dma sg buffers");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
+MODULE_LICENSE("GPL");
+
+#define dprintk(level, fmt, arg...)    if (debug >= level) \
+       printk(KERN_DEBUG "vbuf-sg: " fmt , ## arg)
+
+/* --------------------------------------------------------------------- */
+
+struct scatterlist*
+videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
+{
+       struct scatterlist *sglist;
+       struct page *pg;
+       int i;
+
+       sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
+       if (NULL == sglist)
+               return NULL;
+       for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
+               pg = vmalloc_to_page(virt);
+               if (NULL == pg)
+                       goto err;
+               BUG_ON(PageHighMem(pg));
+               sglist[i].page   = pg;
+               sglist[i].length = PAGE_SIZE;
+       }
+       return sglist;
+
+ err:
+       kfree(sglist);
+       return NULL;
+}
+
+struct scatterlist*
+videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
+{
+       struct scatterlist *sglist;
+       int i = 0;
+
+       if (NULL == pages[0])
+               return NULL;
+       sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
+       if (NULL == sglist)
+               return NULL;
+
+       if (NULL == pages[0])
+               goto nopage;
+       if (PageHighMem(pages[0]))
+               /* DMA to highmem pages might not work */
+               goto highmem;
+       sglist[0].page   = pages[0];
+       sglist[0].offset = offset;
+       sglist[0].length = PAGE_SIZE - offset;
+       for (i = 1; i < nr_pages; i++) {
+               if (NULL == pages[i])
+                       goto nopage;
+               if (PageHighMem(pages[i]))
+                       goto highmem;
+               sglist[i].page   = pages[i];
+               sglist[i].length = PAGE_SIZE;
+       }
+       return sglist;
+
+ nopage:
+       dprintk(2,"sgl: oops - no page\n");
+       kfree(sglist);
+       return NULL;
+
+ highmem:
+       dprintk(2,"sgl: oops - highmem page\n");
+       kfree(sglist);
+       return NULL;
+}
+
+/* --------------------------------------------------------------------- */
+
+struct videobuf_dmabuf *videobuf_to_dma (struct videobuf_buffer *buf)
+{
+       struct videbuf_pci_sg_memory *mem=buf->priv;
+       BUG_ON (!mem);
+
+       MAGIC_CHECK(mem->magic,MAGIC_SG_MEM);
+
+       return &mem->dma;
+}
+
+void videobuf_dma_init(struct videobuf_dmabuf *dma)
+{
+       memset(dma,0,sizeof(*dma));
+       dma->magic = MAGIC_DMABUF;
+}
+
+static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
+                       int direction, unsigned long data, unsigned long size)
+{
+       unsigned long first,last;
+       int err, rw = 0;
+
+       dma->direction = direction;
+       switch (dma->direction) {
+       case PCI_DMA_FROMDEVICE: rw = READ;  break;
+       case PCI_DMA_TODEVICE:   rw = WRITE; break;
+       default:                 BUG();
+       }
+
+       first = (data          & PAGE_MASK) >> PAGE_SHIFT;
+       last  = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT;
+       dma->offset   = data & ~PAGE_MASK;
+       dma->nr_pages = last-first+1;
+       dma->pages = kmalloc(dma->nr_pages * sizeof(struct page*),
+                            GFP_KERNEL);
+       if (NULL == dma->pages)
+               return -ENOMEM;
+       dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n",
+               data,size,dma->nr_pages);
+
+       dma->varea = (void *) data;
+
+
+       err = get_user_pages(current,current->mm,
+                            data & PAGE_MASK, dma->nr_pages,
+                            rw == READ, 1, /* force */
+                            dma->pages, NULL);
+
+       if (err != dma->nr_pages) {
+               dma->nr_pages = (err >= 0) ? err : 0;
+               dprintk(1,"get_user_pages: err=%d [%d]\n",err,dma->nr_pages);
+               return err < 0 ? err : -EINVAL;
+       }
+       return 0;
+}
+
+int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
+                          unsigned long data, unsigned long size)
+{
+       int ret;
+       down_read(&current->mm->mmap_sem);
+       ret = videobuf_dma_init_user_locked(dma, direction, data, size);
+       up_read(&current->mm->mmap_sem);
+
+       return ret;
+}
+
+int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
+                            int nr_pages)
+{
+       dprintk(1,"init kernel [%d pages]\n",nr_pages);
+       dma->direction = direction;
+       dma->vmalloc = vmalloc_32(nr_pages << PAGE_SHIFT);
+       if (NULL == dma->vmalloc) {
+               dprintk(1,"vmalloc_32(%d pages) failed\n",nr_pages);
+               return -ENOMEM;
+       }
+       dprintk(1,"vmalloc is at addr 0x%08lx, size=%d\n",
+                               (unsigned long)dma->vmalloc,
+                               nr_pages << PAGE_SHIFT);
+       memset(dma->vmalloc,0,nr_pages << PAGE_SHIFT);
+       dma->nr_pages = nr_pages;
+       return 0;
+}
+
+int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
+                             dma_addr_t addr, int nr_pages)
+{
+       dprintk(1,"init overlay [%d pages @ bus 0x%lx]\n",
+               nr_pages,(unsigned long)addr);
+       dma->direction = direction;
+       if (0 == addr)
+               return -EINVAL;
+
+       dma->bus_addr = addr;
+       dma->nr_pages = nr_pages;
+       return 0;
+}
+
+int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma)
+{
+       void                   *dev=q->dev;
+
+       MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
+       BUG_ON(0 == dma->nr_pages);
+
+       if (dma->pages) {
+               dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
+                                                  dma->offset);
+       }
+       if (dma->vmalloc) {
+               dma->sglist = videobuf_vmalloc_to_sg
+                                               (dma->vmalloc,dma->nr_pages);
+       }
+       if (dma->bus_addr) {
+               dma->sglist = kmalloc(sizeof(struct scatterlist), GFP_KERNEL);
+               if (NULL != dma->sglist) {
+                       dma->sglen  = 1;
+                       sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK;
+                       dma->sglist[0].offset           = dma->bus_addr & ~PAGE_MASK;
+                       sg_dma_len(&dma->sglist[0])     = dma->nr_pages * PAGE_SIZE;
+               }
+       }
+       if (NULL == dma->sglist) {
+               dprintk(1,"scatterlist is NULL\n");
+               return -ENOMEM;
+       }
+       if (!dma->bus_addr) {
+               dma->sglen = pci_map_sg(dev,dma->sglist,
+                                       dma->nr_pages, dma->direction);
+               if (0 == dma->sglen) {
+                       printk(KERN_WARNING
+                              "%s: videobuf_map_sg failed\n",__FUNCTION__);
+                       kfree(dma->sglist);
+                       dma->sglist = NULL;
+                       dma->sglen = 0;
+                       return -EIO;
+               }
+       }
+       return 0;
+}
+
+int videobuf_dma_sync(struct videobuf_queue *q,struct videobuf_dmabuf *dma)
+{
+       void                   *dev=q->dev;
+
+       MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
+       BUG_ON(!dma->sglen);
+
+       pci_dma_sync_sg_for_cpu (dev,dma->sglist,dma->nr_pages,dma->direction);
+       return 0;
+}
+
+int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma)
+{
+       void                   *dev=q->dev;
+
+       MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
+       if (!dma->sglen)
+               return 0;
+
+       pci_unmap_sg (dev,dma->sglist,dma->nr_pages,dma->direction);
+
+       kfree(dma->sglist);
+       dma->sglist = NULL;
+       dma->sglen = 0;
+       return 0;
+}
+
+int videobuf_dma_free(struct videobuf_dmabuf *dma)
+{
+       MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
+       BUG_ON(dma->sglen);
+
+       if (dma->pages) {
+               int i;
+               for (i=0; i < dma->nr_pages; i++)
+                       page_cache_release(dma->pages[i]);
+               kfree(dma->pages);
+               dma->pages = NULL;
+       }
+
+       vfree(dma->vmalloc);
+       dma->vmalloc = NULL;
+       dma->varea = NULL;
+
+       if (dma->bus_addr) {
+               dma->bus_addr = 0;
+       }
+       dma->direction = PCI_DMA_NONE;
+       return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+int videobuf_pci_dma_map(struct pci_dev *pci,struct videobuf_dmabuf *dma)
+{
+       struct videobuf_queue q;
+
+       q.dev=pci;
+
+       return (videobuf_dma_map(&q,dma));
+}
+
+int videobuf_pci_dma_unmap(struct pci_dev *pci,struct videobuf_dmabuf *dma)
+{
+       struct videobuf_queue q;
+
+       q.dev=pci;
+
+       return (videobuf_dma_unmap(&q,dma));
+}
+
+/* --------------------------------------------------------------------- */
+
+static void
+videobuf_vm_open(struct vm_area_struct *vma)
+{
+       struct videobuf_mapping *map = vma->vm_private_data;
+
+       dprintk(2,"vm_open %p [count=%d,vma=%08lx-%08lx]\n",map,
+               map->count,vma->vm_start,vma->vm_end);
+       map->count++;
+}
+
+static void
+videobuf_vm_close(struct vm_area_struct *vma)
+{
+       struct videobuf_mapping *map = vma->vm_private_data;
+       struct videobuf_queue *q = map->q;
+       struct videbuf_pci_sg_memory *mem;
+       int i;
+
+       dprintk(2,"vm_close %p [count=%d,vma=%08lx-%08lx]\n",map,
+               map->count,vma->vm_start,vma->vm_end);
+
+       map->count--;
+       if (0 == map->count) {
+               dprintk(1,"munmap %p q=%p\n",map,q);
+               mutex_lock(&q->lock);
+               for (i = 0; i < VIDEO_MAX_FRAME; i++) {
+                       if (NULL == q->bufs[i])
+                               continue;
+                       mem=q->bufs[i]->priv;
+
+                       if (!mem)
+                               continue;
+
+                       MAGIC_CHECK(mem->magic,MAGIC_SG_MEM);
+
+                       if (q->bufs[i]->map != map)
+                               continue;
+                       q->bufs[i]->map   = NULL;
+                       q->bufs[i]->baddr = 0;
+                       q->ops->buf_release(q,q->bufs[i]);
+               }
+               mutex_unlock(&q->lock);
+               kfree(map);
+       }
+       return;
+}
+
+/*
+ * Get a anonymous page for the mapping.  Make sure we can DMA to that
+ * memory location with 32bit PCI devices (i.e. don't use highmem for
+ * now ...).  Bounce buffers don't work very well for the data rates
+ * video capture has.
+ */
+static struct page*
+videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
+                  int *type)
+{
+       struct page *page;
+
+       dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n",
+               vaddr,vma->vm_start,vma->vm_end);
+       if (vaddr > vma->vm_end)
+               return NOPAGE_SIGBUS;
+       page = alloc_page(GFP_USER | __GFP_DMA32);
+       if (!page)
+               return NOPAGE_OOM;
+       clear_user_page(page_address(page), vaddr, page);
+       if (type)
+               *type = VM_FAULT_MINOR;
+       return page;
+}
+
+static struct vm_operations_struct videobuf_vm_ops =
+{
+       .open     = videobuf_vm_open,
+       .close    = videobuf_vm_close,
+       .nopage   = videobuf_vm_nopage,
+};
+
+/* ---------------------------------------------------------------------
+ * PCI handlers for the generic methods
+ */
+
+/* Allocated area consists on 3 parts:
+       struct video_buffer
+       struct <driver>_buffer (cx88_buffer, saa7134_buf, ...)
+       struct videobuf_pci_sg_memory
+ */
+
+static void *__videobuf_alloc(size_t size)
+{
+       struct videbuf_pci_sg_memory *mem;
+       struct videobuf_buffer *vb;
+
+       vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
+
+       mem = vb->priv = ((char *)vb)+size;
+       mem->magic=MAGIC_SG_MEM;
+
+       videobuf_dma_init(&mem->dma);
+
+       dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n",
+               __FUNCTION__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb),
+               mem,(long)sizeof(*mem));
+
+       return vb;
+}
+
+static int __videobuf_iolock (struct videobuf_queue* q,
+                             struct videobuf_buffer *vb,
+                             struct v4l2_framebuffer *fbuf)
+{
+       int err,pages;
+       dma_addr_t bus;
+       struct videbuf_pci_sg_memory *mem=vb->priv;
+       BUG_ON(!mem);
+
+       MAGIC_CHECK(mem->magic,MAGIC_SG_MEM);
+
+       switch (vb->memory) {
+       case V4L2_MEMORY_MMAP:
+       case V4L2_MEMORY_USERPTR:
+               if (0 == vb->baddr) {
+                       /* no userspace addr -- kernel bounce buffer */
+                       pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
+                       err = videobuf_dma_init_kernel( &mem->dma,
+                                                       PCI_DMA_FROMDEVICE,
+                                                       pages );
+                       if (0 != err)
+                               return err;
+               } else if (vb->memory == V4L2_MEMORY_USERPTR) {
+                       /* dma directly to userspace */
+                       err = videobuf_dma_init_user( &mem->dma,
+                                                     PCI_DMA_FROMDEVICE,
+                                                     vb->baddr,vb->bsize );
+                       if (0 != err)
+                               return err;
+               } else {
+                       /* NOTE: HACK: videobuf_iolock on V4L2_MEMORY_MMAP
+                       buffers can only be called from videobuf_qbuf
+                       we take current->mm->mmap_sem there, to prevent
+                       locking inversion, so don't take it here */
+
+                       err = videobuf_dma_init_user_locked(&mem->dma,
+                                                     PCI_DMA_FROMDEVICE,
+                                                     vb->baddr, vb->bsize);
+                       if (0 != err)
+                               return err;
+               }
+               break;
+       case V4L2_MEMORY_OVERLAY:
+               if (NULL == fbuf)
+                       return -EINVAL;
+               /* FIXME: need sanity checks for vb->boff */
+               /*
+                * Using a double cast to avoid compiler warnings when
+                * building for PAE. Compiler doesn't like direct casting
+                * of a 32 bit ptr to 64 bit integer.
+                */
+               bus   = (dma_addr_t)(unsigned long)fbuf->base + vb->boff;
+               pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
+               err = videobuf_dma_init_overlay(&mem->dma,PCI_DMA_FROMDEVICE,
+                                               bus, pages);
+               if (0 != err)
+                       return err;
+               break;
+       default:
+               BUG();
+       }
+       err = videobuf_dma_map(q,&mem->dma);
+       if (0 != err)
+               return err;
+
+       return 0;
+}
+
+static int __videobuf_sync(struct videobuf_queue *q,
+                          struct videobuf_buffer *buf)
+{
+       struct videbuf_pci_sg_memory *mem=buf->priv;
+       BUG_ON (!mem);
+       MAGIC_CHECK(mem->magic,MAGIC_SG_MEM);
+
+       return  videobuf_dma_sync(q,&mem->dma);
+}
+
+static int __videobuf_mmap_free(struct videobuf_queue *q)
+{
+       int i;
+
+       for (i = 0; i < VIDEO_MAX_FRAME; i++) {
+               if (q->bufs[i]) {
+                       if (q->bufs[i]->map)
+                               return -EBUSY;
+               }
+       }
+
+       return 0;
+}
+
+static int __videobuf_mmap_mapper(struct videobuf_queue *q,
+                        struct vm_area_struct *vma)
+{
+       struct videbuf_pci_sg_memory *mem;
+       struct videobuf_mapping *map;
+       unsigned int first,last,size,i;
+       int retval;
+
+       retval = -EINVAL;
+       if (!(vma->vm_flags & VM_WRITE)) {
+               dprintk(1,"mmap app bug: PROT_WRITE please\n");
+               goto done;
+       }
+       if (!(vma->vm_flags & VM_SHARED)) {
+               dprintk(1,"mmap app bug: MAP_SHARED please\n");
+               goto done;
+       }
+
+       /* look for first buffer to map */
+       for (first = 0; first < VIDEO_MAX_FRAME; first++) {
+               if (NULL == q->bufs[first])
+                       continue;
+               mem=q->bufs[first]->priv;
+               BUG_ON (!mem);
+               MAGIC_CHECK(mem->magic,MAGIC_SG_MEM);
+
+               if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
+                       continue;
+               if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
+                       break;
+       }
+       if (VIDEO_MAX_FRAME == first) {
+               dprintk(1,"mmap app bug: offset invalid [offset=0x%lx]\n",
+                       (vma->vm_pgoff << PAGE_SHIFT));
+               goto done;
+       }
+
+       /* look for last buffer to map */
+       for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) {
+               if (NULL == q->bufs[last])
+                       continue;
+               if (V4L2_MEMORY_MMAP != q->bufs[last]->memory)
+                       continue;
+               if (q->bufs[last]->map) {
+                       retval = -EBUSY;
+                       goto done;
+               }
+               size += q->bufs[last]->bsize;
+               if (size == (vma->vm_end - vma->vm_start))
+                       break;
+       }
+       if (VIDEO_MAX_FRAME == last) {
+               dprintk(1,"mmap app bug: size invalid [size=0x%lx]\n",
+                       (vma->vm_end - vma->vm_start));
+               goto done;
+       }
+
+       /* create mapping + update buffer list */
+       retval = -ENOMEM;
+       map = kmalloc(sizeof(struct videobuf_mapping),GFP_KERNEL);
+       if (NULL == map)
+               goto done;
+       for (size = 0, i = first; i <= last; size += q->bufs[i++]->bsize) {
+               q->bufs[i]->map   = map;
+               q->bufs[i]->baddr = vma->vm_start + size;
+       }
+       map->count    = 1;
+       map->start    = vma->vm_start;
+       map->end      = vma->vm_end;
+       map->q        = q;
+       vma->vm_ops   = &videobuf_vm_ops;
+       vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+       vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
+       vma->vm_private_data = map;
+       dprintk(1,"mmap %p: q=%p %08lx-%08lx pgoff %08lx bufs %d-%d\n",
+               map,q,vma->vm_start,vma->vm_end,vma->vm_pgoff,first,last);
+       retval = 0;
+
+ done:
+       return retval;
+}
+
+static int __videobuf_copy_to_user ( struct videobuf_queue *q,
+                               char __user *data, size_t count,
+                               int nonblocking )
+{
+       struct videbuf_pci_sg_memory *mem=q->read_buf->priv;
+       BUG_ON (!mem);
+       MAGIC_CHECK(mem->magic,MAGIC_SG_MEM);
+
+       /* copy to userspace */
+       if (count > q->read_buf->size - q->read_off)
+               count = q->read_buf->size - q->read_off;
+
+       if (copy_to_user(data, mem->dma.vmalloc+q->read_off, count))
+               return -EFAULT;
+
+       return count;
+}
+
+static int __videobuf_copy_stream ( struct videobuf_queue *q,
+                               char __user *data, size_t count, size_t pos,
+                               int vbihack, int nonblocking )
+{
+       unsigned int  *fc;
+       struct videbuf_pci_sg_memory *mem=q->read_buf->priv;
+       BUG_ON (!mem);
+       MAGIC_CHECK(mem->magic,MAGIC_SG_MEM);
+
+       if (vbihack) {
+               /* dirty, undocumented hack -- pass the frame counter
+                       * within the last four bytes of each vbi data block.
+                       * We need that one to maintain backward compatibility
+                       * to all vbi decoding software out there ... */
+               fc  = (unsigned int*)mem->dma.vmalloc;
+               fc += (q->read_buf->size>>2) -1;
+               *fc = q->read_buf->field_count >> 1;
+               dprintk(1,"vbihack: %d\n",*fc);
+       }
+
+       /* copy stuff using the common method */
+       count = __videobuf_copy_to_user (q,data,count,nonblocking);
+
+       if ( (count==-EFAULT) && (0 == pos) )
+               return -EFAULT;
+
+       return count;
+}
+
+static struct videobuf_qtype_ops pci_ops = {
+       .magic        = MAGIC_QTYPE_OPS,
+
+       .alloc        = __videobuf_alloc,
+       .iolock       = __videobuf_iolock,
+       .sync         = __videobuf_sync,
+       .mmap_free    = __videobuf_mmap_free,
+       .mmap_mapper  = __videobuf_mmap_mapper,
+       .copy_to_user = __videobuf_copy_to_user,
+       .copy_stream  = __videobuf_copy_stream,
+};
+
+void *videobuf_pci_alloc (size_t size)
+{
+       struct videobuf_queue q;
+
+       /* Required to make generic handler to call __videobuf_alloc */
+       q.int_ops=&pci_ops;
+
+       q.msize=size;
+
+       return videobuf_alloc (&q);
+}
+
+void videobuf_queue_pci_init(struct videobuf_queue* q,
+                        struct videobuf_queue_ops *ops,
+                        void *dev,
+                        spinlock_t *irqlock,
+                        enum v4l2_buf_type type,
+                        enum v4l2_field field,
+                        unsigned int msize,
+                        void *priv)
+{
+       videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
+                                priv, &pci_ops);
+}
+
+/* --------------------------------------------------------------------- */
+
+EXPORT_SYMBOL_GPL(videobuf_vmalloc_to_sg);
+
+EXPORT_SYMBOL_GPL(videobuf_to_dma);
+EXPORT_SYMBOL_GPL(videobuf_dma_init);
+EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
+EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
+EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay);
+EXPORT_SYMBOL_GPL(videobuf_dma_map);
+EXPORT_SYMBOL_GPL(videobuf_dma_sync);
+EXPORT_SYMBOL_GPL(videobuf_dma_unmap);
+EXPORT_SYMBOL_GPL(videobuf_dma_free);
+
+EXPORT_SYMBOL_GPL(videobuf_pci_dma_map);
+EXPORT_SYMBOL_GPL(videobuf_pci_dma_unmap);
+EXPORT_SYMBOL_GPL(videobuf_pci_alloc);
+
+EXPORT_SYMBOL_GPL(videobuf_queue_pci_init);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
similarity index 97%
rename from drivers/media/video/video-buf-dvb.c
rename to drivers/media/video/videobuf-dvb.c
index e617925ba31e495c79b70e552eb5cc040871208f..880317e04a02ba057462955235910bf109428708 100644 (file)
@@ -22,8 +22,8 @@
 #include <linux/file.h>
 #include <linux/freezer.h>
 
-#include <media/video-buf.h>
-#include <media/video-buf-dvb.h>
+#include <media/videobuf-dma-sg.h>
+#include <media/videobuf-dvb.h>
 
 /* ------------------------------------------------------------------ */
 
@@ -45,6 +45,7 @@ static int videobuf_dvb_thread(void *data)
        struct videobuf_buffer *buf;
        unsigned long flags;
        int err;
+       struct videobuf_dmabuf *dma;
 
        dprintk("dvb thread started\n");
        set_freezable();
@@ -56,7 +57,6 @@ static int videobuf_dvb_thread(void *data)
                                 struct videobuf_buffer, stream);
                list_del(&buf->stream);
                err = videobuf_waiton(buf,0,1);
-               BUG_ON(0 != err);
 
                /* no more feeds left or stop_feed() asked us to quit */
                if (0 == dvb->nfeeds)
@@ -66,8 +66,9 @@ static int videobuf_dvb_thread(void *data)
                try_to_freeze();
 
                /* feed buffer data to demux */
+               dma=videobuf_to_dma(buf);
                if (buf->state == STATE_DONE)
-                       dvb_dmx_swfilter(&dvb->demux, buf->dma.vmalloc,
+                       dvb_dmx_swfilter(&dvb->demux, dma->vmalloc,
                                         buf->size);
 
                /* requeue buffer */
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
new file mode 100644 (file)
index 0000000..2e3689a
--- /dev/null
@@ -0,0 +1,370 @@
+/*
+ * helper functions for vmalloc video4linux capture buffers
+ *
+ * The functions expect the hardware being able to scatter gatter
+ * (i.e. the buffers are not linear in physical memory, but fragmented
+ * into PAGE_SIZE chunks).  They also assume the driver does not need
+ * to touch the video data.
+ *
+ * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <media/videobuf-vmalloc.h>
+
+#define MAGIC_DMABUF   0x17760309
+#define MAGIC_VMAL_MEM 0x18221223
+
+#define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \
+       { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); }
+
+static int debug = 0;
+module_param(debug, int, 0644);
+
+MODULE_DESCRIPTION("helper module to manage video4linux vmalloc buffers");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
+MODULE_LICENSE("GPL");
+
+#define dprintk(level, fmt, arg...)    if (debug >= level) \
+       printk(KERN_DEBUG "vbuf-sg: " fmt , ## arg)
+
+
+/***************************************************************************/
+
+static void
+videobuf_vm_open(struct vm_area_struct *vma)
+{
+       struct videobuf_mapping *map = vma->vm_private_data;
+
+       dprintk(2,"vm_open %p [count=%d,vma=%08lx-%08lx]\n",map,
+               map->count,vma->vm_start,vma->vm_end);
+
+       map->count++;
+}
+
+static void
+videobuf_vm_close(struct vm_area_struct *vma)
+{
+       struct videobuf_mapping *map = vma->vm_private_data;
+       struct videobuf_queue *q = map->q;
+       int i;
+
+       dprintk(2,"vm_close %p [count=%d,vma=%08lx-%08lx]\n",map,
+               map->count,vma->vm_start,vma->vm_end);
+
+       map->count--;
+       if (0 == map->count) {
+               dprintk(1,"munmap %p q=%p\n",map,q);
+               mutex_lock(&q->lock);
+               for (i = 0; i < VIDEO_MAX_FRAME; i++) {
+                       if (NULL == q->bufs[i])
+                               continue;
+
+                       if (q->bufs[i]->map != map)
+                               continue;
+
+                       q->ops->buf_release(q,q->bufs[i]);
+
+                       q->bufs[i]->map   = NULL;
+                       q->bufs[i]->baddr = 0;
+               }
+               mutex_unlock(&q->lock);
+               kfree(map);
+       }
+       return;
+}
+
+static struct vm_operations_struct videobuf_vm_ops =
+{
+       .open     = videobuf_vm_open,
+       .close    = videobuf_vm_close,
+};
+
+/* ---------------------------------------------------------------------
+ * vmalloc handlers for the generic methods
+ */
+
+/* Allocated area consists on 3 parts:
+       struct video_buffer
+       struct <driver>_buffer (cx88_buffer, saa7134_buf, ...)
+       struct videobuf_pci_sg_memory
+ */
+
+static void *__videobuf_alloc(size_t size)
+{
+       struct videbuf_vmalloc_memory *mem;
+       struct videobuf_buffer *vb;
+
+       vb = kzalloc(size+sizeof(*mem),GFP_KERNEL);
+
+       mem = vb->priv = ((char *)vb)+size;
+       mem->magic=MAGIC_VMAL_MEM;
+
+       dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n",
+               __FUNCTION__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb),
+               mem,(long)sizeof(*mem));
+
+       return vb;
+}
+
+static int __videobuf_iolock (struct videobuf_queue* q,
+                             struct videobuf_buffer *vb,
+                             struct v4l2_framebuffer *fbuf)
+{
+       int pages;
+
+       struct videbuf_vmalloc_memory *mem=vb->priv;
+
+
+       BUG_ON(!mem);
+
+       MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
+
+       pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT;
+
+       /* Currently, doesn't support V4L2_MEMORY_OVERLAY */
+       if ((vb->memory != V4L2_MEMORY_MMAP) &&
+                               (vb->memory != V4L2_MEMORY_USERPTR) ) {
+               printk(KERN_ERR "Method currently unsupported.\n");
+               return -EINVAL;
+       }
+
+       /* FIXME: should be tested with kernel mmap mem */
+       mem->vmalloc=vmalloc_user (PAGE_ALIGN(vb->size));
+       if (NULL == mem->vmalloc) {
+               printk(KERN_ERR "vmalloc (%d pages) failed\n",pages);
+               return -ENOMEM;
+       }
+
+       dprintk(1,"vmalloc is at addr 0x%08lx, size=%d\n",
+                               (unsigned long)mem->vmalloc,
+                               pages << PAGE_SHIFT);
+
+       /* It seems that some kernel versions need to do remap *after*
+          the mmap() call
+        */
+       if (mem->vma) {
+               int retval=remap_vmalloc_range(mem->vma, mem->vmalloc,0);
+               kfree(mem->vma);
+               mem->vma=NULL;
+               if (retval<0) {
+                       dprintk(1,"mmap app bug: remap_vmalloc_range area %p error %d\n",
+                               mem->vmalloc,retval);
+                       return retval;
+               }
+       }
+
+       return 0;
+}
+
+static int __videobuf_sync(struct videobuf_queue *q,
+                          struct videobuf_buffer *buf)
+{
+       return 0;
+}
+
+static int __videobuf_mmap_free(struct videobuf_queue *q)
+{
+       unsigned int i;
+
+       for (i = 0; i < VIDEO_MAX_FRAME; i++) {
+               if (q->bufs[i]) {
+                       if (q->bufs[i]->map)
+                               return -EBUSY;
+               }
+       }
+
+       return 0;
+}
+
+static int __videobuf_mmap_mapper(struct videobuf_queue *q,
+                        struct vm_area_struct *vma)
+{
+       struct videbuf_vmalloc_memory *mem;
+       struct videobuf_mapping *map;
+       unsigned int first;
+       int retval;
+       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+
+       if (! (vma->vm_flags & VM_WRITE) || ! (vma->vm_flags & VM_SHARED))
+               return -EINVAL;
+
+       /* look for first buffer to map */
+       for (first = 0; first < VIDEO_MAX_FRAME; first++) {
+               if (NULL == q->bufs[first])
+                       continue;
+
+               if (V4L2_MEMORY_MMAP != q->bufs[first]->memory)
+                       continue;
+               if (q->bufs[first]->boff == offset)
+                       break;
+       }
+       if (VIDEO_MAX_FRAME == first) {
+               dprintk(1,"mmap app bug: offset invalid [offset=0x%lx]\n",
+                       (vma->vm_pgoff << PAGE_SHIFT));
+               return -EINVAL;
+       }
+
+       /* create mapping + update buffer list */
+       map = q->bufs[first]->map = kmalloc(sizeof(struct videobuf_mapping),GFP_KERNEL);
+       if (NULL == map)
+               return -ENOMEM;
+
+       map->start = vma->vm_start;
+       map->end   = vma->vm_end;
+       map->q     = q;
+
+       q->bufs[first]->baddr = vma->vm_start;
+
+       vma->vm_ops          = &videobuf_vm_ops;
+       vma->vm_flags       |= VM_DONTEXPAND | VM_RESERVED;
+       vma->vm_private_data = map;
+
+       mem=q->bufs[first]->priv;
+       BUG_ON (!mem);
+       MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
+
+       /* Try to remap memory */
+       retval=remap_vmalloc_range(vma, mem->vmalloc,0);
+       if (retval<0) {
+               dprintk(1,"mmap: postponing remap_vmalloc_range\n");
+
+               mem->vma=kmalloc(sizeof(*vma),GFP_KERNEL);
+               if (!mem->vma) {
+                       kfree(map);
+                       q->bufs[first]->map=NULL;
+                       return -ENOMEM;
+               }
+               memcpy(mem->vma,vma,sizeof(*vma));
+       }
+
+       dprintk(1,"mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
+               map,q,vma->vm_start,vma->vm_end,
+               (long int) q->bufs[first]->bsize,
+               vma->vm_pgoff,first);
+
+       videobuf_vm_open(vma);
+
+       return (0);
+}
+
+static int __videobuf_copy_to_user ( struct videobuf_queue *q,
+                               char __user *data, size_t count,
+                               int nonblocking )
+{
+       struct videbuf_vmalloc_memory *mem=q->read_buf->priv;
+       BUG_ON (!mem);
+       MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
+
+       BUG_ON (!mem->vmalloc);
+
+       /* copy to userspace */
+       if (count > q->read_buf->size - q->read_off)
+               count = q->read_buf->size - q->read_off;
+
+       if (copy_to_user(data, mem->vmalloc+q->read_off, count))
+               return -EFAULT;
+
+       return count;
+}
+
+static int __videobuf_copy_stream ( struct videobuf_queue *q,
+                               char __user *data, size_t count, size_t pos,
+                               int vbihack, int nonblocking )
+{
+       unsigned int  *fc;
+       struct videbuf_vmalloc_memory *mem=q->read_buf->priv;
+       BUG_ON (!mem);
+       MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
+
+       if (vbihack) {
+               /* dirty, undocumented hack -- pass the frame counter
+                       * within the last four bytes of each vbi data block.
+                       * We need that one to maintain backward compatibility
+                       * to all vbi decoding software out there ... */
+               fc  = (unsigned int*)mem->vmalloc;
+               fc += (q->read_buf->size>>2) -1;
+               *fc = q->read_buf->field_count >> 1;
+               dprintk(1,"vbihack: %d\n",*fc);
+       }
+
+       /* copy stuff using the common method */
+       count = __videobuf_copy_to_user (q,data,count,nonblocking);
+
+       if ( (count==-EFAULT) && (0 == pos) )
+               return -EFAULT;
+
+       return count;
+}
+
+static struct videobuf_qtype_ops qops = {
+       .magic        = MAGIC_QTYPE_OPS,
+
+       .alloc        = __videobuf_alloc,
+       .iolock       = __videobuf_iolock,
+       .sync         = __videobuf_sync,
+       .mmap_free    = __videobuf_mmap_free,
+       .mmap_mapper  = __videobuf_mmap_mapper,
+       .copy_to_user = __videobuf_copy_to_user,
+       .copy_stream  = __videobuf_copy_stream,
+};
+
+void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
+                        struct videobuf_queue_ops *ops,
+                        void *dev,
+                        spinlock_t *irqlock,
+                        enum v4l2_buf_type type,
+                        enum v4l2_field field,
+                        unsigned int msize,
+                        void *priv)
+{
+       videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
+                                priv, &qops);
+}
+
+EXPORT_SYMBOL_GPL(videobuf_queue_vmalloc_init);
+
+void *videobuf_to_vmalloc (struct videobuf_buffer *buf)
+{
+       struct videbuf_vmalloc_memory *mem=buf->priv;
+       BUG_ON (!mem);
+       MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
+
+       return mem->vmalloc;
+}
+EXPORT_SYMBOL_GPL(videobuf_to_vmalloc);
+
+void videobuf_vmalloc_free (struct videobuf_buffer *buf)
+{
+       struct videbuf_vmalloc_memory *mem=buf->priv;
+       BUG_ON (!mem);
+
+       MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM);
+
+       vfree(mem->vmalloc);
+       mem->vmalloc=NULL;
+
+       return;
+}
+EXPORT_SYMBOL_GPL(videobuf_vmalloc_free);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
index b876aca69c73673fadb42f5e9388488d030c3eb4..8d8e517b344f1a46ec3b30db7a4cdad1d9334413 100644 (file)
  *     sysfs stuff
  */
 
-static ssize_t show_name(struct class_device *cd, char *buf)
+static ssize_t show_name(struct device *cd,
+                        struct device_attribute *attr, char *buf)
 {
        struct video_device *vfd = container_of(cd, struct video_device,
-                                                               class_dev);
-       return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name);
+                                               class_dev);
+       return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);
 }
 
-static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-
 struct video_device *video_device_alloc(void)
 {
        struct video_device *vfd;
@@ -76,7 +75,7 @@ void video_device_release(struct video_device *vfd)
        kfree(vfd);
 }
 
-static void video_release(struct class_device *cd)
+static void video_release(struct device *cd)
 {
        struct video_device *vfd = container_of(cd, struct video_device,
                                                                class_dev);
@@ -89,9 +88,15 @@ static void video_release(struct class_device *cd)
        vfd->release(vfd);
 }
 
+static struct device_attribute video_device_attrs[] = {
+       __ATTR(name, S_IRUGO, show_name, NULL),
+       __ATTR_NULL
+};
+
 static struct class video_class = {
        .name    = VIDEO_NAME,
-       .release = video_release,
+       .dev_attrs = video_device_attrs,
+       .dev_release = video_release,
 };
 
 /*
@@ -448,7 +453,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
        if (cmd == VIDIOCGMBUF) {
                struct video_mbuf *p=arg;
 
-               memset(p,0,sizeof(p));
+               memset(p, 0, sizeof(*p));
 
                if (!vfd->vidiocgmbuf)
                        return ret;
@@ -1753,22 +1758,16 @@ int video_register_device(struct video_device *vfd, int type, int nr)
        /* sysfs class */
        memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
        if (vfd->dev)
-               vfd->class_dev.dev = vfd->dev;
+               vfd->class_dev.parent = vfd->dev;
        vfd->class_dev.class       = &video_class;
        vfd->class_dev.devt        = MKDEV(VIDEO_MAJOR, vfd->minor);
-       sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
-       ret = class_device_register(&vfd->class_dev);
+       sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base);
+       ret = device_register(&vfd->class_dev);
        if (ret < 0) {
-               printk(KERN_ERR "%s: class_device_register failed\n",
+               printk(KERN_ERR "%s: device_register failed\n",
                       __FUNCTION__);
                goto fail_minor;
        }
-       ret = class_device_create_file(&vfd->class_dev, &class_device_attr_name);
-       if (ret < 0) {
-               printk(KERN_ERR "%s: class_device_create_file 'name' failed\n",
-                      __FUNCTION__);
-               goto fail_classdev;
-       }
 
 #if 1
        /* needed until all drivers are fixed */
@@ -1779,8 +1778,6 @@ int video_register_device(struct video_device *vfd, int type, int nr)
 #endif
        return 0;
 
-fail_classdev:
-       class_device_unregister(&vfd->class_dev);
 fail_minor:
        mutex_lock(&videodev_lock);
        video_device[vfd->minor] = NULL;
@@ -1804,7 +1801,7 @@ void video_unregister_device(struct video_device *vfd)
                panic("videodev: bad unregister");
 
        video_device[vfd->minor]=NULL;
-       class_device_unregister(&vfd->class_dev);
+       device_unregister(&vfd->class_dev);
        mutex_unlock(&videodev_lock);
 }
 
index a0c1647a2ba460b95a03fa3161aefde5a206c272..9a03dc82c6cae270db019cc0e749f929214c97f8 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/moduleparam.h>
 #include <linux/time.h>
 #include <linux/version.h>
 
index f6d3a9460ccce1e0ca83ee27c0f466c11490cbbe..b532aa280a1be1b4b509b0f184de25e59b92d5df 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/videodev.h>
 #endif
 #include <linux/interrupt.h>
-#include <media/video-buf.h>
+#include <media/videobuf-vmalloc.h>
 #include <media/v4l2-common.h>
 #include <linux/kthread.h>
 #include <linux/highmem.h>
@@ -145,7 +145,6 @@ struct vivi_buffer {
        struct videobuf_buffer vb;
 
        struct vivi_fmt        *fmt;
-
 };
 
 struct vivi_dmaqueue {
@@ -171,7 +170,6 @@ struct vivi_dev {
        int                        users;
 
        /* various device info */
-       unsigned int               resources;
        struct video_device        vfd;
 
        struct vivi_dmaqueue       vidq;
@@ -230,9 +228,8 @@ static u8 bars[8][3] = {
 #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
 #define TSTAMP_MIN_X 64
 
-
 static void gen_line(char *basep,int inipos,int wmax,
-                    int hmax, int line, char *timestr)
+                    int hmax, int line, int count, char *timestr)
 {
        int  w,i,j,pos=inipos,y;
        char *p,*s;
@@ -243,9 +240,10 @@ static void gen_line(char *basep,int inipos,int wmax,
 
        /* Generate a standard color bar pattern */
        for (w=0;w<wmax;w++) {
-               r=bars[w*7/wmax][0];
-               g=bars[w*7/wmax][1];
-               b=bars[w*7/wmax][2];
+               int colorpos=((w+count)*8/(wmax+1)) % 8;
+               r=bars[colorpos][0];
+               g=bars[colorpos][1];
+               b=bars[colorpos][2];
 
                for (color=0;color<4;color++) {
                        p=basep+pos;
@@ -326,27 +324,27 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf)
        int hmax  = buf->vb.height;
        int wmax  = buf->vb.width;
        struct timeval ts;
-       char *tmpbuf;
-
-       if (buf->vb.dma.varea) {
-               tmpbuf=kmalloc (wmax*2, GFP_KERNEL);
-       } else {
-               tmpbuf=buf->vb.dma.vmalloc;
-       }
+       char *tmpbuf = kmalloc(wmax*2,GFP_KERNEL);
+       void *vbuf=videobuf_to_vmalloc (&buf->vb);
+       /* FIXME: move to dev struct */
+       static int mv_count=0;
 
+       if (!tmpbuf)
+               return;
 
        for (h=0;h<hmax;h++) {
-               if (buf->vb.dma.varea) {
-                       gen_line(tmpbuf,0,wmax,hmax,h,dev->timestr);
-                       /* FIXME: replacing to __copy_to_user */
-                       if (copy_to_user(buf->vb.dma.varea+pos,tmpbuf,wmax*2)!=0)
-                               dprintk(2,"vivifill copy_to_user failed.\n");
-               } else {
-                       gen_line(tmpbuf,pos,wmax,hmax,h,dev->timestr);
-               }
+               gen_line(tmpbuf,0,wmax,hmax,h,mv_count,
+                        dev->timestr);
+               /* FIXME: replacing to __copy_to_user */
+               if (copy_to_user(vbuf+pos,tmpbuf,wmax*2)!=0)
+                       dprintk(2,"vivifill copy_to_user failed.\n");
                pos += wmax*2;
        }
 
+       mv_count++;
+
+       kfree(tmpbuf);
+
        /* Updates stream time */
 
        dev->us+=jiffies_to_usecs(jiffies-dev->jiffies);
@@ -369,7 +367,7 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf)
                        dev->h,dev->m,dev->s,(dev->us+500)/1000);
 
        dprintk(2,"vivifill at %s: Buffer 0x%08lx size= %d\n",dev->timestr,
-                       (unsigned long)buf->vb.dma.varea,pos);
+                       (unsigned long)tmpbuf,pos);
 
        /* Advice that buffer was filled */
        buf->vb.state = STATE_DONE;
@@ -509,7 +507,6 @@ static void vivi_stop_thread(struct vivi_dmaqueue  *dma_q)
 static int restart_video_queue(struct vivi_dmaqueue *dma_q)
 {
        struct vivi_buffer *buf, *prev;
-       struct list_head *item;
 
        dprintk(1,"%s dma_q=0x%08lx\n",__FUNCTION__,(unsigned long)dma_q);
 
@@ -523,9 +520,7 @@ static int restart_video_queue(struct vivi_dmaqueue *dma_q)
 //             vivi_start_thread(dma_q);
 
                /* cancel all outstanding capture / vbi requests */
-               list_for_each(item,&dma_q->active) {
-                       buf = list_entry(item, struct vivi_buffer, vb.queue);
-
+               list_for_each_entry_safe(buf, prev, &dma_q->active, vb.queue) {
                        list_del(&buf->vb.queue);
                        buf->vb.state = STATE_ERROR;
                        wake_up(&buf->vb.done);
@@ -597,8 +592,12 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
 
        if (0 == *count)
                *count = 32;
+
        while (*size * *count > vid_limit * 1024 * 1024)
                (*count)--;
+
+       dprintk(1,"%s, count=%d, size=%d\n",__FUNCTION__,*count, *size);
+
        return 0;
 }
 
@@ -609,10 +608,8 @@ static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf)
        if (in_interrupt())
                BUG();
 
-
        videobuf_waiton(&buf->vb,0,0);
-       videobuf_dma_unmap(vq, &buf->vb.dma);
-       videobuf_dma_free(&buf->vb.dma);
+       videobuf_vmalloc_free(&buf->vb);
        buf->vb.state = STATE_NEEDS_INIT;
 }
 
@@ -626,7 +623,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
        struct vivi_buffer *buf = container_of(vb,struct vivi_buffer,vb);
        int rc, init_buffer = 0;
 
-//     dprintk(1,"%s, field=%d\n",__FUNCTION__,field);
+       dprintk(1,"%s, field=%d\n",__FUNCTION__,field);
 
        BUG_ON(NULL == fh->fmt);
        if (fh->width  < 48 || fh->width  > norm_maxw() ||
@@ -718,53 +715,13 @@ static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb
        free_buffer(vq,buf);
 }
 
-
 static struct videobuf_queue_ops vivi_video_qops = {
        .buf_setup      = buffer_setup,
        .buf_prepare    = buffer_prepare,
        .buf_queue      = buffer_queue,
        .buf_release    = buffer_release,
-
-       /* Non-pci handling routines */
-//     .vb_map_sg      = vivi_map_sg,
-//     .vb_dma_sync_sg = vivi_dma_sync_sg,
-//     .vb_unmap_sg    = vivi_unmap_sg,
 };
 
-/* ------------------------------------------------------------------
-       IOCTL handling
-   ------------------------------------------------------------------*/
-
-
-static int res_get(struct vivi_dev *dev, struct vivi_fh *fh)
-{
-       /* is it free? */
-       mutex_lock(&dev->lock);
-       if (dev->resources) {
-               /* no, someone else uses it */
-               mutex_unlock(&dev->lock);
-               return 0;
-       }
-       /* it's free, grab it */
-       dev->resources =1;
-       dprintk(1,"res: get\n");
-       mutex_unlock(&dev->lock);
-       return 1;
-}
-
-static int res_locked(struct vivi_dev *dev)
-{
-       return (dev->resources);
-}
-
-static void res_free(struct vivi_dev *dev, struct vivi_fh *fh)
-{
-       mutex_lock(&dev->lock);
-       dev->resources = 0;
-       dprintk(1,"res: put\n");
-       mutex_lock(&dev->lock);
-}
-
 /* ------------------------------------------------------------------
        IOCTL vidioc handling
    ------------------------------------------------------------------*/
@@ -825,8 +782,7 @@ static int vidioc_try_fmt_cap (struct file *file, void *priv,
        field = f->fmt.pix.field;
 
        if (field == V4L2_FIELD_ANY) {
-//             field=V4L2_FIELD_INTERLACED;
-               field=V4L2_FIELD_SEQ_TB;
+               field=V4L2_FIELD_INTERLACED;
        } else if (V4L2_FIELD_INTERLACED != field) {
                dprintk(1,"Field type invalid.\n");
                return -EINVAL;
@@ -904,57 +860,33 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
 static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf)
 {
        struct vivi_fh  *fh=priv;
-       struct videobuf_queue *q=&fh->vb_vidq;
-       struct v4l2_requestbuffers req;
-       unsigned int i;
-       int ret;
-
-       req.type   = q->type;
-       req.count  = 8;
-       req.memory = V4L2_MEMORY_MMAP;
-       ret = videobuf_reqbufs(q,&req);
-       if (ret < 0)
-               return (ret);
 
-       mbuf->frames = req.count;
-       mbuf->size   = 0;
-       for (i = 0; i < mbuf->frames; i++) {
-               mbuf->offsets[i]  = q->bufs[i]->boff;
-               mbuf->size       += q->bufs[i]->bsize;
-       }
-       return (0);
+       return videobuf_cgmbuf (&fh->vb_vidq, mbuf, 8);
 }
 #endif
 
 static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
        struct vivi_fh  *fh=priv;
-       struct vivi_dev *dev    = fh->dev;
 
        if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;
        if (i != fh->type)
                return -EINVAL;
 
-       if (!res_get(dev,fh))
-               return -EBUSY;
-       return (videobuf_streamon(&fh->vb_vidq));
+       return videobuf_streamon(&fh->vb_vidq);
 }
 
 static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 {
        struct vivi_fh  *fh=priv;
-       struct vivi_dev *dev    = fh->dev;
 
        if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                return -EINVAL;
        if (i != fh->type)
                return -EINVAL;
 
-       videobuf_streamoff(&fh->vb_vidq);
-       res_free(dev,fh);
-
-       return (0);
+       return videobuf_streamoff(&fh->vb_vidq);
 }
 
 static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *i)
@@ -1047,31 +979,25 @@ static int vidioc_s_ctrl (struct file *file, void *priv,
 static int vivi_open(struct inode *inode, struct file *file)
 {
        int minor = iminor(inode);
-       struct vivi_dev *h,*dev = NULL;
+       struct vivi_dev *dev;
        struct vivi_fh *fh;
-       struct list_head *list;
-       enum v4l2_buf_type type = 0;
        int i;
 
        printk(KERN_DEBUG "vivi: open called (minor=%d)\n",minor);
 
-       list_for_each(list,&vivi_devlist) {
-               h = list_entry(list, struct vivi_dev, vivi_devlist);
-               if (h->vfd.minor == minor) {
-                       dev  = h;
-                       type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-               }
-       }
-       if (NULL == dev)
-               return -ENODEV;
+       list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
+               if (dev->vfd.minor == minor)
+                       goto found;
+       return -ENODEV;
+found:
 
 
 
        /* If more than one user, mutex should be added */
        dev->users++;
 
-       dprintk(1,"open minor=%d type=%s users=%d\n",
-                               minor,v4l2_type_names[type],dev->users);
+       dprintk(1, "open minor=%d type=%s users=%d\n", minor,
+               v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
 
        /* allocate + initialize per filehandle data */
        fh = kzalloc(sizeof(*fh),GFP_KERNEL);
@@ -1106,7 +1032,7 @@ static int vivi_open(struct inode *inode, struct file *file)
        sprintf(dev->timestr,"%02d:%02d:%02d:%03d",
                        dev->h,dev->m,dev->s,(dev->us+500)/1000);
 
-       videobuf_queue_init(&fh->vb_vidq, &vivi_video_qops,
+       videobuf_queue_vmalloc_init(&fh->vb_vidq, &vivi_video_qops,
                        NULL, NULL,
                        fh->type,
                        V4L2_FIELD_INTERLACED,
@@ -1121,9 +1047,7 @@ vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
        struct vivi_fh        *fh = file->private_data;
 
        if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-               if (res_locked(fh->dev))
-                       return -EBUSY;
-               return videobuf_read_one(&fh->vb_vidq, data, count, ppos,
+               return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0,
                                        file->f_flags & O_NONBLOCK);
        }
        return 0;
@@ -1133,31 +1057,14 @@ static unsigned int
 vivi_poll(struct file *file, struct poll_table_struct *wait)
 {
        struct vivi_fh        *fh = file->private_data;
-       struct vivi_buffer    *buf;
+       struct videobuf_queue *q = &fh->vb_vidq;
 
        dprintk(1,"%s\n",__FUNCTION__);
 
        if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
                return POLLERR;
 
-       if (res_get(fh->dev,fh)) {
-               dprintk(1,"poll: mmap interface\n");
-               /* streaming capture */
-               if (list_empty(&fh->vb_vidq.stream))
-                       return POLLERR;
-               buf = list_entry(fh->vb_vidq.stream.next,struct vivi_buffer,vb.stream);
-       } else {
-               dprintk(1,"poll: read() interface\n");
-               /* read() capture */
-               buf = (struct vivi_buffer*)fh->vb_vidq.read_buf;
-               if (NULL == buf)
-                       return POLLERR;
-       }
-       poll_wait(file, &buf->vb.done, wait);
-       if (buf->vb.state == STATE_DONE ||
-           buf->vb.state == STATE_ERROR)
-               return POLLIN|POLLRDNORM;
-       return 0;
+       return videobuf_poll_stream(file, q, wait);
 }
 
 static int vivi_release(struct inode *inode, struct file *file)
@@ -1205,7 +1112,7 @@ static const struct file_operations vivi_fops = {
        .read           = vivi_read,
        .poll           = vivi_poll,
        .ioctl          = video_ioctl2, /* V4L2 ioctl handler */
-       .mmap           = vivi_mmap,
+       .mmap           = vivi_mmap,
        .llseek         = no_llseek,
 };
 
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
new file mode 100644 (file)
index 0000000..63002e0
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * vp27smpx - driver version 0.0.1
+ *
+ * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * Based on a tvaudio patch from Takahiro Adachi <tadachi@tadachi-net.com>
+ * and Kazuhiko Kawakami <kazz-0@mail.goo.ne.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/videodev.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+
+MODULE_DESCRIPTION("vp27smpx driver");
+MODULE_AUTHOR("Hans Verkuil");
+MODULE_LICENSE("GPL");
+
+static unsigned short normal_i2c[] = { 0xb6 >> 1, I2C_CLIENT_END };
+
+
+I2C_CLIENT_INSMOD;
+
+/* ----------------------------------------------------------------------- */
+
+struct vp27smpx_state {
+       int radio;
+       u32 audmode;
+};
+
+static void vp27smpx_set_audmode(struct i2c_client *client, u32 audmode)
+{
+       struct vp27smpx_state *state = i2c_get_clientdata(client);
+       u8 data[3] = { 0x00, 0x00, 0x04 };
+
+       switch (audmode) {
+               case V4L2_TUNER_MODE_MONO:
+               case V4L2_TUNER_MODE_LANG1:
+                       break;
+               case V4L2_TUNER_MODE_STEREO:
+               case V4L2_TUNER_MODE_LANG1_LANG2:
+                       data[1] = 0x01;
+                       break;
+               case V4L2_TUNER_MODE_LANG2:
+                       data[1] = 0x02;
+                       break;
+       }
+
+       if (i2c_master_send(client, data, sizeof(data)) != sizeof(data)) {
+               v4l_err(client, "%s: I/O error setting audmode\n", client->name);
+       }
+       else {
+               state->audmode = audmode;
+       }
+}
+
+static int vp27smpx_command(struct i2c_client *client, unsigned int cmd,
+                         void *arg)
+{
+       struct vp27smpx_state *state = i2c_get_clientdata(client);
+       struct v4l2_tuner *vt = arg;
+
+       switch (cmd) {
+       case AUDC_SET_RADIO:
+               state->radio = 1;
+               break;
+
+       case VIDIOC_S_STD:
+               state->radio = 0;
+               break;
+
+       case VIDIOC_S_TUNER:
+               if (!state->radio)
+                       vp27smpx_set_audmode(client, vt->audmode);
+               break;
+
+       case VIDIOC_G_TUNER:
+               if (state->radio)
+                       break;
+               vt->audmode = state->audmode;
+               vt->capability = V4L2_TUNER_CAP_STEREO |
+                       V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
+               vt->rxsubchans = V4L2_TUNER_SUB_MONO;
+               break;
+
+       case VIDIOC_G_CHIP_IDENT:
+               return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_VP27SMPX, 0);
+
+       case VIDIOC_LOG_STATUS:
+               v4l_info(client, "Audio Mode: %u%s\n", state->audmode,
+                               state->radio ? " (Radio)" : "");
+               break;
+
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+
+/*
+ * Generic i2c probe
+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
+ */
+
+static struct i2c_driver i2c_driver;
+
+static int vp27smpx_attach(struct i2c_adapter *adapter, int address, int kind)
+{
+       struct i2c_client *client;
+       struct vp27smpx_state *state;
+
+       /* Check if the adapter supports the needed features */
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+               return 0;
+
+       client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
+       if (client == 0)
+               return -ENOMEM;
+
+       client->addr = address;
+       client->adapter = adapter;
+       client->driver = &i2c_driver;
+       snprintf(client->name, sizeof(client->name) - 1, "vp27smpx");
+
+       v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name);
+
+       state = kzalloc(sizeof(struct vp27smpx_state), GFP_KERNEL);
+       if (state == NULL) {
+               kfree(client);
+               return -ENOMEM;
+       }
+       state->audmode = V4L2_TUNER_MODE_STEREO;
+       i2c_set_clientdata(client, state);
+
+       /* initialize vp27smpx */
+       vp27smpx_set_audmode(client, state->audmode);
+       i2c_attach_client(client);
+
+       return 0;
+}
+
+static int vp27smpx_probe(struct i2c_adapter *adapter)
+{
+       if (adapter->class & I2C_CLASS_TV_ANALOG)
+               return i2c_probe(adapter, &addr_data, vp27smpx_attach);
+       return 0;
+}
+
+static int vp27smpx_detach(struct i2c_client *client)
+{
+       struct vp27smpx_state *state = i2c_get_clientdata(client);
+       int err;
+
+       err = i2c_detach_client(client);
+       if (err) {
+               return err;
+       }
+       kfree(state);
+       kfree(client);
+
+       return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+static struct i2c_driver i2c_driver = {
+       .driver = {
+               .name = "vp27smpx",
+       },
+       .id             = I2C_DRIVERID_VP27SMPX,
+       .attach_adapter = vp27smpx_probe,
+       .detach_client  = vp27smpx_detach,
+       .command        = vp27smpx_command,
+};
+
+
+static int __init vp27smpx_init_module(void)
+{
+       return i2c_add_driver(&i2c_driver);
+}
+
+static void __exit vp27smpx_cleanup_module(void)
+{
+       i2c_del_driver(&i2c_driver);
+}
+
+module_init(vp27smpx_init_module);
+module_exit(vp27smpx_cleanup_module);
index 8f31613b9903897b52fe42f12c9533559d120a5f..5a1b5f5a7d463e11cab98c6197b38646e18101f7 100644 (file)
@@ -42,7 +42,6 @@
 #include <asm/page.h>
 #include <asm/uaccess.h>
 #include <linux/page-flags.h>
-#include <linux/moduleparam.h>
 
 #include "w9968cf.h"
 #include "w9968cf_decoder.h"
@@ -2680,7 +2679,7 @@ static int w9968cf_open(struct inode* inode, struct file* filp)
 
        /* This the only safe way to prevent race conditions with disconnect */
        if (!down_read_trylock(&w9968cf_disconnect))
-               return -ERESTARTSYS;
+               return -EAGAIN;
 
        cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
 
index 703b741e46df4477fb5ec5975465458e308ee18a..08a93c31c0a0e6e542a8a149769d076d577bdbfe 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/param.h>
-#include <linux/moduleparam.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/device.h>
@@ -656,7 +655,7 @@ static int zc0301_open(struct inode* inode, struct file* filp)
        int err = 0;
 
        if (!down_read_trylock(&zc0301_dev_lock))
-               return -ERESTARTSYS;
+               return -EAGAIN;
 
        cam = video_get_drvdata(video_devdata(filp));
 
index 73162a3a61dd4182c03921c76595fbdcc53b93ec..48da36a15fcae475ea0a10bb384d6be5b0651e41 100644 (file)
 extern const struct zoran_format zoran_formats[];
 
 static int card[BUZ_MAX] = { -1, -1, -1, -1 };
-module_param_array(card, int, NULL, 0);
+module_param_array(card, int, NULL, 0444);
 MODULE_PARM_DESC(card, "The type of card");
 
 static int encoder[BUZ_MAX] = { -1, -1, -1, -1 };
-module_param_array(encoder, int, NULL, 0);
+module_param_array(encoder, int, NULL, 0444);
 MODULE_PARM_DESC(encoder, "i2c TV encoder");
 
 static int decoder[BUZ_MAX] = { -1, -1, -1, -1 };
-module_param_array(decoder, int, NULL, 0);
+module_param_array(decoder, int, NULL, 0444);
 MODULE_PARM_DESC(decoder, "i2c TV decoder");
 
 /*
@@ -84,29 +84,31 @@ MODULE_PARM_DESC(decoder, "i2c TV decoder");
  */
 
 static unsigned long vidmem = 0;       /* Video memory base address */
-module_param(vidmem, ulong, 0);
+module_param(vidmem, ulong, 0444);
+MODULE_PARM_DESC(vidmem, "Default video memory base address");
 
 /*
    Default input and video norm at startup of the driver.
 */
 
-static int default_input = 0;  /* 0=Composite, 1=S-Video */
-module_param(default_input, int, 0);
+static unsigned int default_input = 0; /* 0=Composite, 1=S-Video */
+module_param(default_input, uint, 0444);
 MODULE_PARM_DESC(default_input,
                 "Default input (0=Composite, 1=S-Video, 2=Internal)");
 
 static int default_mux = 1;    /* 6 Eyes input selection */
-module_param(default_mux, int, 0);
+module_param(default_mux, int, 0644);
 MODULE_PARM_DESC(default_mux,
                 "Default 6 Eyes mux setting (Input selection)");
 
 static int default_norm = 0;   /* 0=PAL, 1=NTSC 2=SECAM */
-module_param(default_norm, int, 0);
+module_param(default_norm, int, 0444);
 MODULE_PARM_DESC(default_norm, "Default norm (0=PAL, 1=NTSC, 2=SECAM)");
 
-static int video_nr = -1;      /* /dev/videoN, -1 for autodetect */
-module_param(video_nr, int, 0);
-MODULE_PARM_DESC(video_nr, "video device number");
+/* /dev/videoN, -1 for autodetect */
+static int video_nr[BUZ_MAX] = {-1, -1, -1, -1};
+module_param_array(video_nr, int, NULL, 0444);
+MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
 
 /*
    Number and size of grab buffers for Video 4 Linux
@@ -127,28 +129,27 @@ MODULE_PARM_DESC(video_nr, "video device number");
 
 int v4l_nbufs = 2;
 int v4l_bufsize = 128;         /* Everybody should be able to work with this setting */
-module_param(v4l_nbufs, int, 0);
+module_param(v4l_nbufs, int, 0644);
 MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use");
-module_param(v4l_bufsize, int, 0);
+module_param(v4l_bufsize, int, 0644);
 MODULE_PARM_DESC(v4l_bufsize, "Maximum size per V4L buffer (in kB)");
 
 int jpg_nbufs = 32;
 int jpg_bufsize = 512;         /* max size for 100% quality full-PAL frame */
-module_param(jpg_nbufs, int, 0);
+module_param(jpg_nbufs, int, 0644);
 MODULE_PARM_DESC(jpg_nbufs, "Maximum number of JPG buffers to use");
-module_param(jpg_bufsize, int, 0);
+module_param(jpg_bufsize, int, 0644);
 MODULE_PARM_DESC(jpg_bufsize, "Maximum size per JPG buffer (in kB)");
 
 int pass_through = 0;          /* 1=Pass through TV signal when device is not used */
                                /* 0=Show color bar when device is not used (LML33: only if lml33dpath=1) */
-module_param(pass_through, int, 0);
+module_param(pass_through, int, 0644);
 MODULE_PARM_DESC(pass_through,
                 "Pass TV signal through to TV-out when idling");
 
-static int debug = 1;
-int *zr_debug = &debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-4)");
+int zr36067_debug = 1;
+module_param_named(debug, zr36067_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-5)");
 
 MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
 MODULE_AUTHOR("Serguei Miridonov");
@@ -161,12 +162,6 @@ static struct pci_device_id zr36067_pci_tbl[] = {
 };
 MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
 
-#define dprintk(num, format, args...) \
-       do { \
-               if (*zr_debug >= num) \
-                       printk(format, ##args); \
-       } while (0)
-
 int zoran_num;                 /* number of Buzs in use */
 struct zoran zoran[BUZ_MAX];
 
@@ -1075,7 +1070,7 @@ test_interrupts (struct zoran *zr)
        if (timeout) {
                dprintk(1, ": time spent: %d\n", 1 * HZ - timeout);
        }
-       if (*zr_debug > 1)
+       if (zr36067_debug > 1)
                print_interrupts(zr);
        btwrite(icr, ZR36057_ICR);
 }
@@ -1121,7 +1116,14 @@ zr36057_init (struct zoran *zr)
                zr->timing = zr->card.tvn[zr->norm];
        }
 
-       zr->input = default_input = (default_input ? 1 : 0);
+       if (default_input > zr->card.inputs-1) {
+               dprintk(1,
+                       KERN_WARNING
+                       "%s: default_input value %d out of range (0-%d)\n",
+                       ZR_DEVNAME(zr), default_input, zr->card.inputs-1);
+               default_input = 0;
+       }
+       zr->input = default_input;
 
        /* Should the following be reset at every open ? */
        zr->hue = 32768;
@@ -1153,12 +1155,12 @@ zr36057_init (struct zoran *zr)
         */
        memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
        strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
-       err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr);
+       err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
        if (err < 0)
                goto exit_unregister;
 
        zoran_init_hardware(zr);
-       if (*zr_debug > 2)
+       if (zr36067_debug > 2)
                detect_guest_activity(zr);
        test_interrupts(zr);
        if (!pass_through) {
@@ -1620,7 +1622,7 @@ init_dc10_cards (void)
        }
 
        /* random nonsense */
-       dprintk(5, KERN_DEBUG "Jotti is een held!\n");
+       dprintk(6, KERN_DEBUG "Jotti is een held!\n");
 
        /* some mainboards might not do PCI-PCI data transfer well */
        if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) {
index ad997c30bee540bc43e50b1ab90b6de88d3d69a2..8444ca0a5f3fd72837554f3edada9dbcbc4918dc 100644 (file)
 #ifndef __ZORAN_CARD_H__
 #define __ZORAN_CARD_H__
 
+extern int zr36067_debug;
+
+#define dprintk(num, format, args...) \
+       do { \
+               if (zr36067_debug >= num) \
+                       printk(format, ##args); \
+       } while (0)
+
 /* Anybody who uses more than four? */
 #define BUZ_MAX 4
 extern int zoran_num;
index ba2f4ed294836586fe36e8560ab54e5cc6389918..68c7c505587e2c6ca26cdd69afc05fab03bdc204 100644 (file)
@@ -52,6 +52,7 @@
 #include "videocodec.h"
 #include "zoran.h"
 #include "zoran_device.h"
+#include "zoran_card.h"
 
 #define IRQ_MASK ( ZR36057_ISR_GIRQ0 | \
                   ZR36057_ISR_GIRQ1 | \
 
 extern const struct zoran_format zoran_formats[];
 
-extern int *zr_debug;
-
-#define dprintk(num, format, args...) \
-       do { \
-               if (*zr_debug >= num) \
-                       printk(format, ##args); \
-       } while (0)
-
 static int lml33dpath = 0;     /* 1 will use digital path in capture
                                 * mode instead of analog. It can be
                                 * used for picture adjustments using
@@ -76,7 +69,7 @@ static int lml33dpath = 0;    /* 1 will use digital path in capture
                                 * load on Bt819 input, there will be
                                 * some image imperfections */
 
-module_param(lml33dpath, bool, 0);
+module_param(lml33dpath, bool, 0644);
 MODULE_PARM_DESC(lml33dpath,
                 "Use digital path capture mode (on LML33 cards)");
 
@@ -174,7 +167,7 @@ post_office_read (struct zoran *zr,
 static void
 dump_guests (struct zoran *zr)
 {
-       if (*zr_debug > 2) {
+       if (zr36067_debug > 2) {
                int i, guest[8];
 
                for (i = 1; i < 8; i++) {       // Don't read jpeg codec here
@@ -1271,7 +1264,7 @@ error_handler (struct zoran *zr,
                zr->num_errors++;
 
                /* Report error */
-               if (*zr_debug > 1 && zr->num_errors <= 8) {
+               if (zr36067_debug > 1 && zr->num_errors <= 8) {
                        long frame;
                        frame =
                            zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
@@ -1531,7 +1524,7 @@ zoran_irq (int             irq,
 
                        if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
                            zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
-                               if (*zr_debug > 1 &&
+                               if (zr36067_debug > 1 &&
                                    (!zr->frame_num || zr->JPEG_error)) {
                                        printk(KERN_INFO
                                               "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n",
@@ -1568,7 +1561,7 @@ zoran_irq (int             irq,
                                                    zr->JPEG_missed;
                                }
 
-                               if (*zr_debug > 2 && zr->frame_num < 6) {
+                               if (zr36067_debug > 2 && zr->frame_num < 6) {
                                        int i;
                                        printk("%s: seq=%ld stat_com:",
                                               ZR_DEVNAME(zr), zr->jpg_seq_num);
index 72a037b75d63af058f8a7869eca4bb4a8c8af824..1c14fa2bd4115623de441807e76688133f6664f3 100644 (file)
@@ -200,14 +200,6 @@ const struct zoran_format zoran_formats[] = {
 // RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined
 
 
-extern int *zr_debug;
-
-#define dprintk(num, format, args...) \
-       do { \
-               if (*zr_debug >= num) \
-                       printk(format, ##args); \
-       } while (0)
-
 extern int v4l_nbufs;
 extern int v4l_bufsize;
 extern int jpg_nbufs;
@@ -215,8 +207,8 @@ extern int jpg_bufsize;
 extern int pass_through;
 
 static int lock_norm = 0;      /* 1=Don't change TV standard (norm) */
-module_param(lock_norm, int, 0);
-MODULE_PARM_DESC(lock_norm, "Users can't change norm");
+module_param(lock_norm, int, 0644);
+MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)");
 
 #ifdef CONFIG_VIDEO_V4L2
        /* small helper function for calculating buffersizes for v4l2
@@ -347,10 +339,7 @@ v4l_fbuffer_alloc (struct file *file)
                if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
                        /* Use kmalloc */
 
-                       mem =
-                           (unsigned char *) kmalloc(fh->v4l_buffers.
-                                                     buffer_size,
-                                                     GFP_KERNEL);
+                       mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL);
                        if (mem == 0) {
                                dprintk(1,
                                        KERN_ERR
@@ -1106,12 +1095,10 @@ jpg_sync (struct file       *file,
                frame = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
 
        /* buffer should now be in BUZ_STATE_DONE */
-       if (*zr_debug > 0)
-               if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)
-                       dprintk(2,
-                               KERN_ERR
-                               "%s: jpg_sync() - internal state error\n",
-                               ZR_DEVNAME(zr));
+       if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)
+               dprintk(2,
+                       KERN_ERR "%s: jpg_sync() - internal state error\n",
+                       ZR_DEVNAME(zr));
 
        *bs = zr->jpg_buffers.buffer[frame].bs;
        bs->frame = frame;
@@ -1389,7 +1376,7 @@ zoran_close (struct inode *inode,
                /* disable interrupts */
                btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
 
-               if (*zr_debug > 1)
+               if (zr36067_debug > 1)
                        print_interrupts(zr);
 
                /* Overlay off */
@@ -3206,7 +3193,7 @@ zoran_do_ioctl (struct inode *inode,
                        "%s: VIDIOC_QUERYBUF - index=%d, type=%d\n",
                        ZR_DEVNAME(zr), buf->index, buf->type);
 
-               memset(buf, 0, sizeof(buf));
+               memset(buf, 0, sizeof(*buf));
                buf->type = type;
                buf->index = index;
 
index 446ae8d5c3df97a9aca4e2541dd9ef6e21b7e212..328ed6e7ac6abe5388a30a90b3b9752e01c9c842 100644 (file)
 #include "videocodec.h"
 #include "zoran.h"
 #include "zoran_procfs.h"
-
-extern int *zr_debug;
-
-#define dprintk(num, format, args...) \
-       do { \
-               if (*zr_debug >= num) \
-                       printk(format, ##args); \
-       } while (0)
+#include "zoran_card.h"
 
 #ifdef CONFIG_PROC_FS
 struct procfs_params_zr36067 {
index 62f77584fb859acb30b4dcac559dc07476b1f456..dd084555da8f8f19c20cfb59455b62b0aefb4579 100644 (file)
    #include<linux/videodev.h> */
 
 /* I/O commands, error codes */
-#include<asm/io.h>
+#include <asm/io.h>
 //#include<errno.h>
 
 /* v4l  API */
-#include<linux/videodev.h>
+#include <linux/videodev.h>
 
 /* headerfile of this module */
 #include"zr36016.h"
index a6bbd125631c06311c06be7bf175a9a73d8ec9a6..9f622e00c479b573875bd062886afa8688063c5c 100644 (file)
    #include<linux/videodev.h> */
 
 /* I/O commands, error codes */
-#include<asm/io.h>
+#include <asm/io.h>
 //#include<errno.h>
 
 /* headerfile of this module */
-#include"zr36050.h"
+#include "zr36050.h"
 
 /* codec io API */
-#include"videocodec.h"
+#include "videocodec.h"
 
 /* it doesn't make sense to have more than 20 or so,
   just to prevent some unwanted loops */
index 97c8f9b9dc124d650ec946973a986b05c2137c78..1ef14fef08e624a85c2a2733fb39fa04c2685344 100644 (file)
    #include<linux/videodev.h> */
 
 /* I/O commands, error codes */
-#include<asm/io.h>
+#include <asm/io.h>
 //#include<errno.h>
 
 /* headerfile of this module */
-#include"zr36060.h"
+#include "zr36060.h"
 
 /* codec io API */
-#include"videocodec.h"
+#include "videocodec.h"
 
 /* it doesn't make sense to have more than 20 or so,
   just to prevent some unwanted loops */
index a49cb9737cd858c8f36679249b29f86b565426f2..aa8a4e461942801db89ec3963c7dabf605dfb006 100644 (file)
@@ -32,3 +32,10 @@ config MMC_BLOCK_BOUNCE
 
          If unsure, say Y here.
 
+config SDIO_UART
+       tristate "SDIO UART/GPS class support"
+       depends on MMC
+       help
+         SDIO function driver for SDIO cards that implements the UART
+         class, as well as the GPS class which appears like a UART.
+
index cf8c939867f531f0f20b252daf928551f3366055..fc5a784cfa1a7410f2025fdfcdddd08f06e8ec4b 100644 (file)
@@ -9,3 +9,5 @@ endif
 obj-$(CONFIG_MMC_BLOCK)                += mmc_block.o
 mmc_block-objs                 := block.o queue.o
 
+obj-$(CONFIG_SDIO_UART)                += sdio_uart.o
+
index 93fe2e5dd6162eb12e3e1bc63adee1cfc5483f9d..e38d5a3b2a899d6f9988e12ad294bf47862959c6 100644 (file)
@@ -151,17 +151,19 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
 
        cmd.opcode = MMC_APP_CMD;
        cmd.arg = card->rca << 16;
-       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
 
        err = mmc_wait_for_cmd(card->host, &cmd, 0);
-       if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD))
+       if (err)
+               return (u32)-1;
+       if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD))
                return (u32)-1;
 
        memset(&cmd, 0, sizeof(struct mmc_command));
 
        cmd.opcode = SD_APP_SEND_NUM_WR_BLKS;
        cmd.arg = 0;
-       cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
        memset(&data, 0, sizeof(struct mmc_data));
 
@@ -192,7 +194,7 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
 
        mmc_wait_for_req(card->host, &mrq);
 
-       if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE)
+       if (cmd.error || data.error)
                return (u32)-1;
 
        blocks = ntohl(blocks);
@@ -220,17 +222,15 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                brq.cmd.arg = req->sector;
                if (!mmc_card_blockaddr(card))
                        brq.cmd.arg <<= 9;
-               brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+               brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
                brq.data.blksz = 1 << md->block_bits;
                brq.stop.opcode = MMC_STOP_TRANSMISSION;
                brq.stop.arg = 0;
-               brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
+               brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
                brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
                if (brq.data.blocks > card->host->max_blk_count)
                        brq.data.blocks = card->host->max_blk_count;
 
-               mmc_set_data_timeout(&brq.data, card, rq_data_dir(req) != READ);
-
                /*
                 * If the host doesn't support multiple block writes, force
                 * block writes to single block. SD cards are excepted from
@@ -243,8 +243,12 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                        brq.data.blocks = 1;
 
                if (brq.data.blocks > 1) {
-                       brq.data.flags |= MMC_DATA_MULTI;
-                       brq.mrq.stop = &brq.stop;
+                       /* SPI multiblock writes terminate using a special
+                        * token, not a STOP_TRANSMISSION request.
+                        */
+                       if (!mmc_host_is_spi(card->host)
+                                       || rq_data_dir(req) == READ)
+                               brq.mrq.stop = &brq.stop;
                        readcmd = MMC_READ_MULTIPLE_BLOCK;
                        writecmd = MMC_WRITE_MULTIPLE_BLOCK;
                } else {
@@ -261,6 +265,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                        brq.data.flags |= MMC_DATA_WRITE;
                }
 
+               mmc_set_data_timeout(&brq.data, card);
+
                brq.data.sg = mq->sg;
                brq.data.sg_len = mmc_queue_map_sg(mq);
 
@@ -302,7 +308,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                        goto cmd_err;
                }
 
-               if (rq_data_dir(req) != READ) {
+               if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
                        do {
                                int err;
 
@@ -510,7 +516,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
        mmc_claim_host(card->host);
        cmd.opcode = MMC_SET_BLOCKLEN;
        cmd.arg = 1 << md->block_bits;
-       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
        err = mmc_wait_for_cmd(card->host, &cmd, 5);
        mmc_release_host(card->host);
 
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
new file mode 100644 (file)
index 0000000..d552de6
--- /dev/null
@@ -0,0 +1,1158 @@
+/*
+ * linux/drivers/mmc/card/sdio_uart.c - SDIO UART/GPS driver
+ *
+ * Based on drivers/serial/8250.c and drivers/serial/serial_core.c
+ * by Russell King.
+ *
+ * Author:     Nicolas Pitre
+ * Created:    June 15, 2007
+ * Copyright:  MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+/*
+ * Note: Although this driver assumes a 16550A-like UART implementation,
+ * it is not possible to leverage the common 8250/16550 driver, nor the
+ * core UART infrastructure, as they assumes direct access to the hardware
+ * registers, often under a spinlock.  This is not possible in the SDIO
+ * context as SDIO access functions must be able to sleep.
+ *
+ * Because we need to lock the SDIO host to ensure an exclusive access to
+ * the card, we simply rely on that lock to also prevent and serialize
+ * concurrent access to the same port.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/serial_reg.h>
+#include <linux/circ_buf.h>
+#include <linux/gfp.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+
+
+#define UART_NR                8       /* Number of UARTs this driver can handle */
+
+
+#define UART_XMIT_SIZE PAGE_SIZE
+#define WAKEUP_CHARS   256
+
+#define circ_empty(circ)       ((circ)->head == (circ)->tail)
+#define circ_clear(circ)       ((circ)->head = (circ)->tail = 0)
+
+#define circ_chars_pending(circ) \
+               (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
+
+#define circ_chars_free(circ) \
+               (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
+
+
+struct uart_icount {
+       __u32   cts;
+       __u32   dsr;
+       __u32   rng;
+       __u32   dcd;
+       __u32   rx;
+       __u32   tx;
+       __u32   frame;
+       __u32   overrun;
+       __u32   parity;
+       __u32   brk;
+};
+
+struct sdio_uart_port {
+       struct kref             kref;
+       struct tty_struct       *tty;
+       unsigned int            index;
+       unsigned int            opened;
+       struct mutex            open_lock;
+       struct sdio_func        *func;
+       struct mutex            func_lock;
+       struct task_struct      *in_sdio_uart_irq;
+       unsigned int            regs_offset;
+       struct circ_buf         xmit;
+       spinlock_t              write_lock;
+       struct uart_icount      icount;
+       unsigned int            uartclk;
+       unsigned int            mctrl;
+       unsigned int            read_status_mask;
+       unsigned int            ignore_status_mask;
+       unsigned char           x_char;
+       unsigned char           ier;
+       unsigned char           lcr;
+};
+
+static struct sdio_uart_port *sdio_uart_table[UART_NR];
+static DEFINE_SPINLOCK(sdio_uart_table_lock);
+
+static int sdio_uart_add_port(struct sdio_uart_port *port)
+{
+       int index, ret = -EBUSY;
+
+       kref_init(&port->kref);
+       mutex_init(&port->open_lock);
+       mutex_init(&port->func_lock);
+       spin_lock_init(&port->write_lock);
+
+       spin_lock(&sdio_uart_table_lock);
+       for (index = 0; index < UART_NR; index++) {
+               if (!sdio_uart_table[index]) {
+                       port->index = index;
+                       sdio_uart_table[index] = port;
+                       ret = 0;
+                       break;
+               }
+       }
+       spin_unlock(&sdio_uart_table_lock);
+
+       return ret;
+}
+
+static struct sdio_uart_port *sdio_uart_port_get(unsigned index)
+{
+       struct sdio_uart_port *port;
+
+       if (index >= UART_NR)
+               return NULL;
+
+       spin_lock(&sdio_uart_table_lock);
+       port = sdio_uart_table[index];
+       if (port)
+               kref_get(&port->kref);
+       spin_unlock(&sdio_uart_table_lock);
+
+       return port;
+}
+
+static void sdio_uart_port_destroy(struct kref *kref)
+{
+       struct sdio_uart_port *port =
+               container_of(kref, struct sdio_uart_port, kref);
+       kfree(port);
+}
+
+static void sdio_uart_port_put(struct sdio_uart_port *port)
+{
+       kref_put(&port->kref, sdio_uart_port_destroy);
+}
+
+static void sdio_uart_port_remove(struct sdio_uart_port *port)
+{
+       struct sdio_func *func;
+
+       BUG_ON(sdio_uart_table[port->index] != port);
+
+       spin_lock(&sdio_uart_table_lock);
+       sdio_uart_table[port->index] = NULL;
+       spin_unlock(&sdio_uart_table_lock);
+
+       /*
+        * We're killing a port that potentially still is in use by
+        * the tty layer. Be careful to prevent any further access
+        * to the SDIO function and arrange for the tty layer to
+        * give up on that port ASAP.
+        * Beware: the lock ordering is critical.
+        */
+       mutex_lock(&port->open_lock);
+       mutex_lock(&port->func_lock);
+       func = port->func;
+       sdio_claim_host(func);
+       port->func = NULL;
+       mutex_unlock(&port->func_lock);
+       if (port->opened)
+               tty_hangup(port->tty);
+       mutex_unlock(&port->open_lock);
+       sdio_release_irq(func);
+       sdio_disable_func(func);
+       sdio_release_host(func);
+
+       sdio_uart_port_put(port);
+}
+
+static int sdio_uart_claim_func(struct sdio_uart_port *port)
+{
+       mutex_lock(&port->func_lock);
+       if (unlikely(!port->func)) {
+               mutex_unlock(&port->func_lock);
+               return -ENODEV;
+       }
+       if (likely(port->in_sdio_uart_irq != current))
+               sdio_claim_host(port->func);
+       mutex_unlock(&port->func_lock);
+       return 0;
+}
+
+static inline void sdio_uart_release_func(struct sdio_uart_port *port)
+{
+       if (likely(port->in_sdio_uart_irq != current))
+               sdio_release_host(port->func);
+}
+
+static inline unsigned int sdio_in(struct sdio_uart_port *port, int offset)
+{
+       unsigned char c;
+       c = sdio_readb(port->func, port->regs_offset + offset, NULL);
+       return c;
+}
+
+static inline void sdio_out(struct sdio_uart_port *port, int offset, int value)
+{
+       sdio_writeb(port->func, value, port->regs_offset + offset, NULL);
+}
+
+static unsigned int sdio_uart_get_mctrl(struct sdio_uart_port *port)
+{
+       unsigned char status;
+       unsigned int ret;
+
+       status = sdio_in(port, UART_MSR);
+
+       ret = 0;
+       if (status & UART_MSR_DCD)
+               ret |= TIOCM_CAR;
+       if (status & UART_MSR_RI)
+               ret |= TIOCM_RNG;
+       if (status & UART_MSR_DSR)
+               ret |= TIOCM_DSR;
+       if (status & UART_MSR_CTS)
+               ret |= TIOCM_CTS;
+       return ret;
+}
+
+static void sdio_uart_write_mctrl(struct sdio_uart_port *port, unsigned int mctrl)
+{
+       unsigned char mcr = 0;
+
+       if (mctrl & TIOCM_RTS)
+               mcr |= UART_MCR_RTS;
+       if (mctrl & TIOCM_DTR)
+               mcr |= UART_MCR_DTR;
+       if (mctrl & TIOCM_OUT1)
+               mcr |= UART_MCR_OUT1;
+       if (mctrl & TIOCM_OUT2)
+               mcr |= UART_MCR_OUT2;
+       if (mctrl & TIOCM_LOOP)
+               mcr |= UART_MCR_LOOP;
+
+       sdio_out(port, UART_MCR, mcr);
+}
+
+static inline void sdio_uart_update_mctrl(struct sdio_uart_port *port,
+                                         unsigned int set, unsigned int clear)
+{
+       unsigned int old;
+
+       old = port->mctrl;
+       port->mctrl = (old & ~clear) | set;
+       if (old != port->mctrl)
+               sdio_uart_write_mctrl(port, port->mctrl);
+}
+
+#define sdio_uart_set_mctrl(port, x)   sdio_uart_update_mctrl(port, x, 0)
+#define sdio_uart_clear_mctrl(port, x) sdio_uart_update_mctrl(port, 0, x)
+
+static void sdio_uart_change_speed(struct sdio_uart_port *port,
+                                  struct ktermios *termios,
+                                  struct ktermios *old)
+{
+       unsigned char cval, fcr = 0;
+       unsigned int baud, quot;
+
+       switch (termios->c_cflag & CSIZE) {
+       case CS5:
+               cval = UART_LCR_WLEN5;
+               break;
+       case CS6:
+               cval = UART_LCR_WLEN6;
+               break;
+       case CS7:
+               cval = UART_LCR_WLEN7;
+               break;
+       default:
+       case CS8:
+               cval = UART_LCR_WLEN8;
+               break;
+       }
+
+       if (termios->c_cflag & CSTOPB)
+               cval |= UART_LCR_STOP;
+       if (termios->c_cflag & PARENB)
+               cval |= UART_LCR_PARITY;
+       if (!(termios->c_cflag & PARODD))
+               cval |= UART_LCR_EPAR;
+
+       for (;;) {
+               baud = tty_termios_baud_rate(termios);
+               if (baud == 0)
+                       baud = 9600;  /* Special case: B0 rate. */
+               if (baud <= port->uartclk)
+                       break;
+               /*
+                * Oops, the quotient was zero.  Try again with the old
+                * baud rate if possible, otherwise default to 9600.
+                */
+               termios->c_cflag &= ~CBAUD;
+               if (old) {
+                       termios->c_cflag |= old->c_cflag & CBAUD;
+                       old = NULL;
+               } else
+                       termios->c_cflag |= B9600;
+       }
+       quot = (2 * port->uartclk + baud) / (2 * baud);
+
+       if (baud < 2400)
+               fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+       else
+               fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;
+
+       port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+       if (termios->c_iflag & INPCK)
+               port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+       if (termios->c_iflag & (BRKINT | PARMRK))
+               port->read_status_mask |= UART_LSR_BI;
+
+       /*
+        * Characters to ignore
+        */
+       port->ignore_status_mask = 0;
+       if (termios->c_iflag & IGNPAR)
+               port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+       if (termios->c_iflag & IGNBRK) {
+               port->ignore_status_mask |= UART_LSR_BI;
+               /*
+                * If we're ignoring parity and break indicators,
+                * ignore overruns too (for real raw support).
+                */
+               if (termios->c_iflag & IGNPAR)
+                       port->ignore_status_mask |= UART_LSR_OE;
+       }
+
+       /*
+        * ignore all characters if CREAD is not set
+        */
+       if ((termios->c_cflag & CREAD) == 0)
+               port->ignore_status_mask |= UART_LSR_DR;
+
+       /*
+        * CTS flow control flag and modem status interrupts
+        */
+       port->ier &= ~UART_IER_MSI;
+       if ((termios->c_cflag & CRTSCTS) || !(termios->c_cflag & CLOCAL))
+               port->ier |= UART_IER_MSI;
+
+       port->lcr = cval;
+
+       sdio_out(port, UART_IER, port->ier);
+       sdio_out(port, UART_LCR, cval | UART_LCR_DLAB);
+       sdio_out(port, UART_DLL, quot & 0xff);
+       sdio_out(port, UART_DLM, quot >> 8);
+       sdio_out(port, UART_LCR, cval);
+       sdio_out(port, UART_FCR, fcr);
+
+       sdio_uart_write_mctrl(port, port->mctrl);
+}
+
+static void sdio_uart_start_tx(struct sdio_uart_port *port)
+{
+       if (!(port->ier & UART_IER_THRI)) {
+               port->ier |= UART_IER_THRI;
+               sdio_out(port, UART_IER, port->ier);
+       }
+}
+
+static void sdio_uart_stop_tx(struct sdio_uart_port *port)
+{
+       if (port->ier & UART_IER_THRI) {
+               port->ier &= ~UART_IER_THRI;
+               sdio_out(port, UART_IER, port->ier);
+       }
+}
+
+static void sdio_uart_stop_rx(struct sdio_uart_port *port)
+{
+       port->ier &= ~UART_IER_RLSI;
+       port->read_status_mask &= ~UART_LSR_DR;
+       sdio_out(port, UART_IER, port->ier);
+}
+
+static void sdio_uart_receive_chars(struct sdio_uart_port *port, int *status)
+{
+       struct tty_struct *tty = port->tty;
+       unsigned int ch, flag;
+       int max_count = 256;
+
+       do {
+               ch = sdio_in(port, UART_RX);
+               flag = TTY_NORMAL;
+               port->icount.rx++;
+
+               if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
+                                       UART_LSR_FE | UART_LSR_OE))) {
+                       /*
+                        * For statistics only
+                        */
+                       if (*status & UART_LSR_BI) {
+                               *status &= ~(UART_LSR_FE | UART_LSR_PE);
+                               port->icount.brk++;
+                       } else if (*status & UART_LSR_PE)
+                               port->icount.parity++;
+                       else if (*status & UART_LSR_FE)
+                               port->icount.frame++;
+                       if (*status & UART_LSR_OE)
+                               port->icount.overrun++;
+
+                       /*
+                        * Mask off conditions which should be ignored.
+                        */
+                       *status &= port->read_status_mask;
+                       if (*status & UART_LSR_BI) {
+                               flag = TTY_BREAK;
+                       } else if (*status & UART_LSR_PE)
+                               flag = TTY_PARITY;
+                       else if (*status & UART_LSR_FE)
+                               flag = TTY_FRAME;
+               }
+
+               if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0)
+                       tty_insert_flip_char(tty, ch, flag);
+
+               /*
+                * Overrun is special.  Since it's reported immediately,
+                * it doesn't affect the current character.
+                */
+               if (*status & ~port->ignore_status_mask & UART_LSR_OE)
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+
+               *status = sdio_in(port, UART_LSR);
+       } while ((*status & UART_LSR_DR) && (max_count-- > 0));
+       tty_flip_buffer_push(tty);
+}
+
+static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
+{
+       struct circ_buf *xmit = &port->xmit;
+       int count;
+
+       if (port->x_char) {
+               sdio_out(port, UART_TX, port->x_char);
+               port->icount.tx++;
+               port->x_char = 0;
+               return;
+       }
+       if (circ_empty(xmit) || port->tty->stopped || port->tty->hw_stopped) {
+               sdio_uart_stop_tx(port);
+               return;
+       }
+
+       count = 16;
+       do {
+               sdio_out(port, UART_TX, xmit->buf[xmit->tail]);
+               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+               port->icount.tx++;
+               if (circ_empty(xmit))
+                       break;
+       } while (--count > 0);
+
+       if (circ_chars_pending(xmit) < WAKEUP_CHARS)
+               tty_wakeup(port->tty);
+
+       if (circ_empty(xmit))
+               sdio_uart_stop_tx(port);
+}
+
+static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
+{
+       int status;
+
+       status = sdio_in(port, UART_MSR);
+
+       if ((status & UART_MSR_ANY_DELTA) == 0)
+               return;
+
+       if (status & UART_MSR_TERI)
+               port->icount.rng++;
+       if (status & UART_MSR_DDSR)
+               port->icount.dsr++;
+       if (status & UART_MSR_DDCD)
+               port->icount.dcd++;
+       if (status & UART_MSR_DCTS) {
+               port->icount.cts++;
+               if (port->tty->termios->c_cflag & CRTSCTS) {
+                       int cts = (status & UART_MSR_CTS);
+                       if (port->tty->hw_stopped) {
+                               if (cts) {
+                                       port->tty->hw_stopped = 0;
+                                       sdio_uart_start_tx(port);
+                                       tty_wakeup(port->tty);
+                               }
+                       } else {
+                               if (!cts) {
+                                       port->tty->hw_stopped = 1;
+                                       sdio_uart_stop_tx(port);
+                               }
+                       }
+               }
+       }
+}
+
+/*
+ * This handles the interrupt from one port.
+ */
+static void sdio_uart_irq(struct sdio_func *func)
+{
+       struct sdio_uart_port *port = sdio_get_drvdata(func);
+       unsigned int iir, lsr;
+
+       /*
+        * In a few places sdio_uart_irq() is called directly instead of
+        * waiting for the actual interrupt to be raised and the SDIO IRQ
+        * thread scheduled in order to reduce latency.  However, some
+        * interaction with the tty core may end up calling us back
+        * (serial echo, flow control, etc.) through those same places
+        * causing undesirable effects.  Let's stop the recursion here.
+        */
+       if (unlikely(port->in_sdio_uart_irq == current))
+               return;
+
+       iir = sdio_in(port, UART_IIR);
+       if (iir & UART_IIR_NO_INT)
+               return;
+
+       port->in_sdio_uart_irq = current;
+       lsr = sdio_in(port, UART_LSR);
+       if (lsr & UART_LSR_DR)
+               sdio_uart_receive_chars(port, &lsr);
+       sdio_uart_check_modem_status(port);
+       if (lsr & UART_LSR_THRE)
+               sdio_uart_transmit_chars(port);
+       port->in_sdio_uart_irq = NULL;
+}
+
+static int sdio_uart_startup(struct sdio_uart_port *port)
+{
+       unsigned long page;
+       int ret;
+
+       /*
+        * Set the TTY IO error marker - we will only clear this
+        * once we have successfully opened the port.
+        */
+       set_bit(TTY_IO_ERROR, &port->tty->flags);
+
+       /* Initialise and allocate the transmit buffer. */
+       page = __get_free_page(GFP_KERNEL);
+       if (!page)
+               return -ENOMEM;
+       port->xmit.buf = (unsigned char *)page;
+       circ_clear(&port->xmit);
+
+       ret = sdio_uart_claim_func(port);
+       if (ret)
+               goto err1;
+       ret = sdio_enable_func(port->func);
+       if (ret)
+               goto err2;
+       ret = sdio_claim_irq(port->func, sdio_uart_irq);
+       if (ret)
+               goto err3;
+
+       /*
+        * Clear the FIFO buffers and disable them.
+        * (they will be reenabled in sdio_change_speed())
+        */
+       sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);
+       sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |
+                       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+       sdio_out(port, UART_FCR, 0);
+
+       /*
+        * Clear the interrupt registers.
+        */
+       (void) sdio_in(port, UART_LSR);
+       (void) sdio_in(port, UART_RX);
+       (void) sdio_in(port, UART_IIR);
+       (void) sdio_in(port, UART_MSR);
+
+       /*
+        * Now, initialize the UART
+        */
+       sdio_out(port, UART_LCR, UART_LCR_WLEN8);
+
+       port->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE;
+       port->mctrl = TIOCM_OUT2;
+
+       sdio_uart_change_speed(port, port->tty->termios, NULL);
+
+       if (port->tty->termios->c_cflag & CBAUD)
+               sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
+
+       if (port->tty->termios->c_cflag & CRTSCTS)
+               if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))
+                       port->tty->hw_stopped = 1;
+
+       clear_bit(TTY_IO_ERROR, &port->tty->flags);
+
+       /* Kick the IRQ handler once while we're still holding the host lock */
+       sdio_uart_irq(port->func);
+
+       sdio_uart_release_func(port);
+       return 0;
+
+err3:
+       sdio_disable_func(port->func);
+err2:
+       sdio_uart_release_func(port);
+err1:
+       free_page((unsigned long)port->xmit.buf);
+       return ret;
+}
+
+static void sdio_uart_shutdown(struct sdio_uart_port *port)
+{
+       int ret;
+
+       ret = sdio_uart_claim_func(port);
+       if (ret)
+               goto skip;
+
+       sdio_uart_stop_rx(port);
+
+       /* TODO: wait here for TX FIFO to drain */
+
+       /* Turn off DTR and RTS early. */
+       if (port->tty->termios->c_cflag & HUPCL)
+               sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+
+        /* Disable interrupts from this port */
+       sdio_release_irq(port->func);
+       port->ier = 0;
+       sdio_out(port, UART_IER, 0);
+
+       sdio_uart_clear_mctrl(port, TIOCM_OUT2);
+
+       /* Disable break condition and FIFOs. */
+       port->lcr &= ~UART_LCR_SBC;
+       sdio_out(port, UART_LCR, port->lcr);
+       sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |
+                                UART_FCR_CLEAR_RCVR |
+                                UART_FCR_CLEAR_XMIT);
+       sdio_out(port, UART_FCR, 0);
+
+       sdio_disable_func(port->func);
+
+       sdio_uart_release_func(port);
+
+skip:
+       /* Free the transmit buffer page. */
+       free_page((unsigned long)port->xmit.buf);
+}
+
+static int sdio_uart_open (struct tty_struct *tty, struct file * filp)
+{
+       struct sdio_uart_port *port;
+       int ret;
+
+       port = sdio_uart_port_get(tty->index);
+       if (!port)
+               return -ENODEV;
+
+       mutex_lock(&port->open_lock);
+
+       /*
+        * Make sure not to mess up with a dead port
+        * which has not been closed yet.
+        */
+       if (tty->driver_data && tty->driver_data != port) {
+               mutex_unlock(&port->open_lock);
+               sdio_uart_port_put(port);
+               return -EBUSY;
+       }
+
+       if (!port->opened) {
+               tty->driver_data = port;
+               port->tty = tty;
+               ret = sdio_uart_startup(port);
+               if (ret) {
+                       tty->driver_data = NULL;
+                       port->tty = NULL;
+                       mutex_unlock(&port->open_lock);
+                       sdio_uart_port_put(port);
+                       return ret;
+               }
+       }
+       port->opened++;
+       mutex_unlock(&port->open_lock);
+       return 0;
+}
+
+static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
+{
+       struct sdio_uart_port *port = tty->driver_data;
+
+       if (!port)
+               return;
+
+       mutex_lock(&port->open_lock);
+       BUG_ON(!port->opened);
+
+       /*
+        * This is messy.  The tty layer calls us even when open()
+        * returned an error.  Ignore this close request if tty->count
+        * is larger than port->count.
+        */
+       if (tty->count > port->opened) {
+               mutex_unlock(&port->open_lock);
+               return;
+       }
+
+       if (--port->opened == 0) {
+               tty->closing = 1;
+               sdio_uart_shutdown(port);
+               tty_ldisc_flush(tty);
+               port->tty = NULL;
+               tty->driver_data = NULL;
+               tty->closing = 0;
+       }
+       mutex_unlock(&port->open_lock);
+       sdio_uart_port_put(port);
+}
+
+static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf,
+                          int count)
+{
+       struct sdio_uart_port *port = tty->driver_data;
+       struct circ_buf *circ = &port->xmit;
+       int c, ret = 0;
+
+       if (!port->func)
+               return -ENODEV;
+
+       spin_lock(&port->write_lock);
+       while (1) {
+               c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
+               if (count < c)
+                       c = count;
+               if (c <= 0)
+                       break;
+               memcpy(circ->buf + circ->head, buf, c);
+               circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
+               buf += c;
+               count -= c;
+               ret += c;
+       }
+       spin_unlock(&port->write_lock);
+
+       if ( !(port->ier & UART_IER_THRI)) {
+               int err = sdio_uart_claim_func(port);
+               if (!err) {
+                       sdio_uart_start_tx(port);
+                       sdio_uart_irq(port->func);
+                       sdio_uart_release_func(port);
+               } else
+                       ret = err;
+       }
+
+       return ret;
+}
+
+static int sdio_uart_write_room(struct tty_struct *tty)
+{
+       struct sdio_uart_port *port = tty->driver_data;
+       return port ? circ_chars_free(&port->xmit) : 0;
+}
+
+static int sdio_uart_chars_in_buffer(struct tty_struct *tty)
+{
+       struct sdio_uart_port *port = tty->driver_data;
+       return port ? circ_chars_pending(&port->xmit) : 0;
+}
+
+static void sdio_uart_send_xchar(struct tty_struct *tty, char ch)
+{
+       struct sdio_uart_port *port = tty->driver_data;
+
+       port->x_char = ch;
+       if (ch && !(port->ier & UART_IER_THRI)) {
+               if (sdio_uart_claim_func(port) != 0)
+                       return;
+               sdio_uart_start_tx(port);
+               sdio_uart_irq(port->func);
+               sdio_uart_release_func(port);
+       }
+}
+
+static void sdio_uart_throttle(struct tty_struct *tty)
+{
+       struct sdio_uart_port *port = tty->driver_data;
+
+       if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
+               return;
+
+       if (sdio_uart_claim_func(port) != 0)
+               return;
+
+       if (I_IXOFF(tty)) {
+               port->x_char = STOP_CHAR(tty);
+               sdio_uart_start_tx(port);
+       }
+
+       if (tty->termios->c_cflag & CRTSCTS)
+               sdio_uart_clear_mctrl(port, TIOCM_RTS);
+
+       sdio_uart_irq(port->func);
+       sdio_uart_release_func(port);
+}
+
+static void sdio_uart_unthrottle(struct tty_struct *tty)
+{
+       struct sdio_uart_port *port = tty->driver_data;
+
+       if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
+               return;
+
+       if (sdio_uart_claim_func(port) != 0)
+               return;
+
+       if (I_IXOFF(tty)) {
+               if (port->x_char) {
+                       port->x_char = 0;
+               } else {
+                       port->x_char = START_CHAR(tty);
+                       sdio_uart_start_tx(port);
+               }
+       }
+
+       if (tty->termios->c_cflag & CRTSCTS)
+               sdio_uart_set_mctrl(port, TIOCM_RTS);
+
+       sdio_uart_irq(port->func);
+       sdio_uart_release_func(port);
+}
+
+static void sdio_uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
+{
+       struct sdio_uart_port *port = tty->driver_data;
+       unsigned int cflag = tty->termios->c_cflag;
+
+#define RELEVANT_IFLAG(iflag)   ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+       if ((cflag ^ old_termios->c_cflag) == 0 &&
+           RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
+               return;
+
+       if (sdio_uart_claim_func(port) != 0)
+               return;
+
+       sdio_uart_change_speed(port, tty->termios, old_termios);
+
+       /* Handle transition to B0 status */
+       if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
+               sdio_uart_clear_mctrl(port, TIOCM_RTS | TIOCM_DTR);
+
+       /* Handle transition away from B0 status */
+       if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
+               unsigned int mask = TIOCM_DTR;
+               if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags))
+                       mask |= TIOCM_RTS;
+               sdio_uart_set_mctrl(port, mask);
+       }
+
+       /* Handle turning off CRTSCTS */
+       if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
+               tty->hw_stopped = 0;
+               sdio_uart_start_tx(port);
+       }
+
+       /* Handle turning on CRTSCTS */
+       if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
+               if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) {
+                       tty->hw_stopped = 1;
+                       sdio_uart_stop_tx(port);
+               }
+       }
+
+       sdio_uart_release_func(port);
+}
+
+static void sdio_uart_break_ctl(struct tty_struct *tty, int break_state)
+{
+       struct sdio_uart_port *port = tty->driver_data;
+
+       if (sdio_uart_claim_func(port) != 0)
+               return;
+
+       if (break_state == -1)
+               port->lcr |= UART_LCR_SBC;
+       else
+               port->lcr &= ~UART_LCR_SBC;
+       sdio_out(port, UART_LCR, port->lcr);
+
+       sdio_uart_release_func(port);
+}
+
+static int sdio_uart_tiocmget(struct tty_struct *tty, struct file *file)
+{
+       struct sdio_uart_port *port = tty->driver_data;
+       int result;
+
+       result = sdio_uart_claim_func(port);
+       if (!result) {
+               result = port->mctrl | sdio_uart_get_mctrl(port);
+               sdio_uart_release_func(port);
+       }
+
+       return result;
+}
+
+static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file,
+                             unsigned int set, unsigned int clear)
+{
+       struct sdio_uart_port *port = tty->driver_data;
+       int result;
+
+       result =sdio_uart_claim_func(port);
+       if(!result) {
+               sdio_uart_update_mctrl(port, set, clear);
+               sdio_uart_release_func(port);
+       }
+
+       return result;
+}
+
+static int sdio_uart_read_proc(char *page, char **start, off_t off,
+                              int count, int *eof, void *data)
+{
+       int i, len = 0;
+       off_t begin = 0;
+
+       len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
+                      "", "", "");
+       for (i = 0; i < UART_NR && len < PAGE_SIZE - 96; i++) {
+               struct sdio_uart_port *port = sdio_uart_port_get(i);
+               if (port) {
+                       len += sprintf(page+len, "%d: uart:SDIO", i);
+                       if(capable(CAP_SYS_ADMIN)) {
+                               len += sprintf(page + len, " tx:%d rx:%d",
+                                              port->icount.tx, port->icount.rx);
+                               if (port->icount.frame)
+                                       len += sprintf(page + len, " fe:%d",
+                                                      port->icount.frame);
+                               if (port->icount.parity)
+                                       len += sprintf(page + len, " pe:%d",
+                                                      port->icount.parity);
+                               if (port->icount.brk)
+                                       len += sprintf(page + len, " brk:%d",
+                                                      port->icount.brk);
+                               if (port->icount.overrun)
+                                       len += sprintf(page + len, " oe:%d",
+                                                      port->icount.overrun);
+                               if (port->icount.cts)
+                                       len += sprintf(page + len, " cts:%d",
+                                                      port->icount.cts);
+                               if (port->icount.dsr)
+                                       len += sprintf(page + len, " dsr:%d",
+                                                      port->icount.dsr);
+                               if (port->icount.rng)
+                                       len += sprintf(page + len, " rng:%d",
+                                                      port->icount.rng);
+                               if (port->icount.dcd)
+                                       len += sprintf(page + len, " dcd:%d",
+                                                      port->icount.dcd);
+                       }
+                       strcat(page, "\n");
+                       len++;
+                       sdio_uart_port_put(port);
+               }
+
+               if (len + begin > off + count)
+                       goto done;
+               if (len + begin < off) {
+                       begin += len;
+                       len = 0;
+               }
+       }
+       *eof = 1;
+
+done:
+       if (off >= len + begin)
+               return 0;
+       *start = page + (off - begin);
+       return (count < begin + len - off) ? count : (begin + len - off);
+}
+
+static const struct tty_operations sdio_uart_ops = {
+       .open                   = sdio_uart_open,
+       .close                  = sdio_uart_close,
+       .write                  = sdio_uart_write,
+       .write_room             = sdio_uart_write_room,
+       .chars_in_buffer        = sdio_uart_chars_in_buffer,
+       .send_xchar             = sdio_uart_send_xchar,
+       .throttle               = sdio_uart_throttle,
+       .unthrottle             = sdio_uart_unthrottle,
+       .set_termios            = sdio_uart_set_termios,
+       .break_ctl              = sdio_uart_break_ctl,
+       .tiocmget               = sdio_uart_tiocmget,
+       .tiocmset               = sdio_uart_tiocmset,
+       .read_proc              = sdio_uart_read_proc,
+};
+
+static struct tty_driver *sdio_uart_tty_driver;
+
+static int sdio_uart_probe(struct sdio_func *func,
+                          const struct sdio_device_id *id)
+{
+       struct sdio_uart_port *port;
+       int ret;
+
+       port = kzalloc(sizeof(struct sdio_uart_port), GFP_KERNEL);
+       if (!port)
+               return -ENOMEM;
+
+       if (func->class == SDIO_CLASS_UART) {
+               printk(KERN_WARNING "%s: need info on UART class basic setup\n",
+                      sdio_func_id(func));
+               kfree(port);
+               return -ENOSYS;
+       } else if (func->class == SDIO_CLASS_GPS) {
+               /*
+                * We need tuple 0x91.  It contains SUBTPL_SIOREG
+                * and SUBTPL_RCVCAPS.
+                */
+               struct sdio_func_tuple *tpl;
+               for (tpl = func->tuples; tpl; tpl = tpl->next) {
+                       if (tpl->code != 0x91)
+                               continue;
+                       if (tpl->size < 10)
+                               continue;
+                       if (tpl->data[1] == 0)  /* SUBTPL_SIOREG */
+                               break;
+               }
+               if (!tpl) {
+                       printk(KERN_WARNING
+                              "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",
+                              sdio_func_id(func));
+                       kfree(port);
+                       return -EINVAL;
+               }
+               printk(KERN_DEBUG "%s: Register ID = 0x%02x, Exp ID = 0x%02x\n",
+                      sdio_func_id(func), tpl->data[2], tpl->data[3]);
+               port->regs_offset = (tpl->data[4] << 0) |
+                                   (tpl->data[5] << 8) |
+                                   (tpl->data[6] << 16);
+               printk(KERN_DEBUG "%s: regs offset = 0x%x\n",
+                      sdio_func_id(func), port->regs_offset);
+               port->uartclk = tpl->data[7] * 115200;
+               if (port->uartclk == 0)
+                       port->uartclk = 115200;
+               printk(KERN_DEBUG "%s: clk %d baudcode %u 4800-div %u\n",
+                      sdio_func_id(func), port->uartclk,
+                      tpl->data[7], tpl->data[8] | (tpl->data[9] << 8));
+       } else {
+               kfree(port);
+               return -EINVAL;
+       }
+
+       port->func = func;
+       sdio_set_drvdata(func, port);
+
+       ret = sdio_uart_add_port(port);
+       if (ret) {
+               kfree(port);
+       } else {
+               struct device *dev;
+               dev = tty_register_device(sdio_uart_tty_driver, port->index, &func->dev);
+               if (IS_ERR(dev)) {
+                       sdio_uart_port_remove(port);
+                       ret = PTR_ERR(dev);
+               }
+       }
+
+       return ret;
+}
+
+static void sdio_uart_remove(struct sdio_func *func)
+{
+       struct sdio_uart_port *port = sdio_get_drvdata(func);
+
+       tty_unregister_device(sdio_uart_tty_driver, port->index);
+       sdio_uart_port_remove(port);
+}
+
+static const struct sdio_device_id sdio_uart_ids[] = {
+       { SDIO_DEVICE_CLASS(SDIO_CLASS_UART)            },
+       { SDIO_DEVICE_CLASS(SDIO_CLASS_GPS)             },
+       { /* end: all zeroes */                         },
+};
+
+MODULE_DEVICE_TABLE(sdio, sdio_uart_ids);
+
+static struct sdio_driver sdio_uart_driver = {
+       .probe          = sdio_uart_probe,
+       .remove         = sdio_uart_remove,
+       .name           = "sdio_uart",
+       .id_table       = sdio_uart_ids,
+};
+
+static int __init sdio_uart_init(void)
+{
+       int ret;
+       struct tty_driver *tty_drv;
+
+       sdio_uart_tty_driver = tty_drv = alloc_tty_driver(UART_NR);
+       if (!tty_drv)
+               return -ENOMEM;
+
+       tty_drv->owner = THIS_MODULE;
+       tty_drv->driver_name = "sdio_uart";
+       tty_drv->name =   "ttySDIO";
+       tty_drv->major = 0;  /* dynamically allocated */
+       tty_drv->minor_start = 0;
+       tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
+       tty_drv->subtype = SERIAL_TYPE_NORMAL;
+       tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+       tty_drv->init_termios = tty_std_termios;
+       tty_drv->init_termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL;
+       tty_drv->init_termios.c_ispeed = 4800;
+       tty_drv->init_termios.c_ospeed = 4800;
+       tty_set_operations(tty_drv, &sdio_uart_ops);
+
+       ret = tty_register_driver(tty_drv);
+       if (ret)
+               goto err1;
+
+       ret = sdio_register_driver(&sdio_uart_driver);
+       if (ret)
+               goto err2;
+
+       return 0;
+
+err2:
+       tty_unregister_driver(tty_drv);
+err1:
+       put_tty_driver(tty_drv);
+       return ret;
+}
+
+static void __exit sdio_uart_exit(void)
+{
+       sdio_unregister_driver(&sdio_uart_driver);
+       tty_unregister_driver(sdio_uart_tty_driver);
+       put_tty_driver(sdio_uart_tty_driver);
+}
+
+module_init(sdio_uart_init);
+module_exit(sdio_uart_exit);
+
+MODULE_AUTHOR("Nicolas Pitre");
+MODULE_LICENSE("GPL");
index 3fdd08c7f143c8f874db806a948e54790f299efc..4985807257a8f0c621ec855add57103ce6b042ef 100644 (file)
@@ -8,5 +8,7 @@ endif
 
 obj-$(CONFIG_MMC)              += mmc_core.o
 mmc_core-y                     := core.o sysfs.o bus.o host.o \
-                                  mmc.o mmc_ops.o sd.o sd_ops.o
+                                  mmc.o mmc_ops.o sd.o sd_ops.o \
+                                  sdio.o sdio_ops.o sdio_bus.o \
+                                  sdio_cis.o sdio_io.o sdio_irq.o
 
index 817a79462b3d5747e75057ac7f6819d925ae4d4e..8d6f6014870f2cebfa8030fca45549b1cfc7fe30 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "sysfs.h"
 #include "core.h"
+#include "sdio_cis.h"
 #include "bus.h"
 
 #define dev_to_mmc_card(d)     container_of(d, struct mmc_card, dev)
@@ -34,6 +35,8 @@ static ssize_t mmc_type_show(struct device *dev,
                return sprintf(buf, "MMC\n");
        case MMC_TYPE_SD:
                return sprintf(buf, "SD\n");
+       case MMC_TYPE_SDIO:
+               return sprintf(buf, "SDIO\n");
        default:
                return -EFAULT;
        }
@@ -59,28 +62,34 @@ mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
                int buf_size)
 {
        struct mmc_card *card = dev_to_mmc_card(dev);
-       int retval = 0, i = 0, length = 0;
-
-#define add_env(fmt,val) do {                                  \
-       retval = add_uevent_var(envp, num_envp, &i,             \
-                               buf, buf_size, &length,         \
-                               fmt, val);                      \
-       if (retval)                                             \
-               return retval;                                  \
-} while (0);
+       const char *type;
+       int i = 0, length = 0;
 
        switch (card->type) {
        case MMC_TYPE_MMC:
-               add_env("MMC_TYPE=%s", "MMC");
+               type = "MMC";
                break;
        case MMC_TYPE_SD:
-               add_env("MMC_TYPE=%s", "SD");
+               type = "SD";
+               break;
+       case MMC_TYPE_SDIO:
+               type = "SDIO";
                break;
+       default:
+               type = NULL;
        }
 
-       add_env("MMC_NAME=%s", mmc_card_name(card));
+       if (type) {
+               if (add_uevent_var(envp, num_envp, &i,
+                               buf, buf_size, &length,
+                               "MMC_TYPE=%s", type))
+                       return -ENOMEM;
+       }
 
-#undef add_env
+       if (add_uevent_var(envp, num_envp, &i,
+                       buf, buf_size, &length,
+                       "MMC_NAME=%s", mmc_card_name(card)))
+               return -ENOMEM;
 
        envp[i] = NULL;
 
@@ -176,6 +185,11 @@ static void mmc_release_card(struct device *dev)
 {
        struct mmc_card *card = dev_to_mmc_card(dev);
 
+       sdio_free_common_cis(card);
+
+       if (card->info)
+               kfree(card->info);
+
        kfree(card);
 }
 
@@ -221,15 +235,25 @@ int mmc_add_card(struct mmc_card *card)
                if (mmc_card_blockaddr(card))
                        type = "SDHC";
                break;
+       case MMC_TYPE_SDIO:
+               type = "SDIO";
+               break;
        default:
                type = "?";
                break;
        }
 
-       printk(KERN_INFO "%s: new %s%s card at address %04x\n",
-               mmc_hostname(card->host),
-               mmc_card_highspeed(card) ? "high speed " : "",
-               type, card->rca);
+       if (mmc_host_is_spi(card->host)) {
+               printk(KERN_INFO "%s: new %s%s card on SPI\n",
+                       mmc_hostname(card->host),
+                       mmc_card_highspeed(card) ? "high speed " : "",
+                       type);
+       } else {
+               printk(KERN_INFO "%s: new %s%s card at address %04x\n",
+                       mmc_hostname(card->host),
+                       mmc_card_highspeed(card) ? "high speed " : "",
+                       type, card->rca);
+       }
 
        card->dev.uevent_suppress = 1;
 
@@ -261,8 +285,13 @@ int mmc_add_card(struct mmc_card *card)
 void mmc_remove_card(struct mmc_card *card)
 {
        if (mmc_card_present(card)) {
-               printk(KERN_INFO "%s: card %04x removed\n",
-                       mmc_hostname(card->host), card->rca);
+               if (mmc_host_is_spi(card->host)) {
+                       printk(KERN_INFO "%s: SPI card removed\n",
+                               mmc_hostname(card->host));
+               } else {
+                       printk(KERN_INFO "%s: card %04x removed\n",
+                               mmc_hostname(card->host), card->rca);
+               }
 
                if (card->host->bus_ops->sysfs_remove)
                        card->host->bus_ops->sysfs_remove(card->host, card);
index bfd2ae5bd669fe2a61307995832f2fd2bcb0c4c2..09435e0ec6806fa4771fb616227413bbc5c2dd33 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/pagemap.h>
 #include <linux/err.h>
+#include <linux/leds.h>
 #include <asm/scatterlist.h>
 #include <linux/scatterlist.h>
 
 #include "core.h"
 #include "bus.h"
 #include "host.h"
+#include "sdio_bus.h"
 
 #include "mmc_ops.h"
 #include "sd_ops.h"
+#include "sdio_ops.h"
 
 extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr);
 extern int mmc_attach_sd(struct mmc_host *host, u32 ocr);
+extern int mmc_attach_sdio(struct mmc_host *host, u32 ocr);
 
 static struct workqueue_struct *workqueue;
 
+/*
+ * Enabling software CRCs on the data blocks can be a significant (30%)
+ * performance cost, and for other reasons may not always be desired.
+ * So we allow it it to be disabled.
+ */
+int use_spi_crc = 1;
+module_param(use_spi_crc, bool, 0);
+
 /*
  * Internal function. Schedule delayed work in the MMC work queue.
  */
@@ -68,6 +80,11 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
        struct mmc_command *cmd = mrq->cmd;
        int err = cmd->error;
 
+       if (err && cmd->retries && mmc_host_is_spi(host)) {
+               if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
+                       cmd->retries = 0;
+       }
+
        if (err && cmd->retries) {
                pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
                        mmc_hostname(host), cmd->opcode, err);
@@ -76,6 +93,8 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
                cmd->error = 0;
                host->ops->request(host, mrq);
        } else {
+               led_trigger_event(host->led, LED_OFF);
+
                pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n",
                        mmc_hostname(host), cmd->opcode, err,
                        cmd->resp[0], cmd->resp[1],
@@ -118,7 +137,7 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
                        "tsac %d ms nsac %d\n",
                        mmc_hostname(host), mrq->data->blksz,
                        mrq->data->blocks, mrq->data->flags,
-                       mrq->data->timeout_ns / 10000000,
+                       mrq->data->timeout_ns / 1000000,
                        mrq->data->timeout_clks);
        }
 
@@ -130,6 +149,8 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
 
        WARN_ON(!host->claimed);
 
+       led_trigger_event(host->led, LED_FULL);
+
        mrq->cmd->error = 0;
        mrq->cmd->mrq = mrq;
        if (mrq->data) {
@@ -199,7 +220,7 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries
 {
        struct mmc_request mrq;
 
-       BUG_ON(!host->claimed);
+       WARN_ON(!host->claimed);
 
        memset(&mrq, 0, sizeof(struct mmc_request));
 
@@ -220,16 +241,23 @@ EXPORT_SYMBOL(mmc_wait_for_cmd);
  *     mmc_set_data_timeout - set the timeout for a data command
  *     @data: data phase for command
  *     @card: the MMC card associated with the data transfer
- *     @write: flag to differentiate reads from writes
  *
  *     Computes the data timeout parameters according to the
  *     correct algorithm given the card type.
  */
-void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card,
-                         int write)
+void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
 {
        unsigned int mult;
 
+       /*
+        * SDIO cards only define an upper 1 s limit on access.
+        */
+       if (mmc_card_sdio(card)) {
+               data->timeout_ns = 1000000000;
+               data->timeout_clks = 0;
+               return;
+       }
+
        /*
         * SD cards use a 100 multiplier rather than 10
         */
@@ -239,7 +267,7 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card,
         * Scale up the multiplier (and therefore the timeout) by
         * the r2w factor for writes.
         */
-       if (write)
+       if (data->flags & MMC_DATA_WRITE)
                mult <<= card->csd.r2w_factor;
 
        data->timeout_ns = card->csd.tacc_ns * mult;
@@ -255,7 +283,7 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card,
                timeout_us += data->timeout_clks * 1000 /
                        (card->host->ios.clock / 1000);
 
-               if (write)
+               if (data->flags & MMC_DATA_WRITE)
                        limit_us = 250000;
                else
                        limit_us = 100000;
@@ -272,15 +300,20 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card,
 EXPORT_SYMBOL(mmc_set_data_timeout);
 
 /**
- *     mmc_claim_host - exclusively claim a host
+ *     __mmc_claim_host - exclusively claim a host
  *     @host: mmc host to claim
+ *     @abort: whether or not the operation should be aborted
  *
- *     Claim a host for a set of operations.
+ *     Claim a host for a set of operations.  If @abort is non null and
+ *     dereference a non-zero value then this will return prematurely with
+ *     that non-zero value without acquiring the lock.  Returns zero
+ *     with the lock held otherwise.
  */
-void mmc_claim_host(struct mmc_host *host)
+int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
 {
        DECLARE_WAITQUEUE(wait, current);
        unsigned long flags;
+       int stop;
 
        might_sleep();
 
@@ -288,19 +321,24 @@ void mmc_claim_host(struct mmc_host *host)
        spin_lock_irqsave(&host->lock, flags);
        while (1) {
                set_current_state(TASK_UNINTERRUPTIBLE);
-               if (!host->claimed)
+               stop = abort ? atomic_read(abort) : 0;
+               if (stop || !host->claimed)
                        break;
                spin_unlock_irqrestore(&host->lock, flags);
                schedule();
                spin_lock_irqsave(&host->lock, flags);
        }
        set_current_state(TASK_RUNNING);
-       host->claimed = 1;
+       if (!stop)
+               host->claimed = 1;
+       else
+               wake_up(&host->wq);
        spin_unlock_irqrestore(&host->lock, flags);
        remove_wait_queue(&host->wq, &wait);
+       return stop;
 }
 
-EXPORT_SYMBOL(mmc_claim_host);
+EXPORT_SYMBOL(__mmc_claim_host);
 
 /**
  *     mmc_release_host - release a host
@@ -313,7 +351,7 @@ void mmc_release_host(struct mmc_host *host)
 {
        unsigned long flags;
 
-       BUG_ON(!host->claimed);
+       WARN_ON(!host->claimed);
 
        spin_lock_irqsave(&host->lock, flags);
        host->claimed = 0;
@@ -433,19 +471,32 @@ static void mmc_power_up(struct mmc_host *host)
        int bit = fls(host->ocr_avail) - 1;
 
        host->ios.vdd = bit;
-       host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
-       host->ios.chip_select = MMC_CS_DONTCARE;
+       if (mmc_host_is_spi(host)) {
+               host->ios.chip_select = MMC_CS_HIGH;
+               host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
+       } else {
+               host->ios.chip_select = MMC_CS_DONTCARE;
+               host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
+       }
        host->ios.power_mode = MMC_POWER_UP;
        host->ios.bus_width = MMC_BUS_WIDTH_1;
        host->ios.timing = MMC_TIMING_LEGACY;
        mmc_set_ios(host);
 
-       mmc_delay(1);
+       /*
+        * This delay should be sufficient to allow the power supply
+        * to reach the minimum voltage.
+        */
+       mmc_delay(2);
 
        host->ios.clock = host->f_min;
        host->ios.power_mode = MMC_POWER_ON;
        mmc_set_ios(host);
 
+       /*
+        * This delay must be at least 74 clock sizes, or 1 ms, or the
+        * time required to reach a stable voltage.
+        */
        mmc_delay(2);
 }
 
@@ -453,8 +504,10 @@ static void mmc_power_off(struct mmc_host *host)
 {
        host->ios.clock = 0;
        host->ios.vdd = 0;
-       host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
-       host->ios.chip_select = MMC_CS_DONTCARE;
+       if (!mmc_host_is_spi(host)) {
+               host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
+               host->ios.chip_select = MMC_CS_DONTCARE;
+       }
        host->ios.power_mode = MMC_POWER_OFF;
        host->ios.bus_width = MMC_BUS_WIDTH_1;
        host->ios.timing = MMC_TIMING_LEGACY;
@@ -511,7 +564,7 @@ void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops)
        BUG_ON(!host);
        BUG_ON(!ops);
 
-       BUG_ON(!host->claimed);
+       WARN_ON(!host->claimed);
 
        spin_lock_irqsave(&host->lock, flags);
 
@@ -535,8 +588,8 @@ void mmc_detach_bus(struct mmc_host *host)
 
        BUG_ON(!host);
 
-       BUG_ON(!host->claimed);
-       BUG_ON(!host->bus_ops);
+       WARN_ON(!host->claimed);
+       WARN_ON(!host->bus_ops);
 
        spin_lock_irqsave(&host->lock, flags);
 
@@ -564,7 +617,7 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay)
 #ifdef CONFIG_MMC_DEBUG
        unsigned long flags;
        spin_lock_irqsave(&host->lock, flags);
-       BUG_ON(host->removed);
+       WARN_ON(host->removed);
        spin_unlock_irqrestore(&host->lock, flags);
 #endif
 
@@ -597,24 +650,38 @@ void mmc_rescan(struct work_struct *work)
 
                mmc_send_if_cond(host, host->ocr_avail);
 
+               /*
+                * First we search for SDIO...
+                */
+               err = mmc_send_io_op_cond(host, 0, &ocr);
+               if (!err) {
+                       if (mmc_attach_sdio(host, ocr))
+                               mmc_power_off(host);
+                       return;
+               }
+
+               /*
+                * ...then normal SD...
+                */
                err = mmc_send_app_op_cond(host, 0, &ocr);
-               if (err == MMC_ERR_NONE) {
+               if (!err) {
                        if (mmc_attach_sd(host, ocr))
                                mmc_power_off(host);
-               } else {
-                       /*
-                        * If we fail to detect any SD cards then try
-                        * searching for MMC cards.
-                        */
-                       err = mmc_send_op_cond(host, 0, &ocr);
-                       if (err == MMC_ERR_NONE) {
-                               if (mmc_attach_mmc(host, ocr))
-                                       mmc_power_off(host);
-                       } else {
+                       return;
+               }
+
+               /*
+                * ...and finally MMC.
+                */
+               err = mmc_send_op_cond(host, 0, &ocr);
+               if (!err) {
+                       if (mmc_attach_mmc(host, ocr))
                                mmc_power_off(host);
-                               mmc_release_host(host);
-                       }
+                       return;
                }
+
+               mmc_release_host(host);
+               mmc_power_off(host);
        } else {
                if (host->bus_ops->detect && !host->bus_dead)
                        host->bus_ops->detect(host);
@@ -725,22 +792,38 @@ static int __init mmc_init(void)
                return -ENOMEM;
 
        ret = mmc_register_bus();
-       if (ret == 0) {
-               ret = mmc_register_host_class();
-               if (ret)
-                       mmc_unregister_bus();
-       }
+       if (ret)
+               goto destroy_workqueue;
+
+       ret = mmc_register_host_class();
+       if (ret)
+               goto unregister_bus;
+
+       ret = sdio_register_bus();
+       if (ret)
+               goto unregister_host_class;
+
+       return 0;
+
+unregister_host_class:
+       mmc_unregister_host_class();
+unregister_bus:
+       mmc_unregister_bus();
+destroy_workqueue:
+       destroy_workqueue(workqueue);
+
        return ret;
 }
 
 static void __exit mmc_exit(void)
 {
+       sdio_unregister_bus();
        mmc_unregister_host_class();
        mmc_unregister_bus();
        destroy_workqueue(workqueue);
 }
 
-module_init(mmc_init);
+subsys_initcall(mmc_init);
 module_exit(mmc_exit);
 
 MODULE_LICENSE("GPL");
index bb2774af9ea91d9891b3b4ba752b4c7221266e8e..39daf2fb5dc46c67691a50e8c72987f797f1c488 100644 (file)
@@ -48,5 +48,7 @@ void mmc_rescan(struct work_struct *work);
 void mmc_start_host(struct mmc_host *host);
 void mmc_stop_host(struct mmc_host *host);
 
+extern int use_spi_crc;
+
 #endif
 
index 2c7ce8f43a9a60367a6f75397a7da831c3afe8d3..64fbc9759a30757426de0270b0afa25d5c31ea94 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/err.h>
 #include <linux/idr.h>
 #include <linux/pagemap.h>
+#include <linux/leds.h>
 
 #include <linux/mmc/host.h>
 
@@ -100,6 +101,9 @@ int mmc_add_host(struct mmc_host *host)
 {
        int err;
 
+       WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
+               !host->ops->enable_sdio_irq);
+
        if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL))
                return -ENOMEM;
 
@@ -112,6 +116,8 @@ int mmc_add_host(struct mmc_host *host)
        snprintf(host->class_dev.bus_id, BUS_ID_SIZE,
                 "mmc%d", host->index);
 
+       led_trigger_register_simple(host->class_dev.bus_id, &host->led);
+
        err = device_add(&host->class_dev);
        if (err)
                return err;
@@ -137,6 +143,8 @@ void mmc_remove_host(struct mmc_host *host)
 
        device_del(&host->class_dev);
 
+       led_trigger_unregister(host->led);
+
        spin_lock(&mmc_host_lock);
        idr_remove(&mmc_host_idr, host->index);
        spin_unlock(&mmc_host_lock);
index 21d7f48e1d4e67c33ff7f59a46955bc7e2e70df0..65fe28860f54431ed77e5069526c566e5376521a 100644 (file)
@@ -161,13 +161,12 @@ static int mmc_read_ext_csd(struct mmc_card *card)
 {
        int err;
        u8 *ext_csd;
+       unsigned int ext_csd_struct;
 
        BUG_ON(!card);
 
-       err = MMC_ERR_FAILED;
-
        if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
-               return MMC_ERR_NONE;
+               return 0;
 
        /*
         * As the ext_csd is so large and mostly unused, we don't store the
@@ -176,13 +175,19 @@ static int mmc_read_ext_csd(struct mmc_card *card)
        ext_csd = kmalloc(512, GFP_KERNEL);
        if (!ext_csd) {
                printk(KERN_ERR "%s: could not allocate a buffer to "
-                       "receive the ext_csd. mmc v4 cards will be "
-                       "treated as v3.\n", mmc_hostname(card->host));
-               return MMC_ERR_FAILED;
+                       "receive the ext_csd.\n", mmc_hostname(card->host));
+               return -ENOMEM;
        }
 
        err = mmc_send_ext_csd(card, ext_csd);
-       if (err != MMC_ERR_NONE) {
+       if (err) {
+               /*
+                * We all hosts that cannot perform the command
+                * to fail more gracefully
+                */
+               if (err != -EINVAL)
+                       goto out;
+
                /*
                 * High capacity cards should have this "magic" size
                 * stored in their CSD.
@@ -197,18 +202,29 @@ static int mmc_read_ext_csd(struct mmc_card *card)
                                "EXT_CSD, performance might "
                                "suffer.\n",
                                mmc_hostname(card->host));
-                       err = MMC_ERR_NONE;
+                       err = 0;
                }
+
                goto out;
        }
 
-       card->ext_csd.sectors =
-               ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
-               ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
-               ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
-               ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
-       if (card->ext_csd.sectors)
-               mmc_card_set_blockaddr(card);
+       ext_csd_struct = ext_csd[EXT_CSD_REV];
+       if (ext_csd_struct > 2) {
+               printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
+                       "version %d\n", mmc_hostname(card->host),
+                       ext_csd_struct);
+               return -EINVAL;
+       }
+
+       if (ext_csd_struct >= 2) {
+               card->ext_csd.sectors =
+                       ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
+                       ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
+                       ext_csd[EXT_CSD_SEC_CNT + 2] << 16 |
+                       ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
+               if (card->ext_csd.sectors)
+                       mmc_card_set_blockaddr(card);
+       }
 
        switch (ext_csd[EXT_CSD_CARD_TYPE]) {
        case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
@@ -246,7 +262,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
        unsigned int max_dtr;
 
        BUG_ON(!host);
-       BUG_ON(!host->claimed);
+       WARN_ON(!host->claimed);
 
        /*
         * Since we're changing the OCR value, we seem to
@@ -258,19 +274,33 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 
        /* The extra bit indicates that we support high capacity */
        err = mmc_send_op_cond(host, ocr | (1 << 30), NULL);
-       if (err != MMC_ERR_NONE)
+       if (err)
                goto err;
 
+       /*
+        * For SPI, enable CRC as appropriate.
+        */
+       if (mmc_host_is_spi(host)) {
+               err = mmc_spi_set_crc(host, use_spi_crc);
+               if (err)
+                       goto err;
+       }
+
        /*
         * Fetch CID from card.
         */
-       err = mmc_all_send_cid(host, cid);
-       if (err != MMC_ERR_NONE)
+       if (mmc_host_is_spi(host))
+               err = mmc_send_cid(host, cid);
+       else
+               err = mmc_all_send_cid(host, cid);
+       if (err)
                goto err;
 
        if (oldcard) {
-               if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)
+               if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
+                       err = -ENOENT;
                        goto err;
+               }
 
                card = oldcard;
        } else {
@@ -278,8 +308,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                 * Allocate card structure.
                 */
                card = mmc_alloc_card(host);
-               if (IS_ERR(card))
+               if (IS_ERR(card)) {
+                       err = PTR_ERR(card);
                        goto err;
+               }
 
                card->type = MMC_TYPE_MMC;
                card->rca = 1;
@@ -287,43 +319,47 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
        }
 
        /*
-        * Set card RCA.
+        * For native busses:  set card RCA and quit open drain mode.
         */
-       err = mmc_set_relative_addr(card);
-       if (err != MMC_ERR_NONE)
-               goto free_card;
+       if (!mmc_host_is_spi(host)) {
+               err = mmc_set_relative_addr(card);
+               if (err)
+                       goto free_card;
 
-       mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
+               mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
+       }
 
        if (!oldcard) {
                /*
                 * Fetch CSD from card.
                 */
                err = mmc_send_csd(card, card->raw_csd);
-               if (err != MMC_ERR_NONE)
+               if (err)
                        goto free_card;
 
                err = mmc_decode_csd(card);
-               if (err < 0)
+               if (err)
                        goto free_card;
                err = mmc_decode_cid(card);
-               if (err < 0)
+               if (err)
                        goto free_card;
        }
 
        /*
         * Select card, as all following commands rely on that.
         */
-       err = mmc_select_card(card);
-       if (err != MMC_ERR_NONE)
-               goto free_card;
+       if (!mmc_host_is_spi(host)) {
+               err = mmc_select_card(card);
+               if (err)
+                       goto free_card;
+       }
 
        if (!oldcard) {
                /*
-                * Fetch and process extened CSD.
+                * Fetch and process extended CSD.
                 */
                err = mmc_read_ext_csd(card);
-               if (err != MMC_ERR_NONE)
+               if (err)
                        goto free_card;
        }
 
@@ -334,7 +370,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                (host->caps & MMC_CAP_MMC_HIGHSPEED)) {
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                        EXT_CSD_HS_TIMING, 1);
-               if (err != MMC_ERR_NONE)
+               if (err)
                        goto free_card;
 
                mmc_card_set_highspeed(card);
@@ -363,7 +399,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                (host->caps & MMC_CAP_4_BIT_DATA)) {
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                        EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4);
-               if (err != MMC_ERR_NONE)
+               if (err)
                        goto free_card;
 
                mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
@@ -372,14 +408,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
        if (!oldcard)
                host->card = card;
 
-       return MMC_ERR_NONE;
+       return 0;
 
 free_card:
        if (!oldcard)
                mmc_remove_card(card);
 err:
 
-       return MMC_ERR_FAILED;
+       return err;
 }
 
 /*
@@ -413,7 +449,7 @@ static void mmc_detect(struct mmc_host *host)
 
        mmc_release_host(host);
 
-       if (err != MMC_ERR_NONE) {
+       if (err) {
                mmc_remove(host);
 
                mmc_claim_host(host);
@@ -480,7 +516,8 @@ static void mmc_suspend(struct mmc_host *host)
        BUG_ON(!host->card);
 
        mmc_claim_host(host);
-       mmc_deselect_cards(host);
+       if (!mmc_host_is_spi(host))
+               mmc_deselect_cards(host);
        host->card->state &= ~MMC_STATE_HIGHSPEED;
        mmc_release_host(host);
 }
@@ -502,7 +539,7 @@ static void mmc_resume(struct mmc_host *host)
        err = mmc_init_card(host, host->ocr, host->card);
        mmc_release_host(host);
 
-       if (err != MMC_ERR_NONE) {
+       if (err) {
                mmc_remove(host);
 
                mmc_claim_host(host);
@@ -536,10 +573,19 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
        int err;
 
        BUG_ON(!host);
-       BUG_ON(!host->claimed);
+       WARN_ON(!host->claimed);
 
        mmc_attach_bus(host, &mmc_ops);
 
+       /*
+        * We need to get OCR a different way for SPI.
+        */
+       if (mmc_host_is_spi(host)) {
+               err = mmc_spi_read_ocr(host, 1, &ocr);
+               if (err)
+                       goto err;
+       }
+
        /*
         * Sanity check the voltages that the card claims to
         * support.
@@ -565,7 +611,7 @@ int mmc_attach_mmc(struct mmc_host *host, u32 ocr)
         * Detect and init the card.
         */
        err = mmc_init_card(host, host->ocr, NULL);
-       if (err != MMC_ERR_NONE)
+       if (err)
                goto err;
 
        mmc_release_host(host);
@@ -587,6 +633,6 @@ err:
        printk(KERN_ERR "%s: error %d whilst initialising MMC card\n",
                mmc_hostname(host), err);
 
-       return 0;
+       return err;
 }
 
index 913e75f008434179e45780ffb7e57ba7c6ff3d9e..bf4bc6adcfef8fbed951a274ee2cc4ca12dae36f 100644 (file)
@@ -40,10 +40,10 @@ static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
        }
 
        err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
-       if (err != MMC_ERR_NONE)
+       if (err)
                return err;
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
 int mmc_select_card(struct mmc_card *card)
@@ -63,23 +63,36 @@ int mmc_go_idle(struct mmc_host *host)
        int err;
        struct mmc_command cmd;
 
-       mmc_set_chip_select(host, MMC_CS_HIGH);
-
-       mmc_delay(1);
+       /*
+        * Non-SPI hosts need to prevent chipselect going active during
+        * GO_IDLE; that would put chips into SPI mode.  Remind them of
+        * that in case of hardware that won't pull up DAT3/nCS otherwise.
+        *
+        * SPI hosts ignore ios.chip_select; it's managed according to
+        * rules that must accomodate non-MMC slaves which this layer
+        * won't even know about.
+        */
+       if (!mmc_host_is_spi(host)) {
+               mmc_set_chip_select(host, MMC_CS_HIGH);
+               mmc_delay(1);
+       }
 
        memset(&cmd, 0, sizeof(struct mmc_command));
 
        cmd.opcode = MMC_GO_IDLE_STATE;
        cmd.arg = 0;
-       cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC;
 
        err = mmc_wait_for_cmd(host, &cmd, 0);
 
        mmc_delay(1);
 
-       mmc_set_chip_select(host, MMC_CS_DONTCARE);
+       if (!mmc_host_is_spi(host)) {
+               mmc_set_chip_select(host, MMC_CS_DONTCARE);
+               mmc_delay(1);
+       }
 
-       mmc_delay(1);
+       host->use_spi_crc = 0;
 
        return err;
 }
@@ -94,23 +107,33 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
        memset(&cmd, 0, sizeof(struct mmc_command));
 
        cmd.opcode = MMC_SEND_OP_COND;
-       cmd.arg = ocr;
-       cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
+       cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
 
        for (i = 100; i; i--) {
                err = mmc_wait_for_cmd(host, &cmd, 0);
-               if (err != MMC_ERR_NONE)
+               if (err)
                        break;
 
-               if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)
+               /* if we're just probing, do a single pass */
+               if (ocr == 0)
                        break;
 
-               err = MMC_ERR_TIMEOUT;
+               /* otherwise wait until reset completes */
+               if (mmc_host_is_spi(host)) {
+                       if (!(cmd.resp[0] & R1_SPI_IDLE))
+                               break;
+               } else {
+                       if (cmd.resp[0] & MMC_CARD_BUSY)
+                               break;
+               }
+
+               err = -ETIMEDOUT;
 
                mmc_delay(10);
        }
 
-       if (rocr)
+       if (rocr && !mmc_host_is_spi(host))
                *rocr = cmd.resp[0];
 
        return err;
@@ -131,12 +154,12 @@ int mmc_all_send_cid(struct mmc_host *host, u32 *cid)
        cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
 
        err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
-       if (err != MMC_ERR_NONE)
+       if (err)
                return err;
 
        memcpy(cid, cmd.resp, sizeof(u32) * 4);
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
 int mmc_set_relative_addr(struct mmc_card *card)
@@ -154,46 +177,52 @@ int mmc_set_relative_addr(struct mmc_card *card)
        cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
        err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
-       if (err != MMC_ERR_NONE)
+       if (err)
                return err;
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
-int mmc_send_csd(struct mmc_card *card, u32 *csd)
+static int
+mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode)
 {
        int err;
        struct mmc_command cmd;
 
-       BUG_ON(!card);
-       BUG_ON(!card->host);
-       BUG_ON(!csd);
+       BUG_ON(!host);
+       BUG_ON(!cxd);
 
        memset(&cmd, 0, sizeof(struct mmc_command));
 
-       cmd.opcode = MMC_SEND_CSD;
-       cmd.arg = card->rca << 16;
+       cmd.opcode = opcode;
+       cmd.arg = arg;
        cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
 
-       err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
-       if (err != MMC_ERR_NONE)
+       err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
+       if (err)
                return err;
 
-       memcpy(csd, cmd.resp, sizeof(u32) * 4);
+       memcpy(cxd, cmd.resp, sizeof(u32) * 4);
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
-int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
+static int
+mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
+               u32 opcode, void *buf, unsigned len)
 {
        struct mmc_request mrq;
        struct mmc_command cmd;
        struct mmc_data data;
        struct scatterlist sg;
+       void *data_buf;
 
-       BUG_ON(!card);
-       BUG_ON(!card->host);
-       BUG_ON(!ext_csd);
+       /* dma onto stack is unsafe/nonportable, but callers to this
+        * routine normally provide temporary on-stack buffers ...
+        */
+       data_buf = kmalloc(len, GFP_KERNEL);
+       if (data_buf == NULL)
+               return -ENOMEM;
 
        memset(&mrq, 0, sizeof(struct mmc_request));
        memset(&cmd, 0, sizeof(struct mmc_command));
@@ -202,28 +231,99 @@ int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
        mrq.cmd = &cmd;
        mrq.data = &data;
 
-       cmd.opcode = MMC_SEND_EXT_CSD;
+       cmd.opcode = opcode;
        cmd.arg = 0;
-       cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
 
-       data.blksz = 512;
+       /* NOTE HACK:  the MMC_RSP_SPI_R1 is always correct here, but we
+        * rely on callers to never use this with "native" calls for reading
+        * CSD or CID.  Native versions of those commands use the R2 type,
+        * not R1 plus a data block.
+        */
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
+
+       data.blksz = len;
        data.blocks = 1;
        data.flags = MMC_DATA_READ;
        data.sg = &sg;
        data.sg_len = 1;
 
-       sg_init_one(&sg, ext_csd, 512);
+       sg_init_one(&sg, data_buf, len);
 
-       mmc_set_data_timeout(&data, card, 0);
+       if (card)
+               mmc_set_data_timeout(&data, card);
 
-       mmc_wait_for_req(card->host, &mrq);
+       mmc_wait_for_req(host, &mrq);
 
-       if (cmd.error != MMC_ERR_NONE)
+       memcpy(buf, data_buf, len);
+       kfree(data_buf);
+
+       if (cmd.error)
                return cmd.error;
-       if (data.error != MMC_ERR_NONE)
+       if (data.error)
                return data.error;
 
-       return MMC_ERR_NONE;
+       return 0;
+}
+
+int mmc_send_csd(struct mmc_card *card, u32 *csd)
+{
+       if (!mmc_host_is_spi(card->host))
+               return mmc_send_cxd_native(card->host, card->rca << 16,
+                               csd, MMC_SEND_CSD);
+
+       return mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16);
+}
+
+int mmc_send_cid(struct mmc_host *host, u32 *cid)
+{
+       if (!mmc_host_is_spi(host)) {
+               if (!host->card)
+                       return -EINVAL;
+               return mmc_send_cxd_native(host, host->card->rca << 16,
+                               cid, MMC_SEND_CID);
+       }
+
+       return mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16);
+}
+
+int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
+{
+       return mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD,
+                       ext_csd, 512);
+}
+
+int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp)
+{
+       struct mmc_command cmd;
+       int err;
+
+       memset(&cmd, 0, sizeof(struct mmc_command));
+
+       cmd.opcode = MMC_SPI_READ_OCR;
+       cmd.arg = highcap ? (1 << 30) : 0;
+       cmd.flags = MMC_RSP_SPI_R3;
+
+       err = mmc_wait_for_cmd(host, &cmd, 0);
+
+       *ocrp = cmd.resp[1];
+       return err;
+}
+
+int mmc_spi_set_crc(struct mmc_host *host, int use_crc)
+{
+       struct mmc_command cmd;
+       int err;
+
+       memset(&cmd, 0, sizeof(struct mmc_command));
+
+       cmd.opcode = MMC_SPI_CRC_ON_OFF;
+       cmd.flags = MMC_RSP_SPI_R1;
+       cmd.arg = use_crc;
+
+       err = mmc_wait_for_cmd(host, &cmd, 0);
+       if (!err)
+               host->use_spi_crc = use_crc;
+       return err;
 }
 
 int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value)
@@ -241,13 +341,13 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value)
                  (index << 16) |
                  (value << 8) |
                  set;
-       cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
+       cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
 
        err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
-       if (err != MMC_ERR_NONE)
+       if (err)
                return err;
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
 int mmc_send_status(struct mmc_card *card, u32 *status)
@@ -261,16 +361,20 @@ int mmc_send_status(struct mmc_card *card, u32 *status)
        memset(&cmd, 0, sizeof(struct mmc_command));
 
        cmd.opcode = MMC_SEND_STATUS;
-       cmd.arg = card->rca << 16;
-       cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+       if (!mmc_host_is_spi(card->host))
+               cmd.arg = card->rca << 16;
+       cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
 
        err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
-       if (err != MMC_ERR_NONE)
+       if (err)
                return err;
 
+       /* NOTE: callers are required to understand the difference
+        * between "native" and SPI format status words!
+        */
        if (status)
                *status = cmd.resp[0];
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
index 76d09a93c5d6c991cbe394889e12428845bacff4..17854bf7cf0d1e36601389d118e178b89f74363e 100644 (file)
@@ -22,6 +22,9 @@ int mmc_send_csd(struct mmc_card *card, u32 *csd);
 int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd);
 int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value);
 int mmc_send_status(struct mmc_card *card, u32 *status);
+int mmc_send_cid(struct mmc_host *host, u32 *cid);
+int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp);
+int mmc_spi_set_crc(struct mmc_host *host, int use_crc);
 
 #endif
 
index 1edc62b1e5c65d4625daf17ee0d0429c34a95d1c..d1c1e0f592f19d56f1b200aa4233f1c95e125054 100644 (file)
@@ -166,8 +166,6 @@ static int mmc_decode_scr(struct mmc_card *card)
        unsigned int scr_struct;
        u32 resp[4];
 
-       BUG_ON(!mmc_card_sd(card));
-
        resp[3] = card->raw_scr[1];
        resp[2] = card->raw_scr[0];
 
@@ -193,30 +191,38 @@ static int mmc_read_switch(struct mmc_card *card)
        u8 *status;
 
        if (card->scr.sda_vsn < SCR_SPEC_VER_1)
-               return MMC_ERR_NONE;
+               return 0;
 
        if (!(card->csd.cmdclass & CCC_SWITCH)) {
                printk(KERN_WARNING "%s: card lacks mandatory switch "
                        "function, performance might suffer.\n",
                        mmc_hostname(card->host));
-               return MMC_ERR_NONE;
+               return 0;
        }
 
-       err = MMC_ERR_FAILED;
+       err = -EIO;
 
        status = kmalloc(64, GFP_KERNEL);
        if (!status) {
                printk(KERN_ERR "%s: could not allocate a buffer for "
                        "switch capabilities.\n", mmc_hostname(card->host));
-               return err;
+               return -ENOMEM;
        }
 
        err = mmc_sd_switch(card, 0, 0, 1, status);
-       if (err != MMC_ERR_NONE) {
+       if (err) {
+               /*
+                * We all hosts that cannot perform the command
+                * to fail more gracefully
+                */
+               if (err != -EINVAL)
+                       goto out;
+
                printk(KERN_WARNING "%s: problem reading switch "
                        "capabilities, performance might suffer.\n",
                        mmc_hostname(card->host));
-               err = MMC_ERR_NONE;
+               err = 0;
+
                goto out;
        }
 
@@ -238,28 +244,28 @@ static int mmc_switch_hs(struct mmc_card *card)
        u8 *status;
 
        if (card->scr.sda_vsn < SCR_SPEC_VER_1)
-               return MMC_ERR_NONE;
+               return 0;
 
        if (!(card->csd.cmdclass & CCC_SWITCH))
-               return MMC_ERR_NONE;
+               return 0;
 
        if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
-               return MMC_ERR_NONE;
+               return 0;
 
        if (card->sw_caps.hs_max_dtr == 0)
-               return MMC_ERR_NONE;
+               return 0;
 
-       err = MMC_ERR_FAILED;
+       err = -EIO;
 
        status = kmalloc(64, GFP_KERNEL);
        if (!status) {
                printk(KERN_ERR "%s: could not allocate a buffer for "
                        "switch capabilities.\n", mmc_hostname(card->host));
-               return err;
+               return -ENOMEM;
        }
 
        err = mmc_sd_switch(card, 1, 0, 1, status);
-       if (err != MMC_ERR_NONE)
+       if (err)
                goto out;
 
        if ((status[16] & 0xF) != 1) {
@@ -292,7 +298,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
        unsigned int max_dtr;
 
        BUG_ON(!host);
-       BUG_ON(!host->claimed);
+       WARN_ON(!host->claimed);
 
        /*
         * Since we're changing the OCR value, we seem to
@@ -309,23 +315,37 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
         * block-addressed SDHC cards.
         */
        err = mmc_send_if_cond(host, ocr);
-       if (err == MMC_ERR_NONE)
+       if (!err)
                ocr |= 1 << 30;
 
        err = mmc_send_app_op_cond(host, ocr, NULL);
-       if (err != MMC_ERR_NONE)
+       if (err)
                goto err;
 
+       /*
+        * For SPI, enable CRC as appropriate.
+        */
+       if (mmc_host_is_spi(host)) {
+               err = mmc_spi_set_crc(host, use_spi_crc);
+               if (err)
+                       goto err;
+       }
+
        /*
         * Fetch CID from card.
         */
-       err = mmc_all_send_cid(host, cid);
-       if (err != MMC_ERR_NONE)
+       if (mmc_host_is_spi(host))
+               err = mmc_send_cid(host, cid);
+       else
+               err = mmc_all_send_cid(host, cid);
+       if (err)
                goto err;
 
        if (oldcard) {
-               if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)
+               if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
+                       err = -ENOENT;
                        goto err;
+               }
 
                card = oldcard;
        } else {
@@ -333,32 +353,36 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
                 * Allocate card structure.
                 */
                card = mmc_alloc_card(host);
-               if (IS_ERR(card))
+               if (IS_ERR(card)) {
+                       err = PTR_ERR(card);
                        goto err;
+               }
 
                card->type = MMC_TYPE_SD;
                memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
        }
 
        /*
-        * Set card RCA.
+        * For native busses:  get card RCA and quit open drain mode.
         */
-       err = mmc_send_relative_addr(host, &card->rca);
-       if (err != MMC_ERR_NONE)
-               goto free_card;
+       if (!mmc_host_is_spi(host)) {
+               err = mmc_send_relative_addr(host, &card->rca);
+               if (err)
+                       goto free_card;
 
-       mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
+               mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
+       }
 
        if (!oldcard) {
                /*
                 * Fetch CSD from card.
                 */
                err = mmc_send_csd(card, card->raw_csd);
-               if (err != MMC_ERR_NONE)
+               if (err)
                        goto free_card;
 
                err = mmc_decode_csd(card);
-               if (err < 0)
+               if (err)
                        goto free_card;
 
                mmc_decode_cid(card);
@@ -367,16 +391,18 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
        /*
         * Select card, as all following commands rely on that.
         */
-       err = mmc_select_card(card);
-       if (err != MMC_ERR_NONE)
-               goto free_card;
+       if (!mmc_host_is_spi(host)) {
+               err = mmc_select_card(card);
+               if (err)
+                       goto free_card;
+       }
 
        if (!oldcard) {
                /*
                 * Fetch SCR from card.
                 */
                err = mmc_app_send_scr(card, card->raw_scr);
-               if (err != MMC_ERR_NONE)
+               if (err)
                        goto free_card;
 
                err = mmc_decode_scr(card);
@@ -387,7 +413,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
                 * Fetch switch information from card.
                 */
                err = mmc_read_switch(card);
-               if (err != MMC_ERR_NONE)
+               if (err)
                        goto free_card;
        }
 
@@ -395,7 +421,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
         * Attempt to change to high-speed (if supported)
         */
        err = mmc_switch_hs(card);
-       if (err != MMC_ERR_NONE)
+       if (err)
                goto free_card;
 
        /*
@@ -418,7 +444,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
        if ((host->caps & MMC_CAP_4_BIT_DATA) &&
                (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
                err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
-               if (err != MMC_ERR_NONE)
+               if (err)
                        goto free_card;
 
                mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
@@ -442,14 +468,14 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
        if (!oldcard)
                host->card = card;
 
-       return MMC_ERR_NONE;
+       return 0;
 
 free_card:
        if (!oldcard)
                mmc_remove_card(card);
 err:
 
-       return MMC_ERR_FAILED;
+       return err;
 }
 
 /*
@@ -483,7 +509,7 @@ static void mmc_sd_detect(struct mmc_host *host)
 
        mmc_release_host(host);
 
-       if (err != MMC_ERR_NONE) {
+       if (err) {
                mmc_sd_remove(host);
 
                mmc_claim_host(host);
@@ -552,7 +578,8 @@ static void mmc_sd_suspend(struct mmc_host *host)
        BUG_ON(!host->card);
 
        mmc_claim_host(host);
-       mmc_deselect_cards(host);
+       if (!mmc_host_is_spi(host))
+               mmc_deselect_cards(host);
        host->card->state &= ~MMC_STATE_HIGHSPEED;
        mmc_release_host(host);
 }
@@ -574,7 +601,7 @@ static void mmc_sd_resume(struct mmc_host *host)
        err = mmc_sd_init_card(host, host->ocr, host->card);
        mmc_release_host(host);
 
-       if (err != MMC_ERR_NONE) {
+       if (err) {
                mmc_sd_remove(host);
 
                mmc_claim_host(host);
@@ -608,10 +635,21 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
        int err;
 
        BUG_ON(!host);
-       BUG_ON(!host->claimed);
+       WARN_ON(!host->claimed);
 
        mmc_attach_bus(host, &mmc_sd_ops);
 
+       /*
+        * We need to get OCR a different way for SPI.
+        */
+       if (mmc_host_is_spi(host)) {
+               mmc_go_idle(host);
+
+               err = mmc_spi_read_ocr(host, 0, &ocr);
+               if (err)
+                       goto err;
+       }
+
        /*
         * Sanity check the voltages that the card claims to
         * support.
@@ -644,7 +682,7 @@ int mmc_attach_sd(struct mmc_host *host, u32 ocr)
         * Detect and init the card.
         */
        err = mmc_sd_init_card(host, host->ocr, NULL);
-       if (err != MMC_ERR_NONE)
+       if (err)
                goto err;
 
        mmc_release_host(host);
@@ -666,6 +704,6 @@ err:
        printk(KERN_ERR "%s: error %d whilst initialising SD card\n",
                mmc_hostname(host), err);
 
-       return 0;
+       return err;
 }
 
index 342f340ebc2579d8c81dd231f526b140f87552d5..ee4029a24efdb59b87e213e0c431c58f6afdd46b 100644 (file)
@@ -33,21 +33,21 @@ static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
 
        if (card) {
                cmd.arg = card->rca << 16;
-               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+               cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
        } else {
                cmd.arg = 0;
-               cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR;
+               cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_BCR;
        }
 
        err = mmc_wait_for_cmd(host, &cmd, 0);
-       if (err != MMC_ERR_NONE)
+       if (err)
                return err;
 
        /* Check that card supported application commands */
-       if (!(cmd.resp[0] & R1_APP_CMD))
-               return MMC_ERR_FAILED;
+       if (!mmc_host_is_spi(host) && !(cmd.resp[0] & R1_APP_CMD))
+               return -EOPNOTSUPP;
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
 /**
@@ -73,7 +73,7 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
        BUG_ON(!cmd);
        BUG_ON(retries < 0);
 
-       err = MMC_ERR_INVALID;
+       err = -EIO;
 
        /*
         * We have to resend MMC_APP_CMD for each attempt so
@@ -83,8 +83,14 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
                memset(&mrq, 0, sizeof(struct mmc_request));
 
                err = mmc_app_cmd(host, card);
-               if (err != MMC_ERR_NONE)
+               if (err) {
+                       /* no point in retrying; no APP commands allowed */
+                       if (mmc_host_is_spi(host)) {
+                               if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
+                                       break;
+                       }
                        continue;
+               }
 
                memset(&mrq, 0, sizeof(struct mmc_request));
 
@@ -97,8 +103,14 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
                mmc_wait_for_req(host, &mrq);
 
                err = cmd->error;
-               if (cmd->error == MMC_ERR_NONE)
+               if (!cmd->error)
                        break;
+
+               /* no point in retrying illegal APP commands */
+               if (mmc_host_is_spi(host)) {
+                       if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
+                               break;
+               }
        }
 
        return err;
@@ -127,14 +139,14 @@ int mmc_app_set_bus_width(struct mmc_card *card, int width)
                cmd.arg = SD_BUS_WIDTH_4;
                break;
        default:
-               return MMC_ERR_INVALID;
+               return -EINVAL;
        }
 
        err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES);
-       if (err != MMC_ERR_NONE)
+       if (err)
                return err;
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
 int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
@@ -147,23 +159,36 @@ int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
        memset(&cmd, 0, sizeof(struct mmc_command));
 
        cmd.opcode = SD_APP_OP_COND;
-       cmd.arg = ocr;
-       cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
+       if (mmc_host_is_spi(host))
+               cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */
+       else
+               cmd.arg = ocr;
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
 
        for (i = 100; i; i--) {
                err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES);
-               if (err != MMC_ERR_NONE)
+               if (err)
                        break;
 
-               if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)
+               /* if we're just probing, do a single pass */
+               if (ocr == 0)
                        break;
 
-               err = MMC_ERR_TIMEOUT;
+               /* otherwise wait until reset completes */
+               if (mmc_host_is_spi(host)) {
+                       if (!(cmd.resp[0] & R1_SPI_IDLE))
+                               break;
+               } else {
+                       if (cmd.resp[0] & MMC_CARD_BUSY)
+                               break;
+               }
+
+               err = -ETIMEDOUT;
 
                mmc_delay(10);
        }
 
-       if (rocr)
+       if (rocr && !mmc_host_is_spi(host))
                *rocr = cmd.resp[0];
 
        return err;
@@ -174,6 +199,7 @@ int mmc_send_if_cond(struct mmc_host *host, u32 ocr)
        struct mmc_command cmd;
        int err;
        static const u8 test_pattern = 0xAA;
+       u8 result_pattern;
 
        /*
         * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND
@@ -182,16 +208,21 @@ int mmc_send_if_cond(struct mmc_host *host, u32 ocr)
         */
        cmd.opcode = SD_SEND_IF_COND;
        cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern;
-       cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR;
+       cmd.flags = MMC_RSP_SPI_R7 | MMC_RSP_R7 | MMC_CMD_BCR;
 
        err = mmc_wait_for_cmd(host, &cmd, 0);
-       if (err != MMC_ERR_NONE)
+       if (err)
                return err;
 
-       if ((cmd.resp[0] & 0xFF) != test_pattern)
-               return MMC_ERR_FAILED;
+       if (mmc_host_is_spi(host))
+               result_pattern = cmd.resp[1] & 0xFF;
+       else
+               result_pattern = cmd.resp[0] & 0xFF;
+
+       if (result_pattern != test_pattern)
+               return -EIO;
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
 int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)
@@ -209,12 +240,12 @@ int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)
        cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
 
        err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
-       if (err != MMC_ERR_NONE)
+       if (err)
                return err;
 
        *rca = cmd.resp[0] >> 16;
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
 int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
@@ -229,8 +260,10 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
        BUG_ON(!card->host);
        BUG_ON(!scr);
 
+       /* NOTE: caller guarantees scr is heap-allocated */
+
        err = mmc_app_cmd(card->host, card);
-       if (err != MMC_ERR_NONE)
+       if (err)
                return err;
 
        memset(&mrq, 0, sizeof(struct mmc_request));
@@ -242,7 +275,7 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
 
        cmd.opcode = SD_APP_SEND_SCR;
        cmd.arg = 0;
-       cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
        data.blksz = 8;
        data.blocks = 1;
@@ -252,19 +285,19 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
 
        sg_init_one(&sg, scr, 8);
 
-       mmc_set_data_timeout(&data, card, 0);
+       mmc_set_data_timeout(&data, card);
 
        mmc_wait_for_req(card->host, &mrq);
 
-       if (cmd.error != MMC_ERR_NONE)
+       if (cmd.error)
                return cmd.error;
-       if (data.error != MMC_ERR_NONE)
+       if (data.error)
                return data.error;
 
        scr[0] = ntohl(scr[0]);
        scr[1] = ntohl(scr[1]);
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
 int mmc_sd_switch(struct mmc_card *card, int mode, int group,
@@ -278,6 +311,8 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group,
        BUG_ON(!card);
        BUG_ON(!card->host);
 
+       /* NOTE: caller guarantees resp is heap-allocated */
+
        mode = !!mode;
        value &= 0xF;
 
@@ -292,7 +327,7 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group,
        cmd.arg = mode << 31 | 0x00FFFFFF;
        cmd.arg &= ~(0xF << (group * 4));
        cmd.arg |= value << (group * 4);
-       cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+       cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
        data.blksz = 64;
        data.blocks = 1;
@@ -302,15 +337,15 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group,
 
        sg_init_one(&sg, resp, 64);
 
-       mmc_set_data_timeout(&data, card, 0);
+       mmc_set_data_timeout(&data, card);
 
        mmc_wait_for_req(card->host, &mrq);
 
-       if (cmd.error != MMC_ERR_NONE)
+       if (cmd.error)
                return cmd.error;
-       if (data.error != MMC_ERR_NONE)
+       if (data.error)
                return data.error;
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
new file mode 100644 (file)
index 0000000..87a50f4
--- /dev/null
@@ -0,0 +1,395 @@
+/*
+ *  linux/drivers/mmc/sdio.c
+ *
+ *  Copyright 2006-2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/err.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "core.h"
+#include "bus.h"
+#include "sdio_bus.h"
+#include "mmc_ops.h"
+#include "sd_ops.h"
+#include "sdio_ops.h"
+#include "sdio_cis.h"
+
+static int sdio_read_fbr(struct sdio_func *func)
+{
+       int ret;
+       unsigned char data;
+
+       ret = mmc_io_rw_direct(func->card, 0, 0,
+               SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data);
+       if (ret)
+               goto out;
+
+       data &= 0x0f;
+
+       if (data == 0x0f) {
+               ret = mmc_io_rw_direct(func->card, 0, 0,
+                       SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF_EXT, 0, &data);
+               if (ret)
+                       goto out;
+       }
+
+       func->class = data;
+
+out:
+       return ret;
+}
+
+static int sdio_init_func(struct mmc_card *card, unsigned int fn)
+{
+       int ret;
+       struct sdio_func *func;
+
+       BUG_ON(fn > SDIO_MAX_FUNCS);
+
+       func = sdio_alloc_func(card);
+       if (IS_ERR(func))
+               return PTR_ERR(func);
+
+       func->num = fn;
+
+       ret = sdio_read_fbr(func);
+       if (ret)
+               goto fail;
+
+       ret = sdio_read_func_cis(func);
+       if (ret)
+               goto fail;
+
+       card->sdio_func[fn - 1] = func;
+
+       return 0;
+
+fail:
+       /*
+        * It is okay to remove the function here even though we hold
+        * the host lock as we haven't registered the device yet.
+        */
+       sdio_remove_func(func);
+       return ret;
+}
+
+static int sdio_read_cccr(struct mmc_card *card)
+{
+       int ret;
+       int cccr_vsn;
+       unsigned char data;
+
+       memset(&card->cccr, 0, sizeof(struct sdio_cccr));
+
+       ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CCCR, 0, &data);
+       if (ret)
+               goto out;
+
+       cccr_vsn = data & 0x0f;
+
+       if (cccr_vsn > SDIO_CCCR_REV_1_20) {
+               printk(KERN_ERR "%s: unrecognised CCCR structure version %d\n",
+                       mmc_hostname(card->host), cccr_vsn);
+               return -EINVAL;
+       }
+
+       card->cccr.sdio_vsn = (data & 0xf0) >> 4;
+
+       ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CAPS, 0, &data);
+       if (ret)
+               goto out;
+
+       if (data & SDIO_CCCR_CAP_SMB)
+               card->cccr.multi_block = 1;
+       if (data & SDIO_CCCR_CAP_LSC)
+               card->cccr.low_speed = 1;
+       if (data & SDIO_CCCR_CAP_4BLS)
+               card->cccr.wide_bus = 1;
+
+       if (cccr_vsn >= SDIO_CCCR_REV_1_10) {
+               ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_POWER, 0, &data);
+               if (ret)
+                       goto out;
+
+               if (data & SDIO_POWER_SMPC)
+                       card->cccr.high_power = 1;
+       }
+
+       if (cccr_vsn >= SDIO_CCCR_REV_1_20) {
+               ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data);
+               if (ret)
+                       goto out;
+
+               if (data & SDIO_SPEED_SHS)
+                       card->cccr.high_speed = 1;
+       }
+
+out:
+       return ret;
+}
+
+static int sdio_enable_wide(struct mmc_card *card)
+{
+       int ret;
+       u8 ctrl;
+
+       if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
+               return 0;
+
+       if (card->cccr.low_speed && !card->cccr.wide_bus)
+               return 0;
+
+       ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl);
+       if (ret)
+               return ret;
+
+       ctrl |= SDIO_BUS_WIDTH_4BIT;
+
+       ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL);
+       if (ret)
+               return ret;
+
+       mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
+
+       return 0;
+}
+
+/*
+ * Host is being removed. Free up the current card.
+ */
+static void mmc_sdio_remove(struct mmc_host *host)
+{
+       int i;
+
+       BUG_ON(!host);
+       BUG_ON(!host->card);
+
+       for (i = 0;i < host->card->sdio_funcs;i++) {
+               if (host->card->sdio_func[i]) {
+                       sdio_remove_func(host->card->sdio_func[i]);
+                       host->card->sdio_func[i] = NULL;
+               }
+       }
+
+       mmc_remove_card(host->card);
+       host->card = NULL;
+}
+
+/*
+ * Card detection callback from host.
+ */
+static void mmc_sdio_detect(struct mmc_host *host)
+{
+       int err;
+
+       BUG_ON(!host);
+       BUG_ON(!host->card);
+
+       mmc_claim_host(host);
+
+       /*
+        * Just check if our card has been removed.
+        */
+       err = mmc_select_card(host->card);
+
+       mmc_release_host(host);
+
+       if (err) {
+               mmc_sdio_remove(host);
+
+               mmc_claim_host(host);
+               mmc_detach_bus(host);
+               mmc_release_host(host);
+       }
+}
+
+
+static const struct mmc_bus_ops mmc_sdio_ops = {
+       .remove = mmc_sdio_remove,
+       .detect = mmc_sdio_detect,
+};
+
+
+/*
+ * Starting point for SDIO card init.
+ */
+int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
+{
+       int err;
+       int i, funcs;
+       struct mmc_card *card;
+
+       BUG_ON(!host);
+       WARN_ON(!host->claimed);
+
+       mmc_attach_bus(host, &mmc_sdio_ops);
+
+       /*
+        * Sanity check the voltages that the card claims to
+        * support.
+        */
+       if (ocr & 0x7F) {
+               printk(KERN_WARNING "%s: card claims to support voltages "
+                      "below the defined range. These will be ignored.\n",
+                      mmc_hostname(host));
+               ocr &= ~0x7F;
+       }
+
+       if (ocr & MMC_VDD_165_195) {
+               printk(KERN_WARNING "%s: SDIO card claims to support the "
+                      "incompletely defined 'low voltage range'. This "
+                      "will be ignored.\n", mmc_hostname(host));
+               ocr &= ~MMC_VDD_165_195;
+       }
+
+       host->ocr = mmc_select_voltage(host, ocr);
+
+       /*
+        * Can we support the voltage(s) of the card(s)?
+        */
+       if (!host->ocr) {
+               err = -EINVAL;
+               goto err;
+       }
+
+       /*
+        * Inform the card of the voltage
+        */
+       err = mmc_send_io_op_cond(host, host->ocr, &ocr);
+       if (err)
+               goto err;
+
+       /*
+        * For SPI, enable CRC as appropriate.
+        */
+       if (mmc_host_is_spi(host)) {
+               err = mmc_spi_set_crc(host, use_spi_crc);
+               if (err)
+                       goto err;
+       }
+
+       /*
+        * The number of functions on the card is encoded inside
+        * the ocr.
+        */
+       funcs = (ocr & 0x70000000) >> 28;
+
+       /*
+        * Allocate card structure.
+        */
+       card = mmc_alloc_card(host);
+       if (IS_ERR(card)) {
+               err = PTR_ERR(card);
+               goto err;
+       }
+
+       card->type = MMC_TYPE_SDIO;
+       card->sdio_funcs = funcs;
+
+       host->card = card;
+
+       /*
+        * For native busses:  set card RCA and quit open drain mode.
+        */
+       if (!mmc_host_is_spi(host)) {
+               err = mmc_send_relative_addr(host, &card->rca);
+               if (err)
+                       goto remove;
+
+               mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
+       }
+
+       /*
+        * Select card, as all following commands rely on that.
+        */
+       if (!mmc_host_is_spi(host)) {
+               err = mmc_select_card(card);
+               if (err)
+                       goto remove;
+       }
+
+       /*
+        * Read the common registers.
+        */
+       err = sdio_read_cccr(card);
+       if (err)
+               goto remove;
+
+       /*
+        * Read the common CIS tuples.
+        */
+       err = sdio_read_common_cis(card);
+       if (err)
+               goto remove;
+
+       /*
+        * No support for high-speed yet, so just set
+        * the card's maximum speed.
+        */
+       mmc_set_clock(host, card->cis.max_dtr);
+
+       /*
+        * Switch to wider bus (if supported).
+        */
+       err = sdio_enable_wide(card);
+       if (err)
+               goto remove;
+
+       /*
+        * Initialize (but don't add) all present functions.
+        */
+       for (i = 0;i < funcs;i++) {
+               err = sdio_init_func(host->card, i + 1);
+               if (err)
+                       goto remove;
+       }
+
+       mmc_release_host(host);
+
+       /*
+        * First add the card to the driver model...
+        */
+       err = mmc_add_card(host->card);
+       if (err)
+               goto remove_added;
+
+       /*
+        * ...then the SDIO functions.
+        */
+       for (i = 0;i < funcs;i++) {
+               err = sdio_add_func(host->card->sdio_func[i]);
+               if (err)
+                       goto remove_added;
+       }
+
+       return 0;
+
+
+remove_added:
+       /* Remove without lock if the device has been added. */
+       mmc_sdio_remove(host);
+       mmc_claim_host(host);
+remove:
+       /* And with lock if it hasn't been added. */
+       if (host->card)
+               mmc_sdio_remove(host);
+err:
+       mmc_detach_bus(host);
+       mmc_release_host(host);
+
+       printk(KERN_ERR "%s: error %d whilst initialising SDIO card\n",
+               mmc_hostname(host), err);
+
+       return err;
+}
+
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
new file mode 100644 (file)
index 0000000..0713a8c
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ *  linux/drivers/mmc/core/sdio_bus.c
+ *
+ *  Copyright 2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * SDIO function driver model
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "sdio_cis.h"
+#include "sdio_bus.h"
+
+#define dev_to_sdio_func(d)    container_of(d, struct sdio_func, dev)
+#define to_sdio_driver(d)      container_of(d, struct sdio_driver, drv)
+
+/* show configuration fields */
+#define sdio_config_attr(field, format_string)                         \
+static ssize_t                                                         \
+field##_show(struct device *dev, struct device_attribute *attr, char *buf)                             \
+{                                                                      \
+       struct sdio_func *func;                                         \
+                                                                       \
+       func = dev_to_sdio_func (dev);                                  \
+       return sprintf (buf, format_string, func->field);               \
+}
+
+sdio_config_attr(class, "0x%02x\n");
+sdio_config_attr(vendor, "0x%04x\n");
+sdio_config_attr(device, "0x%04x\n");
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct sdio_func *func = dev_to_sdio_func (dev);
+
+       return sprintf(buf, "sdio:c%02Xv%04Xd%04X\n",
+                       func->class, func->vendor, func->device);
+}
+
+static struct device_attribute sdio_dev_attrs[] = {
+       __ATTR_RO(class),
+       __ATTR_RO(vendor),
+       __ATTR_RO(device),
+       __ATTR_RO(modalias),
+       __ATTR_NULL,
+};
+
+static const struct sdio_device_id *sdio_match_one(struct sdio_func *func,
+       const struct sdio_device_id *id)
+{
+       if (id->class != (__u8)SDIO_ANY_ID && id->class != func->class)
+               return NULL;
+       if (id->vendor != (__u16)SDIO_ANY_ID && id->vendor != func->vendor)
+               return NULL;
+       if (id->device != (__u16)SDIO_ANY_ID && id->device != func->device)
+               return NULL;
+       return id;
+}
+
+static const struct sdio_device_id *sdio_match_device(struct sdio_func *func,
+       struct sdio_driver *sdrv)
+{
+       const struct sdio_device_id *ids;
+
+       ids = sdrv->id_table;
+
+       if (ids) {
+               while (ids->class || ids->vendor || ids->device) {
+                       if (sdio_match_one(func, ids))
+                               return ids;
+                       ids++;
+               }
+       }
+
+       return NULL;
+}
+
+static int sdio_bus_match(struct device *dev, struct device_driver *drv)
+{
+       struct sdio_func *func = dev_to_sdio_func(dev);
+       struct sdio_driver *sdrv = to_sdio_driver(drv);
+
+       if (sdio_match_device(func, sdrv))
+               return 1;
+
+       return 0;
+}
+
+static int
+sdio_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
+               int buf_size)
+{
+       struct sdio_func *func = dev_to_sdio_func(dev);
+       int i = 0, length = 0;
+
+       if (add_uevent_var(envp, num_envp, &i,
+                       buf, buf_size, &length,
+                       "SDIO_CLASS=%02X", func->class))
+               return -ENOMEM;
+
+       if (add_uevent_var(envp, num_envp, &i,
+                       buf, buf_size, &length,
+                       "SDIO_ID=%04X:%04X", func->vendor, func->device))
+               return -ENOMEM;
+
+       if (add_uevent_var(envp, num_envp, &i,
+                       buf, buf_size, &length,
+                       "MODALIAS=sdio:c%02Xv%04Xd%04X",
+                       func->class, func->vendor, func->device))
+               return -ENOMEM;
+
+       envp[i] = NULL;
+
+       return 0;
+}
+
+static int sdio_bus_probe(struct device *dev)
+{
+       struct sdio_driver *drv = to_sdio_driver(dev->driver);
+       struct sdio_func *func = dev_to_sdio_func(dev);
+       const struct sdio_device_id *id;
+       int ret;
+
+       id = sdio_match_device(func, drv);
+       if (!id)
+               return -ENODEV;
+
+       /* Set the default block size so the driver is sure it's something
+        * sensible. */
+       sdio_claim_host(func);
+       ret = sdio_set_block_size(func, 0);
+       sdio_release_host(func);
+       if (ret)
+               return ret;
+
+       return drv->probe(func, id);
+}
+
+static int sdio_bus_remove(struct device *dev)
+{
+       struct sdio_driver *drv = to_sdio_driver(dev->driver);
+       struct sdio_func *func = dev_to_sdio_func(dev);
+
+       drv->remove(func);
+
+       if (func->irq_handler) {
+               printk(KERN_WARNING "WARNING: driver %s did not remove "
+                       "its interrupt handler!\n", drv->name);
+               sdio_claim_host(func);
+               sdio_release_irq(func);
+               sdio_release_host(func);
+       }
+
+       return 0;
+}
+
+static struct bus_type sdio_bus_type = {
+       .name           = "sdio",
+       .dev_attrs      = sdio_dev_attrs,
+       .match          = sdio_bus_match,
+       .uevent         = sdio_bus_uevent,
+       .probe          = sdio_bus_probe,
+       .remove         = sdio_bus_remove,
+};
+
+int sdio_register_bus(void)
+{
+       return bus_register(&sdio_bus_type);
+}
+
+void sdio_unregister_bus(void)
+{
+       bus_unregister(&sdio_bus_type);
+}
+
+/**
+ *     sdio_register_driver - register a function driver
+ *     @drv: SDIO function driver
+ */
+int sdio_register_driver(struct sdio_driver *drv)
+{
+       drv->drv.name = drv->name;
+       drv->drv.bus = &sdio_bus_type;
+       return driver_register(&drv->drv);
+}
+EXPORT_SYMBOL_GPL(sdio_register_driver);
+
+/**
+ *     sdio_unregister_driver - unregister a function driver
+ *     @drv: SDIO function driver
+ */
+void sdio_unregister_driver(struct sdio_driver *drv)
+{
+       drv->drv.bus = &sdio_bus_type;
+       driver_unregister(&drv->drv);
+}
+EXPORT_SYMBOL_GPL(sdio_unregister_driver);
+
+static void sdio_release_func(struct device *dev)
+{
+       struct sdio_func *func = dev_to_sdio_func(dev);
+
+       sdio_free_func_cis(func);
+
+       if (func->info)
+               kfree(func->info);
+
+       kfree(func);
+}
+
+/*
+ * Allocate and initialise a new SDIO function structure.
+ */
+struct sdio_func *sdio_alloc_func(struct mmc_card *card)
+{
+       struct sdio_func *func;
+
+       func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL);
+       if (!func)
+               return ERR_PTR(-ENOMEM);
+
+       func->card = card;
+
+       device_initialize(&func->dev);
+
+       func->dev.parent = &card->dev;
+       func->dev.bus = &sdio_bus_type;
+       func->dev.release = sdio_release_func;
+
+       return func;
+}
+
+/*
+ * Register a new SDIO function with the driver model.
+ */
+int sdio_add_func(struct sdio_func *func)
+{
+       int ret;
+
+       snprintf(func->dev.bus_id, sizeof(func->dev.bus_id),
+                "%s:%d", mmc_card_id(func->card), func->num);
+
+       ret = device_add(&func->dev);
+       if (ret == 0)
+               sdio_func_set_present(func);
+
+       return ret;
+}
+
+/*
+ * Unregister a SDIO function with the driver model, and
+ * (eventually) free it.
+ */
+void sdio_remove_func(struct sdio_func *func)
+{
+       if (sdio_func_present(func))
+               device_del(&func->dev);
+
+       put_device(&func->dev);
+}
+
diff --git a/drivers/mmc/core/sdio_bus.h b/drivers/mmc/core/sdio_bus.h
new file mode 100644 (file)
index 0000000..567a768
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *  linux/drivers/mmc/core/sdio_bus.h
+ *
+ *  Copyright 2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+#ifndef _MMC_CORE_SDIO_BUS_H
+#define _MMC_CORE_SDIO_BUS_H
+
+struct sdio_func *sdio_alloc_func(struct mmc_card *card);
+int sdio_add_func(struct sdio_func *func);
+void sdio_remove_func(struct sdio_func *func);
+
+int sdio_register_bus(void);
+void sdio_unregister_bus(void);
+
+#endif
+
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
new file mode 100644 (file)
index 0000000..d5e51b1
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * linux/drivers/mmc/core/sdio_cis.c
+ *
+ * Author:     Nicolas Pitre
+ * Created:    June 11, 2007
+ * Copyright:  MontaVista Software Inc.
+ *
+ * Copyright 2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/kernel.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "sdio_cis.h"
+#include "sdio_ops.h"
+
+static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func,
+                        const unsigned char *buf, unsigned size)
+{
+       unsigned i, nr_strings;
+       char **buffer, *string;
+
+       buf += 2;
+       size -= 2;
+
+       nr_strings = 0;
+       for (i = 0; i < size; i++) {
+               if (buf[i] == 0xff)
+                       break;
+               if (buf[i] == 0)
+                       nr_strings++;
+       }
+
+       if (buf[i-1] != '\0') {
+               printk(KERN_WARNING "SDIO: ignoring broken CISTPL_VERS_1\n");
+               return 0;
+       }
+
+       size = i;
+
+       buffer = kzalloc(sizeof(char*) * nr_strings + size, GFP_KERNEL);
+       if (!buffer)
+               return -ENOMEM;
+
+       string = (char*)(buffer + nr_strings);
+
+       for (i = 0; i < nr_strings; i++) {
+               buffer[i] = string;
+               strcpy(string, buf);
+               string += strlen(string) + 1;
+               buf += strlen(buf) + 1;
+       }
+
+       if (func) {
+               func->num_info = nr_strings;
+               func->info = (const char**)buffer;
+       } else {
+               card->num_info = nr_strings;
+               card->info = (const char**)buffer;
+       }
+
+       return 0;
+}
+
+static int cistpl_manfid(struct mmc_card *card, struct sdio_func *func,
+                        const unsigned char *buf, unsigned size)
+{
+       unsigned int vendor, device;
+
+       /* TPLMID_MANF */
+       vendor = buf[0] | (buf[1] << 8);
+
+       /* TPLMID_CARD */
+       device = buf[2] | (buf[3] << 8);
+
+       if (func) {
+               func->vendor = vendor;
+               func->device = device;
+       } else {
+               card->cis.vendor = vendor;
+               card->cis.device = device;
+       }
+
+       return 0;
+}
+
+static const unsigned char speed_val[16] =
+       { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
+static const unsigned int speed_unit[8] =
+       { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
+
+static int cistpl_funce_common(struct mmc_card *card,
+                              const unsigned char *buf, unsigned size)
+{
+       if (size < 0x04 || buf[0] != 0)
+               return -EINVAL;
+
+       /* TPLFE_FN0_BLK_SIZE */
+       card->cis.blksize = buf[1] | (buf[2] << 8);
+
+       /* TPLFE_MAX_TRAN_SPEED */
+       card->cis.max_dtr = speed_val[(buf[3] >> 3) & 15] *
+                           speed_unit[buf[3] & 7];
+
+       return 0;
+}
+
+static int cistpl_funce_func(struct sdio_func *func,
+                            const unsigned char *buf, unsigned size)
+{
+       unsigned vsn;
+       unsigned min_size;
+
+       vsn = func->card->cccr.sdio_vsn;
+       min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42;
+
+       if (size < min_size || buf[0] != 1)
+               return -EINVAL;
+
+       /* TPLFE_MAX_BLK_SIZE */
+       func->max_blksize = buf[12] | (buf[13] << 8);
+
+       return 0;
+}
+
+static int cistpl_funce(struct mmc_card *card, struct sdio_func *func,
+                       const unsigned char *buf, unsigned size)
+{
+       int ret;
+
+       /*
+        * There should be two versions of the CISTPL_FUNCE tuple,
+        * one for the common CIS (function 0) and a version used by
+        * the individual function's CIS (1-7). Yet, the later has a
+        * different length depending on the SDIO spec version.
+        */
+       if (func)
+               ret = cistpl_funce_func(func, buf, size);
+       else
+               ret = cistpl_funce_common(card, buf, size);
+
+       if (ret) {
+               printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u "
+                      "type %u\n", mmc_hostname(card->host), size, buf[0]);
+               return ret;
+       }
+
+       return 0;
+}
+
+typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *,
+                          const unsigned char *, unsigned);
+
+struct cis_tpl {
+       unsigned char code;
+       unsigned char min_size;
+       tpl_parse_t *parse;
+};
+
+static const struct cis_tpl cis_tpl_list[] = {
+       {       0x15,   3,      cistpl_vers_1           },
+       {       0x20,   4,      cistpl_manfid           },
+       {       0x21,   2,      /* cistpl_funcid */     },
+       {       0x22,   0,      cistpl_funce            },
+};
+
+static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
+{
+       int ret;
+       struct sdio_func_tuple *this, **prev;
+       unsigned i, ptr = 0;
+
+       /*
+        * Note that this works for the common CIS (function number 0) as
+        * well as a function's CIS * since SDIO_CCCR_CIS and SDIO_FBR_CIS
+        * have the same offset.
+        */
+       for (i = 0; i < 3; i++) {
+               unsigned char x, fn;
+
+               if (func)
+                       fn = func->num;
+               else
+                       fn = 0;
+
+               ret = mmc_io_rw_direct(card, 0, 0,
+                       SDIO_FBR_BASE(fn) + SDIO_FBR_CIS + i, 0, &x);
+               if (ret)
+                       return ret;
+               ptr |= x << (i * 8);
+       }
+
+       if (func)
+               prev = &func->tuples;
+       else
+               prev = &card->tuples;
+
+       BUG_ON(*prev);
+
+       do {
+               unsigned char tpl_code, tpl_link;
+
+               ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_code);
+               if (ret)
+                       break;
+
+               /* 0xff means we're done */
+               if (tpl_code == 0xff)
+                       break;
+
+               ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_link);
+               if (ret)
+                       break;
+
+               this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL);
+               if (!this)
+                       return -ENOMEM;
+
+               for (i = 0; i < tpl_link; i++) {
+                       ret = mmc_io_rw_direct(card, 0, 0,
+                                              ptr + i, 0, &this->data[i]);
+                       if (ret)
+                               break;
+               }
+               if (ret) {
+                       kfree(this);
+                       break;
+               }
+
+               for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++)
+                       if (cis_tpl_list[i].code == tpl_code)
+                               break;
+               if (i >= ARRAY_SIZE(cis_tpl_list)) {
+                       /* this tuple is unknown to the core */
+                       this->next = NULL;
+                       this->code = tpl_code;
+                       this->size = tpl_link;
+                       *prev = this;
+                       prev = &this->next;
+                       printk(KERN_DEBUG
+                              "%s: queuing CIS tuple 0x%02x length %u\n",
+                              mmc_hostname(card->host), tpl_code, tpl_link);
+               } else {
+                       const struct cis_tpl *tpl = cis_tpl_list + i;
+                       if (tpl_link < tpl->min_size) {
+                               printk(KERN_ERR
+                                      "%s: bad CIS tuple 0x%02x (length = %u, expected >= %u)\n",
+                                      mmc_hostname(card->host),
+                                      tpl_code, tpl_link, tpl->min_size);
+                               ret = -EINVAL;
+                       } else if (tpl->parse) {
+                               ret = tpl->parse(card, func,
+                                                this->data, tpl_link);
+                       }
+                       kfree(this);
+               }
+
+               ptr += tpl_link;
+       } while (!ret);
+
+       /*
+        * Link in all unknown tuples found in the common CIS so that
+        * drivers don't have to go digging in two places.
+        */
+       if (func)
+               *prev = card->tuples;
+
+       return ret;
+}
+
+int sdio_read_common_cis(struct mmc_card *card)
+{
+       return sdio_read_cis(card, NULL);
+}
+
+void sdio_free_common_cis(struct mmc_card *card)
+{
+       struct sdio_func_tuple *tuple, *victim;
+
+       tuple = card->tuples;
+
+       while (tuple) {
+               victim = tuple;
+               tuple = tuple->next;
+               kfree(victim);
+       }
+
+       card->tuples = NULL;
+}
+
+int sdio_read_func_cis(struct sdio_func *func)
+{
+       int ret;
+
+       ret = sdio_read_cis(func->card, func);
+       if (ret)
+               return ret;
+
+       /*
+        * Since we've linked to tuples in the card structure,
+        * we must make sure we have a reference to it.
+        */
+       get_device(&func->card->dev);
+
+       /*
+        * Vendor/device id is optional for function CIS, so
+        * copy it from the card structure as needed.
+        */
+       if (func->vendor == 0) {
+               func->vendor = func->card->cis.vendor;
+               func->device = func->card->cis.device;
+       }
+
+       return 0;
+}
+
+void sdio_free_func_cis(struct sdio_func *func)
+{
+       struct sdio_func_tuple *tuple, *victim;
+
+       tuple = func->tuples;
+
+       while (tuple && tuple != func->card->tuples) {
+               victim = tuple;
+               tuple = tuple->next;
+               kfree(victim);
+       }
+
+       func->tuples = NULL;
+
+       /*
+        * We have now removed the link to the tuples in the
+        * card structure, so remove the reference.
+        */
+       put_device(&func->card->dev);
+}
+
diff --git a/drivers/mmc/core/sdio_cis.h b/drivers/mmc/core/sdio_cis.h
new file mode 100644 (file)
index 0000000..4d903c2
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * linux/drivers/mmc/core/sdio_cis.h
+ *
+ * Author:     Nicolas Pitre
+ * Created:    June 11, 2007
+ * Copyright:  MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef _MMC_SDIO_CIS_H
+#define _MMC_SDIO_CIS_H
+
+int sdio_read_common_cis(struct mmc_card *card);
+void sdio_free_common_cis(struct mmc_card *card);
+
+int sdio_read_func_cis(struct sdio_func *func);
+void sdio_free_func_cis(struct sdio_func *func);
+
+#endif
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
new file mode 100644 (file)
index 0000000..625b92c
--- /dev/null
@@ -0,0 +1,548 @@
+/*
+ *  linux/drivers/mmc/core/sdio_io.c
+ *
+ *  Copyright 2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "sdio_ops.h"
+
+/**
+ *     sdio_claim_host - exclusively claim a bus for a certain SDIO function
+ *     @func: SDIO function that will be accessed
+ *
+ *     Claim a bus for a set of operations. The SDIO function given
+ *     is used to figure out which bus is relevant.
+ */
+void sdio_claim_host(struct sdio_func *func)
+{
+       BUG_ON(!func);
+       BUG_ON(!func->card);
+
+       mmc_claim_host(func->card->host);
+}
+EXPORT_SYMBOL_GPL(sdio_claim_host);
+
+/**
+ *     sdio_release_host - release a bus for a certain SDIO function
+ *     @func: SDIO function that was accessed
+ *
+ *     Release a bus, allowing others to claim the bus for their
+ *     operations.
+ */
+void sdio_release_host(struct sdio_func *func)
+{
+       BUG_ON(!func);
+       BUG_ON(!func->card);
+
+       mmc_release_host(func->card->host);
+}
+EXPORT_SYMBOL_GPL(sdio_release_host);
+
+/**
+ *     sdio_enable_func - enables a SDIO function for usage
+ *     @func: SDIO function to enable
+ *
+ *     Powers up and activates a SDIO function so that register
+ *     access is possible.
+ */
+int sdio_enable_func(struct sdio_func *func)
+{
+       int ret;
+       unsigned char reg;
+       unsigned long timeout;
+
+       BUG_ON(!func);
+       BUG_ON(!func->card);
+
+       pr_debug("SDIO: Enabling device %s...\n", sdio_func_id(func));
+
+       ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, &reg);
+       if (ret)
+               goto err;
+
+       reg |= 1 << func->num;
+
+       ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
+       if (ret)
+               goto err;
+
+       /*
+        * FIXME: This should timeout based on information in the CIS,
+        * but we don't have card to parse that yet.
+        */
+       timeout = jiffies + HZ;
+
+       while (1) {
+               ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IORx, 0, &reg);
+               if (ret)
+                       goto err;
+               if (reg & (1 << func->num))
+                       break;
+               ret = -ETIME;
+               if (time_after(jiffies, timeout))
+                       goto err;
+       }
+
+       pr_debug("SDIO: Enabled device %s\n", sdio_func_id(func));
+
+       return 0;
+
+err:
+       pr_debug("SDIO: Failed to enable device %s\n", sdio_func_id(func));
+       return ret;
+}
+EXPORT_SYMBOL_GPL(sdio_enable_func);
+
+/**
+ *     sdio_disable_func - disable a SDIO function
+ *     @func: SDIO function to disable
+ *
+ *     Powers down and deactivates a SDIO function. Register access
+ *     to this function will fail until the function is reenabled.
+ */
+int sdio_disable_func(struct sdio_func *func)
+{
+       int ret;
+       unsigned char reg;
+
+       BUG_ON(!func);
+       BUG_ON(!func->card);
+
+       pr_debug("SDIO: Disabling device %s...\n", sdio_func_id(func));
+
+       ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IOEx, 0, &reg);
+       if (ret)
+               goto err;
+
+       reg &= ~(1 << func->num);
+
+       ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IOEx, reg, NULL);
+       if (ret)
+               goto err;
+
+       pr_debug("SDIO: Disabled device %s\n", sdio_func_id(func));
+
+       return 0;
+
+err:
+       pr_debug("SDIO: Failed to disable device %s\n", sdio_func_id(func));
+       return -EIO;
+}
+EXPORT_SYMBOL_GPL(sdio_disable_func);
+
+/**
+ *     sdio_set_block_size - set the block size of an SDIO function
+ *     @func: SDIO function to change
+ *     @blksz: new block size or 0 to use the default.
+ *
+ *     The default block size is the largest supported by both the function
+ *     and the host, with a maximum of 512 to ensure that arbitrarily sized
+ *     data transfer use the optimal (least) number of commands.
+ *
+ *     A driver may call this to override the default block size set by the
+ *     core. This can be used to set a block size greater than the maximum
+ *     that reported by the card; it is the driver's responsibility to ensure
+ *     it uses a value that the card supports.
+ *
+ *     Returns 0 on success, -EINVAL if the host does not support the
+ *     requested block size, or -EIO (etc.) if one of the resultant FBR block
+ *     size register writes failed.
+ *
+ */
+int sdio_set_block_size(struct sdio_func *func, unsigned blksz)
+{
+       int ret;
+
+       if (blksz > func->card->host->max_blk_size)
+               return -EINVAL;
+
+       if (blksz == 0) {
+               blksz = min(min(
+                       func->max_blksize,
+                       func->card->host->max_blk_size),
+                       512u);
+       }
+
+       ret = mmc_io_rw_direct(func->card, 1, 0,
+               SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE,
+               blksz & 0xff, NULL);
+       if (ret)
+               return ret;
+       ret = mmc_io_rw_direct(func->card, 1, 0,
+               SDIO_FBR_BASE(func->num) + SDIO_FBR_BLKSIZE + 1,
+               (blksz >> 8) & 0xff, NULL);
+       if (ret)
+               return ret;
+       func->cur_blksize = blksz;
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(sdio_set_block_size);
+
+/* Split an arbitrarily sized data transfer into several
+ * IO_RW_EXTENDED commands. */
+static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
+       unsigned addr, int incr_addr, u8 *buf, unsigned size)
+{
+       unsigned remainder = size;
+       unsigned max_blocks;
+       int ret;
+
+       /* Do the bulk of the transfer using block mode (if supported). */
+       if (func->card->cccr.multi_block) {
+               /* Blocks per command is limited by host count, host transfer
+                * size (we only use a single sg entry) and the maximum for
+                * IO_RW_EXTENDED of 511 blocks. */
+               max_blocks = min(min(
+                       func->card->host->max_blk_count,
+                       func->card->host->max_seg_size / func->cur_blksize),
+                       511u);
+
+               while (remainder > func->cur_blksize) {
+                       unsigned blocks;
+
+                       blocks = remainder / func->cur_blksize;
+                       if (blocks > max_blocks)
+                               blocks = max_blocks;
+                       size = blocks * func->cur_blksize;
+
+                       ret = mmc_io_rw_extended(func->card, write,
+                               func->num, addr, incr_addr, buf,
+                               blocks, func->cur_blksize);
+                       if (ret)
+                               return ret;
+
+                       remainder -= size;
+                       buf += size;
+                       if (incr_addr)
+                               addr += size;
+               }
+       }
+
+       /* Write the remainder using byte mode. */
+       while (remainder > 0) {
+               size = remainder;
+               if (size > func->cur_blksize)
+                       size = func->cur_blksize;
+               if (size > 512)
+                       size = 512; /* maximum size for byte mode */
+
+               ret = mmc_io_rw_extended(func->card, write, func->num, addr,
+                        incr_addr, buf, 1, size);
+               if (ret)
+                       return ret;
+
+               remainder -= size;
+               buf += size;
+               if (incr_addr)
+                       addr += size;
+       }
+       return 0;
+}
+
+/**
+ *     sdio_readb - read a single byte from a SDIO function
+ *     @func: SDIO function to access
+ *     @addr: address to read
+ *     @err_ret: optional status value from transfer
+ *
+ *     Reads a single byte from the address space of a given SDIO
+ *     function. If there is a problem reading the address, 0xff
+ *     is returned and @err_ret will contain the error code.
+ */
+unsigned char sdio_readb(struct sdio_func *func, unsigned int addr,
+       int *err_ret)
+{
+       int ret;
+       unsigned char val;
+
+       BUG_ON(!func);
+
+       if (err_ret)
+               *err_ret = 0;
+
+       ret = mmc_io_rw_direct(func->card, 0, func->num, addr, 0, &val);
+       if (ret) {
+               if (err_ret)
+                       *err_ret = ret;
+               return 0xFF;
+       }
+
+       return val;
+}
+EXPORT_SYMBOL_GPL(sdio_readb);
+
+/**
+ *     sdio_writeb - write a single byte to a SDIO function
+ *     @func: SDIO function to access
+ *     @b: byte to write
+ *     @addr: address to write to
+ *     @err_ret: optional status value from transfer
+ *
+ *     Writes a single byte to the address space of a given SDIO
+ *     function. @err_ret will contain the status of the actual
+ *     transfer.
+ */
+void sdio_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
+       int *err_ret)
+{
+       int ret;
+
+       BUG_ON(!func);
+
+       ret = mmc_io_rw_direct(func->card, 1, func->num, addr, b, NULL);
+       if (err_ret)
+               *err_ret = ret;
+}
+EXPORT_SYMBOL_GPL(sdio_writeb);
+
+/**
+ *     sdio_memcpy_fromio - read a chunk of memory from a SDIO function
+ *     @func: SDIO function to access
+ *     @dst: buffer to store the data
+ *     @addr: address to begin reading from
+ *     @count: number of bytes to read
+ *
+ *     Reads from the address space of a given SDIO function. Return
+ *     value indicates if the transfer succeeded or not.
+ */
+int sdio_memcpy_fromio(struct sdio_func *func, void *dst,
+       unsigned int addr, int count)
+{
+       return sdio_io_rw_ext_helper(func, 0, addr, 1, dst, count);
+}
+EXPORT_SYMBOL_GPL(sdio_memcpy_fromio);
+
+/**
+ *     sdio_memcpy_toio - write a chunk of memory to a SDIO function
+ *     @func: SDIO function to access
+ *     @addr: address to start writing to
+ *     @src: buffer that contains the data to write
+ *     @count: number of bytes to write
+ *
+ *     Writes to the address space of a given SDIO function. Return
+ *     value indicates if the transfer succeeded or not.
+ */
+int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,
+       void *src, int count)
+{
+       return sdio_io_rw_ext_helper(func, 1, addr, 1, src, count);
+}
+EXPORT_SYMBOL_GPL(sdio_memcpy_toio);
+
+/**
+ *     sdio_readsb - read from a FIFO on a SDIO function
+ *     @func: SDIO function to access
+ *     @dst: buffer to store the data
+ *     @addr: address of (single byte) FIFO
+ *     @count: number of bytes to read
+ *
+ *     Reads from the specified FIFO of a given SDIO function. Return
+ *     value indicates if the transfer succeeded or not.
+ */
+int sdio_readsb(struct sdio_func *func, void *dst, unsigned int addr,
+       int count)
+{
+       return sdio_io_rw_ext_helper(func, 0, addr, 0, dst, count);
+}
+
+EXPORT_SYMBOL_GPL(sdio_readsb);
+
+/**
+ *     sdio_writesb - write to a FIFO of a SDIO function
+ *     @func: SDIO function to access
+ *     @addr: address of (single byte) FIFO
+ *     @src: buffer that contains the data to write
+ *     @count: number of bytes to write
+ *
+ *     Writes to the specified FIFO of a given SDIO function. Return
+ *     value indicates if the transfer succeeded or not.
+ */
+int sdio_writesb(struct sdio_func *func, unsigned int addr, void *src,
+       int count)
+{
+       return sdio_io_rw_ext_helper(func, 1, addr, 0, src, count);
+}
+EXPORT_SYMBOL_GPL(sdio_writesb);
+
+/**
+ *     sdio_readw - read a 16 bit integer from a SDIO function
+ *     @func: SDIO function to access
+ *     @addr: address to read
+ *     @err_ret: optional status value from transfer
+ *
+ *     Reads a 16 bit integer from the address space of a given SDIO
+ *     function. If there is a problem reading the address, 0xffff
+ *     is returned and @err_ret will contain the error code.
+ */
+unsigned short sdio_readw(struct sdio_func *func, unsigned int addr,
+       int *err_ret)
+{
+       int ret;
+
+       if (err_ret)
+               *err_ret = 0;
+
+       ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 2);
+       if (ret) {
+               if (err_ret)
+                       *err_ret = ret;
+               return 0xFFFF;
+       }
+
+       return le16_to_cpu(*(u16*)func->tmpbuf);
+}
+EXPORT_SYMBOL_GPL(sdio_readw);
+
+/**
+ *     sdio_writew - write a 16 bit integer to a SDIO function
+ *     @func: SDIO function to access
+ *     @b: integer to write
+ *     @addr: address to write to
+ *     @err_ret: optional status value from transfer
+ *
+ *     Writes a 16 bit integer to the address space of a given SDIO
+ *     function. @err_ret will contain the status of the actual
+ *     transfer.
+ */
+void sdio_writew(struct sdio_func *func, unsigned short b, unsigned int addr,
+       int *err_ret)
+{
+       int ret;
+
+       *(u16*)func->tmpbuf = cpu_to_le16(b);
+
+       ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 2);
+       if (err_ret)
+               *err_ret = ret;
+}
+EXPORT_SYMBOL_GPL(sdio_writew);
+
+/**
+ *     sdio_readl - read a 32 bit integer from a SDIO function
+ *     @func: SDIO function to access
+ *     @addr: address to read
+ *     @err_ret: optional status value from transfer
+ *
+ *     Reads a 32 bit integer from the address space of a given SDIO
+ *     function. If there is a problem reading the address,
+ *     0xffffffff is returned and @err_ret will contain the error
+ *     code.
+ */
+unsigned long sdio_readl(struct sdio_func *func, unsigned int addr,
+       int *err_ret)
+{
+       int ret;
+
+       if (err_ret)
+               *err_ret = 0;
+
+       ret = sdio_memcpy_fromio(func, func->tmpbuf, addr, 4);
+       if (ret) {
+               if (err_ret)
+                       *err_ret = ret;
+               return 0xFFFFFFFF;
+       }
+
+       return le32_to_cpu(*(u32*)func->tmpbuf);
+}
+EXPORT_SYMBOL_GPL(sdio_readl);
+
+/**
+ *     sdio_writel - write a 32 bit integer to a SDIO function
+ *     @func: SDIO function to access
+ *     @b: integer to write
+ *     @addr: address to write to
+ *     @err_ret: optional status value from transfer
+ *
+ *     Writes a 32 bit integer to the address space of a given SDIO
+ *     function. @err_ret will contain the status of the actual
+ *     transfer.
+ */
+void sdio_writel(struct sdio_func *func, unsigned long b, unsigned int addr,
+       int *err_ret)
+{
+       int ret;
+
+       *(u32*)func->tmpbuf = cpu_to_le32(b);
+
+       ret = sdio_memcpy_toio(func, addr, func->tmpbuf, 4);
+       if (err_ret)
+               *err_ret = ret;
+}
+EXPORT_SYMBOL_GPL(sdio_writel);
+
+/**
+ *     sdio_f0_readb - read a single byte from SDIO function 0
+ *     @func: an SDIO function of the card
+ *     @addr: address to read
+ *     @err_ret: optional status value from transfer
+ *
+ *     Reads a single byte from the address space of SDIO function 0.
+ *     If there is a problem reading the address, 0xff is returned
+ *     and @err_ret will contain the error code.
+ */
+unsigned char sdio_f0_readb(struct sdio_func *func, unsigned int addr,
+       int *err_ret)
+{
+       int ret;
+       unsigned char val;
+
+       BUG_ON(!func);
+
+       if (err_ret)
+               *err_ret = 0;
+
+       ret = mmc_io_rw_direct(func->card, 0, 0, addr, 0, &val);
+       if (ret) {
+               if (err_ret)
+                       *err_ret = ret;
+               return 0xFF;
+       }
+
+       return val;
+}
+EXPORT_SYMBOL_GPL(sdio_f0_readb);
+
+/**
+ *     sdio_f0_writeb - write a single byte to SDIO function 0
+ *     @func: an SDIO function of the card
+ *     @b: byte to write
+ *     @addr: address to write to
+ *     @err_ret: optional status value from transfer
+ *
+ *     Writes a single byte to the address space of SDIO function 0.
+ *     @err_ret will contain the status of the actual transfer.
+ *
+ *     Only writes to the vendor specific CCCR registers (0xF0 -
+ *     0xFF) are permiited; @err_ret will be set to -EINVAL for *
+ *     writes outside this range.
+ */
+void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr,
+       int *err_ret)
+{
+       int ret;
+
+       BUG_ON(!func);
+
+       if (addr < 0xF0 || addr > 0xFF) {
+               if (err_ret)
+                       *err_ret = -EINVAL;
+               return;
+       }
+
+       ret = mmc_io_rw_direct(func->card, 1, 0, addr, b, NULL);
+       if (err_ret)
+               *err_ret = ret;
+}
+EXPORT_SYMBOL_GPL(sdio_f0_writeb);
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
new file mode 100644 (file)
index 0000000..3bd3021
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * linux/drivers/mmc/core/sdio_irq.c
+ *
+ * Author:      Nicolas Pitre
+ * Created:     June 18, 2007
+ * Copyright:   MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+
+#include <linux/mmc/core.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "sdio_ops.h"
+
+static int process_sdio_pending_irqs(struct mmc_card *card)
+{
+       int i, ret, count;
+       unsigned char pending;
+
+       ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
+       if (ret) {
+               printk(KERN_DEBUG "%s: error %d reading SDIO_CCCR_INTx\n",
+                      mmc_card_id(card), ret);
+               return ret;
+       }
+
+       count = 0;
+       for (i = 1; i <= 7; i++) {
+               if (pending & (1 << i)) {
+                       struct sdio_func *func = card->sdio_func[i - 1];
+                       if (!func) {
+                               printk(KERN_WARNING "%s: pending IRQ for "
+                                       "non-existant function\n",
+                                       mmc_card_id(card));
+                               ret = -EINVAL;
+                       } else if (func->irq_handler) {
+                               func->irq_handler(func);
+                               count++;
+                       } else {
+                               printk(KERN_WARNING "%s: pending IRQ with no handler\n",
+                                      sdio_func_id(func));
+                               ret = -EINVAL;
+                       }
+               }
+       }
+
+       if (count)
+               return count;
+
+       return ret;
+}
+
+static int sdio_irq_thread(void *_host)
+{
+       struct mmc_host *host = _host;
+       struct sched_param param = { .sched_priority = 1 };
+       unsigned long period, idle_period;
+       int ret;
+
+       sched_setscheduler(current, SCHED_FIFO, &param);
+
+       /*
+        * We want to allow for SDIO cards to work even on non SDIO
+        * aware hosts.  One thing that non SDIO host cannot do is
+        * asynchronous notification of pending SDIO card interrupts
+        * hence we poll for them in that case.
+        */
+       idle_period = msecs_to_jiffies(10);
+       period = (host->caps & MMC_CAP_SDIO_IRQ) ?
+               MAX_SCHEDULE_TIMEOUT : idle_period;
+
+       pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n",
+                mmc_hostname(host), period);
+
+       do {
+               /*
+                * We claim the host here on drivers behalf for a couple
+                * reasons:
+                *
+                * 1) it is already needed to retrieve the CCCR_INTx;
+                * 2) we want the driver(s) to clear the IRQ condition ASAP;
+                * 3) we need to control the abort condition locally.
+                *
+                * Just like traditional hard IRQ handlers, we expect SDIO
+                * IRQ handlers to be quick and to the point, so that the
+                * holding of the host lock does not cover too much work
+                * that doesn't require that lock to be held.
+                */
+               ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);
+               if (ret)
+                       break;
+               ret = process_sdio_pending_irqs(host->card);
+               mmc_release_host(host);
+
+               /*
+                * Give other threads a chance to run in the presence of
+                * errors.  FIXME: determine if due to card removal and
+                * possibly exit this thread if so.
+                */
+               if (ret < 0)
+                       ssleep(1);
+
+               /*
+                * Adaptive polling frequency based on the assumption
+                * that an interrupt will be closely followed by more.
+                * This has a substantial benefit for network devices.
+                */
+               if (!(host->caps & MMC_CAP_SDIO_IRQ)) {
+                       if (ret > 0)
+                               period /= 2;
+                       else {
+                               period++;
+                               if (period > idle_period)
+                                       period = idle_period;
+                       }
+               }
+
+               set_task_state(current, TASK_INTERRUPTIBLE);
+               if (host->caps & MMC_CAP_SDIO_IRQ)
+                       host->ops->enable_sdio_irq(host, 1);
+               if (!kthread_should_stop())
+                       schedule_timeout(period);
+               set_task_state(current, TASK_RUNNING);
+       } while (!kthread_should_stop());
+
+       if (host->caps & MMC_CAP_SDIO_IRQ)
+               host->ops->enable_sdio_irq(host, 0);
+
+       pr_debug("%s: IRQ thread exiting with code %d\n",
+                mmc_hostname(host), ret);
+
+       return ret;
+}
+
+static int sdio_card_irq_get(struct mmc_card *card)
+{
+       struct mmc_host *host = card->host;
+
+       WARN_ON(!host->claimed);
+
+       if (!host->sdio_irqs++) {
+               atomic_set(&host->sdio_irq_thread_abort, 0);
+               host->sdio_irq_thread =
+                       kthread_run(sdio_irq_thread, host, "ksdiorqd");
+               if (IS_ERR(host->sdio_irq_thread)) {
+                       int err = PTR_ERR(host->sdio_irq_thread);
+                       host->sdio_irqs--;
+                       return err;
+               }
+       }
+
+       return 0;
+}
+
+static int sdio_card_irq_put(struct mmc_card *card)
+{
+       struct mmc_host *host = card->host;
+
+       WARN_ON(!host->claimed);
+       BUG_ON(host->sdio_irqs < 1);
+
+       if (!--host->sdio_irqs) {
+               atomic_set(&host->sdio_irq_thread_abort, 1);
+               kthread_stop(host->sdio_irq_thread);
+       }
+
+       return 0;
+}
+
+/**
+ *     sdio_claim_irq - claim the IRQ for a SDIO function
+ *     @func: SDIO function
+ *     @handler: IRQ handler callback
+ *
+ *     Claim and activate the IRQ for the given SDIO function. The provided
+ *     handler will be called when that IRQ is asserted.  The host is always
+ *     claimed already when the handler is called so the handler must not
+ *     call sdio_claim_host() nor sdio_release_host().
+ */
+int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler)
+{
+       int ret;
+       unsigned char reg;
+
+       BUG_ON(!func);
+       BUG_ON(!func->card);
+
+       pr_debug("SDIO: Enabling IRQ for %s...\n", sdio_func_id(func));
+
+       if (func->irq_handler) {
+               pr_debug("SDIO: IRQ for %s already in use.\n", sdio_func_id(func));
+               return -EBUSY;
+       }
+
+       ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, &reg);
+       if (ret)
+               return ret;
+
+       reg |= 1 << func->num;
+
+       reg |= 1; /* Master interrupt enable */
+
+       ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL);
+       if (ret)
+               return ret;
+
+       func->irq_handler = handler;
+       ret = sdio_card_irq_get(func->card);
+       if (ret)
+               func->irq_handler = NULL;
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(sdio_claim_irq);
+
+/**
+ *     sdio_release_irq - release the IRQ for a SDIO function
+ *     @func: SDIO function
+ *
+ *     Disable and release the IRQ for the given SDIO function.
+ */
+int sdio_release_irq(struct sdio_func *func)
+{
+       int ret;
+       unsigned char reg;
+
+       BUG_ON(!func);
+       BUG_ON(!func->card);
+
+       pr_debug("SDIO: Disabling IRQ for %s...\n", sdio_func_id(func));
+
+       if (func->irq_handler) {
+               func->irq_handler = NULL;
+               sdio_card_irq_put(func->card);
+       }
+
+       ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, &reg);
+       if (ret)
+               return ret;
+
+       reg &= ~(1 << func->num);
+
+       /* Disable master interrupt with the last function interrupt */
+       if (!(reg & 0xFE))
+               reg = 0;
+
+       ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(sdio_release_irq);
+
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
new file mode 100644 (file)
index 0000000..4d289b2
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ *  linux/drivers/mmc/sdio_ops.c
+ *
+ *  Copyright 2006-2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sdio.h>
+
+#include "core.h"
+
+int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
+{
+       struct mmc_command cmd;
+       int i, err = 0;
+
+       BUG_ON(!host);
+
+       memset(&cmd, 0, sizeof(struct mmc_command));
+
+       cmd.opcode = SD_IO_SEND_OP_COND;
+       cmd.arg = ocr;
+       cmd.flags = MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR;
+
+       for (i = 100; i; i--) {
+               err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
+               if (err)
+                       break;
+
+               /* if we're just probing, do a single pass */
+               if (ocr == 0)
+                       break;
+
+               /* otherwise wait until reset completes */
+               if (mmc_host_is_spi(host)) {
+                       /*
+                        * Both R1_SPI_IDLE and MMC_CARD_BUSY indicate
+                        * an initialized card under SPI, but some cards
+                        * (Marvell's) only behave when looking at this
+                        * one.
+                        */
+                       if (cmd.resp[1] & MMC_CARD_BUSY)
+                               break;
+               } else {
+                       if (cmd.resp[0] & MMC_CARD_BUSY)
+                               break;
+               }
+
+               err = -ETIMEDOUT;
+
+               mmc_delay(10);
+       }
+
+       if (rocr)
+               *rocr = cmd.resp[mmc_host_is_spi(host) ? 1 : 0];
+
+       return err;
+}
+
+int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
+       unsigned addr, u8 in, u8* out)
+{
+       struct mmc_command cmd;
+       int err;
+
+       BUG_ON(!card);
+       BUG_ON(fn > 7);
+
+       memset(&cmd, 0, sizeof(struct mmc_command));
+
+       cmd.opcode = SD_IO_RW_DIRECT;
+       cmd.arg = write ? 0x80000000 : 0x00000000;
+       cmd.arg |= fn << 28;
+       cmd.arg |= (write && out) ? 0x08000000 : 0x00000000;
+       cmd.arg |= addr << 9;
+       cmd.arg |= in;
+       cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC;
+
+       err = mmc_wait_for_cmd(card->host, &cmd, 0);
+       if (err)
+               return err;
+
+       if (mmc_host_is_spi(card->host)) {
+               /* host driver already reported errors */
+       } else {
+               if (cmd.resp[0] & R5_ERROR)
+                       return -EIO;
+               if (cmd.resp[0] & R5_FUNCTION_NUMBER)
+                       return -EINVAL;
+               if (cmd.resp[0] & R5_OUT_OF_RANGE)
+                       return -ERANGE;
+       }
+
+       if (out) {
+               if (mmc_host_is_spi(card->host))
+                       *out = (cmd.resp[0] >> 8) & 0xFF;
+               else
+                       *out = cmd.resp[0] & 0xFF;
+       }
+
+       return 0;
+}
+
+int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
+       unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz)
+{
+       struct mmc_request mrq;
+       struct mmc_command cmd;
+       struct mmc_data data;
+       struct scatterlist sg;
+
+       BUG_ON(!card);
+       BUG_ON(fn > 7);
+       BUG_ON(blocks == 1 && blksz > 512);
+       WARN_ON(blocks == 0);
+       WARN_ON(blksz == 0);
+
+       memset(&mrq, 0, sizeof(struct mmc_request));
+       memset(&cmd, 0, sizeof(struct mmc_command));
+       memset(&data, 0, sizeof(struct mmc_data));
+
+       mrq.cmd = &cmd;
+       mrq.data = &data;
+
+       cmd.opcode = SD_IO_RW_EXTENDED;
+       cmd.arg = write ? 0x80000000 : 0x00000000;
+       cmd.arg |= fn << 28;
+       cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;
+       cmd.arg |= addr << 9;
+       if (blocks == 1 && blksz <= 512)
+               cmd.arg |= (blksz == 512) ? 0 : blksz;  /* byte mode */
+       else
+               cmd.arg |= 0x08000000 | blocks;         /* block mode */
+       cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+
+       data.blksz = blksz;
+       data.blocks = blocks;
+       data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
+       data.sg = &sg;
+       data.sg_len = 1;
+
+       sg_init_one(&sg, buf, blksz * blocks);
+
+       mmc_set_data_timeout(&data, card);
+
+       mmc_wait_for_req(card->host, &mrq);
+
+       if (cmd.error)
+               return cmd.error;
+       if (data.error)
+               return data.error;
+
+       if (mmc_host_is_spi(card->host)) {
+               /* host driver already reported errors */
+       } else {
+               if (cmd.resp[0] & R5_ERROR)
+                       return -EIO;
+               if (cmd.resp[0] & R5_FUNCTION_NUMBER)
+                       return -EINVAL;
+               if (cmd.resp[0] & R5_OUT_OF_RANGE)
+                       return -ERANGE;
+       }
+
+       return 0;
+}
+
diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h
new file mode 100644 (file)
index 0000000..e2e74b0
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ *  linux/drivers/mmc/sdio_ops.c
+ *
+ *  Copyright 2006-2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef _MMC_SDIO_OPS_H
+#define _MMC_SDIO_OPS_H
+
+int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr);
+int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
+       unsigned addr, u8 in, u8* out);
+int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
+       unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz);
+
+#endif
+
index e23082fe88d0ddebac4921b54631fb75bed935e0..5fef6783c7161fc8cf95b836e49dcc13259ff655 100644 (file)
@@ -35,6 +35,23 @@ config MMC_SDHCI
 
          If unsure, say N.
 
+config MMC_RICOH_MMC
+       tristate "Ricoh MMC Controller Disabler  (EXPERIMENTAL)"
+       depends on PCI && EXPERIMENTAL && MMC_SDHCI
+       help
+         This selects the disabler for the Ricoh MMC Controller. This
+         proprietary controller is unnecessary because the SDHCI driver
+         supports MMC cards on the SD controller, but if it is not
+         disabled, it will steal the MMC cards away - rendering them
+         useless. It is safe to select this driver even if you don't
+         have a Ricoh based card reader.
+
+
+         To compile this driver as a module, choose M here:
+         the module will be called ricoh_mmc.
+
+         If unsure, say Y.
+
 config MMC_OMAP
        tristate "TI OMAP Multimedia Card Interface support"
        depends on ARCH_OMAP
@@ -100,3 +117,16 @@ config MMC_TIFM_SD
           To compile this driver as a module, choose M here: the
          module will be called tifm_sd.
 
+config MMC_SPI
+       tristate "MMC/SD over SPI (EXPERIMENTAL)"
+       depends on MMC && SPI_MASTER && !HIGHMEM && EXPERIMENTAL
+       select CRC7
+       select CRC_ITU_T
+       help
+         Some systems accss MMC/SD cards using a SPI controller instead of
+         using a "native" MMC/SD controller.  This has a disadvantage of
+         being relatively high overhead, but a compensating advantage of
+         working on many systems without dedicated MMC/SD controllers.
+
+         If unsure, or if your system has no SPI master driver, say N.
+
index 6685f64345b4d649b16113dae53ec6bb00e21dcb..3877c87e6da26e699a730959104dc61ce5992290 100644 (file)
@@ -10,9 +10,11 @@ obj-$(CONFIG_MMC_ARMMMCI)    += mmci.o
 obj-$(CONFIG_MMC_PXA)          += pxamci.o
 obj-$(CONFIG_MMC_IMX)          += imxmmc.o
 obj-$(CONFIG_MMC_SDHCI)                += sdhci.o
+obj-$(CONFIG_MMC_RICOH_MMC)    += ricoh_mmc.o
 obj-$(CONFIG_MMC_WBSD)         += wbsd.o
 obj-$(CONFIG_MMC_AU1X)         += au1xmmc.o
 obj-$(CONFIG_MMC_OMAP)         += omap.o
 obj-$(CONFIG_MMC_AT91)         += at91_mci.o
 obj-$(CONFIG_MMC_TIFM_SD)      += tifm_sd.o
+obj-$(CONFIG_MMC_SPI)          += mmc_spi.o
 
index 955ea60583b5f5c77438c0ea166d6be060f37dcd..6ba98a49612d4c27ce4dc39aaff749cea6295942 100644 (file)
@@ -328,7 +328,7 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host)
        data = cmd->data;
        if (!data) return;
 
-       if (cmd->data->flags & MMC_DATA_MULTI) {
+       if (cmd->data->blocks > 1) {
                pr_debug("multiple write : wait for BLKE...\n");
                at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
        } else
@@ -428,6 +428,14 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
        }
 
        if (data) {
+
+               if ( data->blksz & 0x3 ) {
+                       pr_debug("Unsupported block size\n");
+                       cmd->error = -EINVAL;
+                       mmc_request_done(host->mmc, host->request);
+                       return;
+               }
+
                block_length = data->blksz;
                blocks = data->blocks;
 
@@ -439,7 +447,7 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command
 
                if (data->flags & MMC_DATA_STREAM)
                        cmdr |= AT91_MCI_TRTYP_STREAM;
-               if (data->flags & MMC_DATA_MULTI)
+               if (data->blocks > 1)
                        cmdr |= AT91_MCI_TRTYP_MULTIPLE;
        }
        else {
@@ -577,24 +585,22 @@ static void at91_mci_completed_command(struct at91mci_host *host)
                        AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE |
                        AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)) {
                if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
-                       cmd->error = MMC_ERR_NONE;
+                       cmd->error = 0;
                }
                else {
                        if (status & (AT91_MCI_RTOE | AT91_MCI_DTOE))
-                               cmd->error = MMC_ERR_TIMEOUT;
+                               cmd->error = -ETIMEDOUT;
                        else if (status & (AT91_MCI_RCRCE | AT91_MCI_DCRCE))
-                               cmd->error = MMC_ERR_BADCRC;
-                       else if (status & (AT91_MCI_OVRE | AT91_MCI_UNRE))
-                               cmd->error = MMC_ERR_FIFO;
+                               cmd->error = -EILSEQ;
                        else
-                               cmd->error = MMC_ERR_FAILED;
+                               cmd->error = -EIO;
 
                        pr_debug("Error detected and set to %d (cmd = %d, retries = %d)\n",
                                 cmd->error, cmd->opcode, cmd->retries);
                }
        }
        else
-               cmd->error = MMC_ERR_NONE;
+               cmd->error = 0;
 
        at91_mci_process_next(host);
 }
@@ -836,7 +842,6 @@ static int __init at91_mci_probe(struct platform_device *pdev)
        mmc->f_min = 375000;
        mmc->f_max = 25000000;
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-       mmc->caps = MMC_CAP_BYTEBLOCK;
 
        mmc->max_blk_size = 4095;
        mmc->max_blk_count = mmc->max_req_size;
index 34c99d4ea0415885e3bff95df2f6cc60a8aa564f..92c4d0dfee434d4d09eb5183314b2a1c3d09d9ed 100644 (file)
@@ -186,7 +186,7 @@ static void au1xmmc_tasklet_finish(unsigned long param)
 }
 
 static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
-                               struct mmc_command *cmd, unsigned int flags)
+                               struct mmc_command *cmd, struct mmc_data *data)
 {
        u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);
 
@@ -208,19 +208,21 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
        default:
                printk(KERN_INFO "au1xmmc: unhandled response type %02x\n",
                        mmc_resp_type(cmd));
-               return MMC_ERR_INVALID;
+               return -EINVAL;
        }
 
-       if (flags & MMC_DATA_READ) {
-               if (flags & MMC_DATA_MULTI)
-                       mmccmd |= SD_CMD_CT_4;
-               else
-                       mmccmd |= SD_CMD_CT_2;
-       } else if (flags & MMC_DATA_WRITE) {
-               if (flags & MMC_DATA_MULTI)
-                       mmccmd |= SD_CMD_CT_3;
-               else
-                       mmccmd |= SD_CMD_CT_1;
+       if (data) {
+               if (flags & MMC_DATA_READ) {
+                       if (data->blocks > 1)
+                               mmccmd |= SD_CMD_CT_4;
+                       else
+                               mmccmd |= SD_CMD_CT_2;
+               } else if (flags & MMC_DATA_WRITE) {
+                       if (data->blocks > 1)
+                               mmccmd |= SD_CMD_CT_3;
+                       else
+                               mmccmd |= SD_CMD_CT_1;
+               }
        }
 
        au_writel(cmd->arg, HOST_CMDARG(host));
@@ -253,7 +255,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
                IRQ_ON(host, SD_CONFIG_CR);
        }
 
-       return MMC_ERR_NONE;
+       return 0;
 }
 
 static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
@@ -278,7 +280,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
        while((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB))
                status = au_readl(HOST_STATUS(host));
 
-       data->error = MMC_ERR_NONE;
+       data->error = 0;
        dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir);
 
         /* Process any errors */
@@ -288,14 +290,14 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
                crc |= ((status & 0x07) == 0x02) ? 0 : 1;
 
        if (crc)
-               data->error = MMC_ERR_BADCRC;
+               data->error = -EILSEQ;
 
        /* Clear the CRC bits */
        au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host));
 
        data->bytes_xfered = 0;
 
-       if (data->error == MMC_ERR_NONE) {
+       if (!data->error) {
                if (host->flags & HOST_F_DMA) {
                        u32 chan = DMA_CHANNEL(host);
 
@@ -475,7 +477,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
                return;
 
        cmd = mrq->cmd;
-       cmd->error = MMC_ERR_NONE;
+       cmd->error = 0;
 
        if (cmd->flags & MMC_RSP_PRESENT) {
                if (cmd->flags & MMC_RSP_136) {
@@ -512,11 +514,11 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
         /* Figure out errors */
 
        if (status & (SD_STATUS_SC | SD_STATUS_WC | SD_STATUS_RC))
-               cmd->error = MMC_ERR_BADCRC;
+               cmd->error = -EILSEQ;
 
        trans = host->flags & (HOST_F_XMIT | HOST_F_RECV);
 
-       if (!trans || cmd->error != MMC_ERR_NONE) {
+       if (!trans || cmd->error) {
 
                IRQ_OFF(host, SD_CONFIG_TH | SD_CONFIG_RA|SD_CONFIG_RF);
                tasklet_schedule(&host->finish_task);
@@ -589,7 +591,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
                                   data->sg_len, host->dma.dir);
 
        if (host->dma.len == 0)
-               return MMC_ERR_TIMEOUT;
+               return -ETIMEDOUT;
 
        au_writel(data->blksz - 1, HOST_BLKSIZE(host));
 
@@ -640,11 +642,11 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
                        //IRQ_ON(host, SD_CONFIG_RA|SD_CONFIG_RF);
        }
 
-       return MMC_ERR_NONE;
+       return 0;
 
  dataerr:
        dma_unmap_sg(mmc_dev(host->mmc),data->sg,data->sg_len,host->dma.dir);
-       return MMC_ERR_TIMEOUT;
+       return -ETIMEDOUT;
 }
 
 /* static void au1xmmc_request
@@ -656,7 +658,7 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
 
        struct au1xmmc_host *host = mmc_priv(mmc);
        unsigned int flags = 0;
-       int ret = MMC_ERR_NONE;
+       int ret = 0;
 
        WARN_ON(irqs_disabled());
        WARN_ON(host->status != HOST_S_IDLE);
@@ -672,10 +674,10 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq)
                ret = au1xmmc_prepare_data(host, mrq->data);
        }
 
-       if (ret == MMC_ERR_NONE)
-               ret = au1xmmc_send_command(host, 0, mrq->cmd, flags);
+       if (!ret)
+               ret = au1xmmc_send_command(host, 0, mrq->cmd, mrq->data);
 
-       if (ret != MMC_ERR_NONE) {
+       if (ret) {
                mrq->cmd->error = ret;
                au1xmmc_finish_request(host);
        }
@@ -764,10 +766,10 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id)
 
                if (host->mrq && (status & STATUS_TIMEOUT)) {
                        if (status & SD_STATUS_RAT)
-                               host->mrq->cmd->error = MMC_ERR_TIMEOUT;
+                               host->mrq->cmd->error = -ETIMEDOUT;
 
                        else if (status & SD_STATUS_DT)
-                               host->mrq->data->error = MMC_ERR_TIMEOUT;
+                               host->mrq->data->error = -ETIMEDOUT;
 
                        /* In PIO mode, interrupts might still be enabled */
                        IRQ_OFF(host, SD_CONFIG_NE | SD_CONFIG_TH);
index 54bfc9f255966329b6e01c290650f297e7859154..6ebc41e7592cefd131915f6d82b4aff87aca1496 100644 (file)
@@ -428,11 +428,11 @@ static int imxmci_finish_data(struct imxmci_host *host, unsigned int stat)
        if ( stat & STATUS_ERR_MASK ) {
                dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",stat);
                if(stat & (STATUS_CRC_READ_ERR | STATUS_CRC_WRITE_ERR))
-                       data->error = MMC_ERR_BADCRC;
+                       data->error = -EILSEQ;
                else if(stat & STATUS_TIME_OUT_READ)
-                       data->error = MMC_ERR_TIMEOUT;
+                       data->error = -ETIMEDOUT;
                else
-                       data->error = MMC_ERR_FAILED;
+                       data->error = -EIO;
        } else {
                data->bytes_xfered = host->dma_size;
        }
@@ -458,10 +458,10 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat)
 
        if (stat & STATUS_TIME_OUT_RESP) {
                dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n");
-               cmd->error = MMC_ERR_TIMEOUT;
+               cmd->error = -ETIMEDOUT;
        } else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
                dev_dbg(mmc_dev(host->mmc), "cmd crc error\n");
-               cmd->error = MMC_ERR_BADCRC;
+               cmd->error = -EILSEQ;
        }
 
        if(cmd->flags & MMC_RSP_PRESENT) {
@@ -482,7 +482,7 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat)
        dev_dbg(mmc_dev(host->mmc), "RESP 0x%08x, 0x%08x, 0x%08x, 0x%08x, error %d\n",
                cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3], cmd->error);
 
-       if (data && (cmd->error == MMC_ERR_NONE) && !(stat & STATUS_ERR_MASK)) {
+       if (data && !cmd->error && !(stat & STATUS_ERR_MASK)) {
                if (host->req->data->flags & MMC_DATA_WRITE) {
 
                        /* Wait for FIFO to be empty before starting DMA write */
@@ -491,7 +491,7 @@ static int imxmci_cmd_done(struct imxmci_host *host, unsigned int stat)
                        if(imxmci_busy_wait_for_status(host, &stat,
                                STATUS_APPL_BUFF_FE,
                                40, "imxmci_cmd_done DMA WR") < 0) {
-                               cmd->error = MMC_ERR_FIFO;
+                               cmd->error = -EIO;
                                imxmci_finish_data(host, stat);
                                if(host->req)
                                        imxmci_finish_request(host, host->req);
@@ -884,9 +884,21 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        }
 }
 
+static int imxmci_get_ro(struct mmc_host *mmc)
+{
+       struct imxmci_host *host = mmc_priv(mmc);
+
+       if (host->pdata && host->pdata->get_ro)
+               return host->pdata->get_ro(mmc_dev(mmc));
+       /* Host doesn't support read only detection so assume writeable */
+       return 0;
+}
+
+
 static const struct mmc_host_ops imxmci_ops = {
        .request        = imxmci_request,
        .set_ios        = imxmci_set_ios,
+       .get_ro         = imxmci_get_ro,
 };
 
 static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr)
@@ -913,7 +925,7 @@ static void imxmci_check_status(unsigned long data)
 {
        struct imxmci_host *host = (struct imxmci_host *)data;
 
-       if( host->pdata->card_present() != host->present ) {
+       if( host->pdata->card_present(mmc_dev(host->mmc)) != host->present ) {
                host->present ^= 1;
                dev_info(mmc_dev(host->mmc), "card %s\n",
                      host->present ? "inserted" : "removed");
@@ -963,7 +975,7 @@ static int imxmci_probe(struct platform_device *pdev)
        mmc->f_min = 150000;
        mmc->f_max = CLK_RATE/2;
        mmc->ocr_avail = MMC_VDD_32_33;
-       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_BYTEBLOCK;
+       mmc->caps = MMC_CAP_4_BIT_DATA;
 
        /* MMC core transfer sizes tunable parameters */
        mmc->max_hw_segs = 64;
@@ -1022,7 +1034,7 @@ static int imxmci_probe(struct platform_device *pdev)
        if (ret)
                goto out;
 
-       host->present = host->pdata->card_present();
+       host->present = host->pdata->card_present(mmc_dev(mmc));
        init_timer(&host->timer);
        host->timer.data = (unsigned long)host;
        host->timer.function = imxmci_check_status;
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
new file mode 100644 (file)
index 0000000..f30327b
--- /dev/null
@@ -0,0 +1,1408 @@
+/*
+ * mmc_spi.c - Access SD/MMC cards through SPI master controllers
+ *
+ * (C) Copyright 2005, Intec Automation,
+ *             Mike Lavender (mike@steroidmicros)
+ * (C) Copyright 2006-2007, David Brownell
+ * (C) Copyright 2007, Axis Communications,
+ *             Hans-Peter Nilsson (hp@axis.com)
+ * (C) Copyright 2007, ATRON electronic GmbH,
+ *             Jan Nikitenko <jan.nikitenko@gmail.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/hrtimer.h>
+#include <linux/delay.h>
+#include <linux/blkdev.h>
+#include <linux/dma-mapping.h>
+#include <linux/crc7.h>
+#include <linux/crc-itu-t.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>             /* for R1_SPI_* bit values */
+
+#include <linux/spi/spi.h>
+#include <linux/spi/mmc_spi.h>
+
+#include <asm/unaligned.h>
+
+
+/* NOTES:
+ *
+ * - For now, we won't try to interoperate with a real mmc/sd/sdio
+ *   controller, although some of them do have hardware support for
+ *   SPI protocol.  The main reason for such configs would be mmc-ish
+ *   cards like DataFlash, which don't support that "native" protocol.
+ *
+ *   We don't have a "DataFlash/MMC/SD/SDIO card slot" abstraction to
+ *   switch between driver stacks, and in any case if "native" mode
+ *   is available, it will be faster and hence preferable.
+ *
+ * - MMC depends on a different chipselect management policy than the
+ *   SPI interface currently supports for shared bus segments:  it needs
+ *   to issue multiple spi_message requests with the chipselect active,
+ *   using the results of one message to decide the next one to issue.
+ *
+ *   Pending updates to the programming interface, this driver expects
+ *   that it not share the bus with other drivers (precluding conflicts).
+ *
+ * - We tell the controller to keep the chipselect active from the
+ *   beginning of an mmc_host_ops.request until the end.  So beware
+ *   of SPI controller drivers that mis-handle the cs_change flag!
+ *
+ *   However, many cards seem OK with chipselect flapping up/down
+ *   during that time ... at least on unshared bus segments.
+ */
+
+
+/*
+ * Local protocol constants, internal to data block protocols.
+ */
+
+/* Response tokens used to ack each block written: */
+#define SPI_MMC_RESPONSE_CODE(x)       ((x) & 0x1f)
+#define SPI_RESPONSE_ACCEPTED          ((2 << 1)|1)
+#define SPI_RESPONSE_CRC_ERR           ((5 << 1)|1)
+#define SPI_RESPONSE_WRITE_ERR         ((6 << 1)|1)
+
+/* Read and write blocks start with these tokens and end with crc;
+ * on error, read tokens act like a subset of R2_SPI_* values.
+ */
+#define SPI_TOKEN_SINGLE       0xfe    /* single block r/w, multiblock read */
+#define SPI_TOKEN_MULTI_WRITE  0xfc    /* multiblock write */
+#define SPI_TOKEN_STOP_TRAN    0xfd    /* terminate multiblock write */
+
+#define MMC_SPI_BLOCKSIZE      512
+
+
+/* These fixed timeouts come from the latest SD specs, which say to ignore
+ * the CSD values.  The R1B value is for card erase (e.g. the "I forgot the
+ * card's password" scenario); it's mostly applied to STOP_TRANSMISSION after
+ * reads which takes nowhere near that long.  Older cards may be able to use
+ * shorter timeouts ... but why bother?
+ */
+#define readblock_timeout      ktime_set(0, 100 * 1000 * 1000)
+#define writeblock_timeout     ktime_set(0, 250 * 1000 * 1000)
+#define r1b_timeout            ktime_set(3, 0)
+
+
+/****************************************************************************/
+
+/*
+ * Local Data Structures
+ */
+
+/* "scratch" is per-{command,block} data exchanged with the card */
+struct scratch {
+       u8                      status[29];
+       u8                      data_token;
+       __be16                  crc_val;
+};
+
+struct mmc_spi_host {
+       struct mmc_host         *mmc;
+       struct spi_device       *spi;
+
+       unsigned char           power_mode;
+       u16                     powerup_msecs;
+
+       struct mmc_spi_platform_data    *pdata;
+
+       /* for bulk data transfers */
+       struct spi_transfer     token, t, crc, early_status;
+       struct spi_message      m;
+
+       /* for status readback */
+       struct spi_transfer     status;
+       struct spi_message      readback;
+
+       /* underlying DMA-aware controller, or null */
+       struct device           *dma_dev;
+
+       /* buffer used for commands and for message "overhead" */
+       struct scratch          *data;
+       dma_addr_t              data_dma;
+
+       /* Specs say to write ones most of the time, even when the card
+        * has no need to read its input data; and many cards won't care.
+        * This is our source of those ones.
+        */
+       void                    *ones;
+       dma_addr_t              ones_dma;
+};
+
+
+/****************************************************************************/
+
+/*
+ * MMC-over-SPI protocol glue, used by the MMC stack interface
+ */
+
+static inline int mmc_cs_off(struct mmc_spi_host *host)
+{
+       /* chipselect will always be inactive after setup() */
+       return spi_setup(host->spi);
+}
+
+static int
+mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len)
+{
+       int status;
+
+       if (len > sizeof(*host->data)) {
+               WARN_ON(1);
+               return -EIO;
+       }
+
+       host->status.len = len;
+
+       if (host->dma_dev)
+               dma_sync_single_for_device(host->dma_dev,
+                               host->data_dma, sizeof(*host->data),
+                               DMA_FROM_DEVICE);
+
+       status = spi_sync(host->spi, &host->readback);
+       if (status == 0)
+               status = host->readback.status;
+
+       if (host->dma_dev)
+               dma_sync_single_for_cpu(host->dma_dev,
+                               host->data_dma, sizeof(*host->data),
+                               DMA_FROM_DEVICE);
+
+       return status;
+}
+
+static int
+mmc_spi_skip(struct mmc_spi_host *host, ktime_t timeout, unsigned n, u8 byte)
+{
+       u8              *cp = host->data->status;
+
+       timeout = ktime_add(timeout, ktime_get());
+
+       while (1) {
+               int             status;
+               unsigned        i;
+
+               status = mmc_spi_readbytes(host, n);
+               if (status < 0)
+                       return status;
+
+               for (i = 0; i < n; i++) {
+                       if (cp[i] != byte)
+                               return cp[i];
+               }
+
+               /* REVISIT investigate msleep() to avoid busy-wait I/O
+                * in at least some cases.
+                */
+               if (ktime_to_ns(ktime_sub(ktime_get(), timeout)) > 0)
+                       break;
+       }
+       return -ETIMEDOUT;
+}
+
+static inline int
+mmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout)
+{
+       return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0);
+}
+
+static int mmc_spi_readtoken(struct mmc_spi_host *host)
+{
+       return mmc_spi_skip(host, readblock_timeout, 1, 0xff);
+}
+
+
+/*
+ * Note that for SPI, cmd->resp[0] is not the same data as "native" protocol
+ * hosts return!  The low byte holds R1_SPI bits.  The next byte may hold
+ * R2_SPI bits ... for SEND_STATUS, or after data read errors.
+ *
+ * cmd->resp[1] holds any four-byte response, for R3 (READ_OCR) and on
+ * newer cards R7 (IF_COND).
+ */
+
+static char *maptype(struct mmc_command *cmd)
+{
+       switch (mmc_spi_resp_type(cmd)) {
+       case MMC_RSP_SPI_R1:    return "R1";
+       case MMC_RSP_SPI_R1B:   return "R1B";
+       case MMC_RSP_SPI_R2:    return "R2/R5";
+       case MMC_RSP_SPI_R3:    return "R3/R4/R7";
+       default:                return "?";
+       }
+}
+
+/* return zero, else negative errno after setting cmd->error */
+static int mmc_spi_response_get(struct mmc_spi_host *host,
+               struct mmc_command *cmd, int cs_on)
+{
+       u8      *cp = host->data->status;
+       u8      *end = cp + host->t.len;
+       int     value = 0;
+       char    tag[32];
+
+       snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
+               cmd->opcode, maptype(cmd));
+
+       /* Except for data block reads, the whole response will already
+        * be stored in the scratch buffer.  It's somewhere after the
+        * command and the first byte we read after it.  We ignore that
+        * first byte.  After STOP_TRANSMISSION command it may include
+        * two data bits, but otherwise it's all ones.
+        */
+       cp += 8;
+       while (cp < end && *cp == 0xff)
+               cp++;
+
+       /* Data block reads (R1 response types) may need more data... */
+       if (cp == end) {
+               unsigned        i;
+
+               cp = host->data->status;
+
+               /* Card sends N(CR) (== 1..8) bytes of all-ones then one
+                * status byte ... and we already scanned 2 bytes.
+                *
+                * REVISIT block read paths use nasty byte-at-a-time I/O
+                * so it can always DMA directly into the target buffer.
+                * It'd probably be better to memcpy() the first chunk and
+                * avoid extra i/o calls...
+                */
+               for (i = 2; i < 9; i++) {
+                       value = mmc_spi_readbytes(host, 1);
+                       if (value < 0)
+                               goto done;
+                       if (*cp != 0xff)
+                               goto checkstatus;
+               }
+               value = -ETIMEDOUT;
+               goto done;
+       }
+
+checkstatus:
+       if (*cp & 0x80) {
+               dev_dbg(&host->spi->dev, "%s: INVALID RESPONSE, %02x\n",
+                                       tag, *cp);
+               value = -EBADR;
+               goto done;
+       }
+
+       cmd->resp[0] = *cp++;
+       cmd->error = 0;
+
+       /* Status byte: the entire seven-bit R1 response.  */
+       if (cmd->resp[0] != 0) {
+               if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS
+                                       | R1_SPI_ILLEGAL_COMMAND)
+                               & cmd->resp[0])
+                       value = -EINVAL;
+               else if (R1_SPI_COM_CRC & cmd->resp[0])
+                       value = -EILSEQ;
+               else if ((R1_SPI_ERASE_SEQ | R1_SPI_ERASE_RESET)
+                               & cmd->resp[0])
+                       value = -EIO;
+               /* else R1_SPI_IDLE, "it's resetting" */
+       }
+
+       switch (mmc_spi_resp_type(cmd)) {
+
+       /* SPI R1B == R1 + busy; STOP_TRANSMISSION (for multiblock reads)
+        * and less-common stuff like various erase operations.
+        */
+       case MMC_RSP_SPI_R1B:
+               /* maybe we read all the busy tokens already */
+               while (cp < end && *cp == 0)
+                       cp++;
+               if (cp == end)
+                       mmc_spi_wait_unbusy(host, r1b_timeout);
+               break;
+
+       /* SPI R2 == R1 + second status byte; SEND_STATUS
+        * SPI R5 == R1 + data byte; IO_RW_DIRECT
+        */
+       case MMC_RSP_SPI_R2:
+               cmd->resp[0] |= *cp << 8;
+               break;
+
+       /* SPI R3, R4, or R7 == R1 + 4 bytes */
+       case MMC_RSP_SPI_R3:
+               cmd->resp[1] = be32_to_cpu(get_unaligned((u32 *)cp));
+               break;
+
+       /* SPI R1 == just one status byte */
+       case MMC_RSP_SPI_R1:
+               break;
+
+       default:
+               dev_dbg(&host->spi->dev, "bad response type %04x\n",
+                               mmc_spi_resp_type(cmd));
+               if (value >= 0)
+                       value = -EINVAL;
+               goto done;
+       }
+
+       if (value < 0)
+               dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n",
+                       tag, cmd->resp[0], cmd->resp[1]);
+
+       /* disable chipselect on errors and some success cases */
+       if (value >= 0 && cs_on)
+               return value;
+done:
+       if (value < 0)
+               cmd->error = value;
+       mmc_cs_off(host);
+       return value;
+}
+
+/* Issue command and read its response.
+ * Returns zero on success, negative for error.
+ *
+ * On error, caller must cope with mmc core retry mechanism.  That
+ * means immediate low-level resubmit, which affects the bus lock...
+ */
+static int
+mmc_spi_command_send(struct mmc_spi_host *host,
+               struct mmc_request *mrq,
+               struct mmc_command *cmd, int cs_on)
+{
+       struct scratch          *data = host->data;
+       u8                      *cp = data->status;
+       u32                     arg = cmd->arg;
+       int                     status;
+       struct spi_transfer     *t;
+
+       /* We can handle most commands (except block reads) in one full
+        * duplex I/O operation before either starting the next transfer
+        * (data block or command) or else deselecting the card.
+        *
+        * First, write 7 bytes:
+        *  - an all-ones byte to ensure the card is ready
+        *  - opcode byte (plus start and transmission bits)
+        *  - four bytes of big-endian argument
+        *  - crc7 (plus end bit) ... always computed, it's cheap
+        *
+        * We init the whole buffer to all-ones, which is what we need
+        * to write while we're reading (later) response data.
+        */
+       memset(cp++, 0xff, sizeof(data->status));
+
+       *cp++ = 0x40 | cmd->opcode;
+       *cp++ = (u8)(arg >> 24);
+       *cp++ = (u8)(arg >> 16);
+       *cp++ = (u8)(arg >> 8);
+       *cp++ = (u8)arg;
+       *cp++ = (crc7(0, &data->status[1], 5) << 1) | 0x01;
+
+       /* Then, read up to 13 bytes (while writing all-ones):
+        *  - N(CR) (== 1..8) bytes of all-ones
+        *  - status byte (for all response types)
+        *  - the rest of the response, either:
+        *      + nothing, for R1 or R1B responses
+        *      + second status byte, for R2 responses
+        *      + four data bytes, for R3 and R7 responses
+        *
+        * Finally, read some more bytes ... in the nice cases we know in
+        * advance how many, and reading 1 more is always OK:
+        *  - N(EC) (== 0..N) bytes of all-ones, before deselect/finish
+        *  - N(RC) (== 1..N) bytes of all-ones, before next command
+        *  - N(WR) (== 1..N) bytes of all-ones, before data write
+        *
+        * So in those cases one full duplex I/O of at most 21 bytes will
+        * handle the whole command, leaving the card ready to receive a
+        * data block or new command.  We do that whenever we can, shaving
+        * CPU and IRQ costs (especially when using DMA or FIFOs).
+        *
+        * There are two other cases, where it's not generally practical
+        * to rely on a single I/O:
+        *
+        *  - R1B responses need at least N(EC) bytes of all-zeroes.
+        *
+        *    In this case we can *try* to fit it into one I/O, then
+        *    maybe read more data later.
+        *
+        *  - Data block reads are more troublesome, since a variable
+        *    number of padding bytes precede the token and data.
+        *      + N(CX) (== 0..8) bytes of all-ones, before CSD or CID
+        *      + N(AC) (== 1..many) bytes of all-ones
+        *
+        *    In this case we currently only have minimal speedups here:
+        *    when N(CR) == 1 we can avoid I/O in response_get().
+        */
+       if (cs_on && (mrq->data->flags & MMC_DATA_READ)) {
+               cp += 2;        /* min(N(CR)) + status */
+               /* R1 */
+       } else {
+               cp += 10;       /* max(N(CR)) + status + min(N(RC),N(WR)) */
+               if (cmd->flags & MMC_RSP_SPI_S2)        /* R2/R5 */
+                       cp++;
+               else if (cmd->flags & MMC_RSP_SPI_B4)   /* R3/R4/R7 */
+                       cp += 4;
+               else if (cmd->flags & MMC_RSP_BUSY)     /* R1B */
+                       cp = data->status + sizeof(data->status);
+               /* else:  R1 (most commands) */
+       }
+
+       dev_dbg(&host->spi->dev, "  mmc_spi: CMD%d, resp %s\n",
+               cmd->opcode, maptype(cmd));
+
+       /* send command, leaving chipselect active */
+       spi_message_init(&host->m);
+
+       t = &host->t;
+       memset(t, 0, sizeof(*t));
+       t->tx_buf = t->rx_buf = data->status;
+       t->tx_dma = t->rx_dma = host->data_dma;
+       t->len = cp - data->status;
+       t->cs_change = 1;
+       spi_message_add_tail(t, &host->m);
+
+       if (host->dma_dev) {
+               host->m.is_dma_mapped = 1;
+               dma_sync_single_for_device(host->dma_dev,
+                               host->data_dma, sizeof(*host->data),
+                               DMA_BIDIRECTIONAL);
+       }
+       status = spi_sync(host->spi, &host->m);
+       if (status == 0)
+               status = host->m.status;
+
+       if (host->dma_dev)
+               dma_sync_single_for_cpu(host->dma_dev,
+                               host->data_dma, sizeof(*host->data),
+                               DMA_BIDIRECTIONAL);
+       if (status < 0) {
+               dev_dbg(&host->spi->dev, "  ... write returned %d\n", status);
+               cmd->error = status;
+               return status;
+       }
+
+       /* after no-data commands and STOP_TRANSMISSION, chipselect off */
+       return mmc_spi_response_get(host, cmd, cs_on);
+}
+
+/* Build data message with up to four separate transfers.  For TX, we
+ * start by writing the data token.  And in most cases, we finish with
+ * a status transfer.
+ *
+ * We always provide TX data for data and CRC.  The MMC/SD protocol
+ * requires us to write ones; but Linux defaults to writing zeroes;
+ * so we explicitly initialize it to all ones on RX paths.
+ *
+ * We also handle DMA mapping, so the underlying SPI controller does
+ * not need to (re)do it for each message.
+ */
+static void
+mmc_spi_setup_data_message(
+       struct mmc_spi_host     *host,
+       int                     multiple,
+       enum dma_data_direction direction)
+{
+       struct spi_transfer     *t;
+       struct scratch          *scratch = host->data;
+       dma_addr_t              dma = host->data_dma;
+
+       spi_message_init(&host->m);
+       if (dma)
+               host->m.is_dma_mapped = 1;
+
+       /* for reads, readblock() skips 0xff bytes before finding
+        * the token; for writes, this transfer issues that token.
+        */
+       if (direction == DMA_TO_DEVICE) {
+               t = &host->token;
+               memset(t, 0, sizeof(*t));
+               t->len = 1;
+               if (multiple)
+                       scratch->data_token = SPI_TOKEN_MULTI_WRITE;
+               else
+                       scratch->data_token = SPI_TOKEN_SINGLE;
+               t->tx_buf = &scratch->data_token;
+               if (dma)
+                       t->tx_dma = dma + offsetof(struct scratch, data_token);
+               spi_message_add_tail(t, &host->m);
+       }
+
+       /* Body of transfer is buffer, then CRC ...
+        * either TX-only, or RX with TX-ones.
+        */
+       t = &host->t;
+       memset(t, 0, sizeof(*t));
+       t->tx_buf = host->ones;
+       t->tx_dma = host->ones_dma;
+       /* length and actual buffer info are written later */
+       spi_message_add_tail(t, &host->m);
+
+       t = &host->crc;
+       memset(t, 0, sizeof(*t));
+       t->len = 2;
+       if (direction == DMA_TO_DEVICE) {
+               /* the actual CRC may get written later */
+               t->tx_buf = &scratch->crc_val;
+               if (dma)
+                       t->tx_dma = dma + offsetof(struct scratch, crc_val);
+       } else {
+               t->tx_buf = host->ones;
+               t->tx_dma = host->ones_dma;
+               t->rx_buf = &scratch->crc_val;
+               if (dma)
+                       t->rx_dma = dma + offsetof(struct scratch, crc_val);
+       }
+       spi_message_add_tail(t, &host->m);
+
+       /*
+        * A single block read is followed by N(EC) [0+] all-ones bytes
+        * before deselect ... don't bother.
+        *
+        * Multiblock reads are followed by N(AC) [1+] all-ones bytes before
+        * the next block is read, or a STOP_TRANSMISSION is issued.  We'll
+        * collect that single byte, so readblock() doesn't need to.
+        *
+        * For a write, the one-byte data response follows immediately, then
+        * come zero or more busy bytes, then N(WR) [1+] all-ones bytes.
+        * Then single block reads may deselect, and multiblock ones issue
+        * the next token (next data block, or STOP_TRAN).  We can try to
+        * minimize I/O ops by using a single read to collect end-of-busy.
+        */
+       if (multiple || direction == DMA_TO_DEVICE) {
+               t = &host->early_status;
+               memset(t, 0, sizeof(*t));
+               t->len = (direction == DMA_TO_DEVICE)
+                               ? sizeof(scratch->status)
+                               : 1;
+               t->tx_buf = host->ones;
+               t->tx_dma = host->ones_dma;
+               t->rx_buf = scratch->status;
+               if (dma)
+                       t->rx_dma = dma + offsetof(struct scratch, status);
+               t->cs_change = 1;
+               spi_message_add_tail(t, &host->m);
+       }
+}
+
+/*
+ * Write one block:
+ *  - caller handled preceding N(WR) [1+] all-ones bytes
+ *  - data block
+ *     + token
+ *     + data bytes
+ *     + crc16
+ *  - an all-ones byte ... card writes a data-response byte
+ *  - followed by N(EC) [0+] all-ones bytes, card writes zero/'busy'
+ *
+ * Return negative errno, else success.
+ */
+static int
+mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t)
+{
+       struct spi_device       *spi = host->spi;
+       int                     status, i;
+       struct scratch          *scratch = host->data;
+
+       if (host->mmc->use_spi_crc)
+               scratch->crc_val = cpu_to_be16(
+                               crc_itu_t(0, t->tx_buf, t->len));
+       if (host->dma_dev)
+               dma_sync_single_for_device(host->dma_dev,
+                               host->data_dma, sizeof(*scratch),
+                               DMA_BIDIRECTIONAL);
+
+       status = spi_sync(spi, &host->m);
+       if (status == 0)
+               status = host->m.status;
+
+       if (status != 0) {
+               dev_dbg(&spi->dev, "write error (%d)\n", status);
+               return status;
+       }
+
+       if (host->dma_dev)
+               dma_sync_single_for_cpu(host->dma_dev,
+                               host->data_dma, sizeof(*scratch),
+                               DMA_BIDIRECTIONAL);
+
+       /*
+        * Get the transmission data-response reply.  It must follow
+        * immediately after the data block we transferred.  This reply
+        * doesn't necessarily tell whether the write operation succeeded;
+        * it just says if the transmission was ok and whether *earlier*
+        * writes succeeded; see the standard.
+        */
+       switch (SPI_MMC_RESPONSE_CODE(scratch->status[0])) {
+       case SPI_RESPONSE_ACCEPTED:
+               status = 0;
+               break;
+       case SPI_RESPONSE_CRC_ERR:
+               /* host shall then issue MMC_STOP_TRANSMISSION */
+               status = -EILSEQ;
+               break;
+       case SPI_RESPONSE_WRITE_ERR:
+               /* host shall then issue MMC_STOP_TRANSMISSION,
+                * and should MMC_SEND_STATUS to sort it out
+                */
+               status = -EIO;
+               break;
+       default:
+               status = -EPROTO;
+               break;
+       }
+       if (status != 0) {
+               dev_dbg(&spi->dev, "write error %02x (%d)\n",
+                       scratch->status[0], status);
+               return status;
+       }
+
+       t->tx_buf += t->len;
+       if (host->dma_dev)
+               t->tx_dma += t->len;
+
+       /* Return when not busy.  If we didn't collect that status yet,
+        * we'll need some more I/O.
+        */
+       for (i = 1; i < sizeof(scratch->status); i++) {
+               if (scratch->status[i] != 0)
+                       return 0;
+       }
+       return mmc_spi_wait_unbusy(host, writeblock_timeout);
+}
+
+/*
+ * Read one block:
+ *  - skip leading all-ones bytes ... either
+ *      + N(AC) [1..f(clock,CSD)] usually, else
+ *      + N(CX) [0..8] when reading CSD or CID
+ *  - data block
+ *     + token ... if error token, no data or crc
+ *     + data bytes
+ *     + crc16
+ *
+ * After single block reads, we're done; N(EC) [0+] all-ones bytes follow
+ * before dropping chipselect.
+ *
+ * For multiblock reads, caller either reads the next block or issues a
+ * STOP_TRANSMISSION command.
+ */
+static int
+mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t)
+{
+       struct spi_device       *spi = host->spi;
+       int                     status;
+       struct scratch          *scratch = host->data;
+
+       /* At least one SD card sends an all-zeroes byte when N(CX)
+        * applies, before the all-ones bytes ... just cope with that.
+        */
+       status = mmc_spi_readbytes(host, 1);
+       if (status < 0)
+               return status;
+       status = scratch->status[0];
+       if (status == 0xff || status == 0)
+               status = mmc_spi_readtoken(host);
+
+       if (status == SPI_TOKEN_SINGLE) {
+               if (host->dma_dev) {
+                       dma_sync_single_for_device(host->dma_dev,
+                                       host->data_dma, sizeof(*scratch),
+                                       DMA_BIDIRECTIONAL);
+                       dma_sync_single_for_device(host->dma_dev,
+                                       t->rx_dma, t->len,
+                                       DMA_FROM_DEVICE);
+               }
+
+               status = spi_sync(spi, &host->m);
+               if (status == 0)
+                       status = host->m.status;
+
+               if (host->dma_dev) {
+                       dma_sync_single_for_cpu(host->dma_dev,
+                                       host->data_dma, sizeof(*scratch),
+                                       DMA_BIDIRECTIONAL);
+                       dma_sync_single_for_cpu(host->dma_dev,
+                                       t->rx_dma, t->len,
+                                       DMA_FROM_DEVICE);
+               }
+
+       } else {
+               dev_dbg(&spi->dev, "read error %02x (%d)\n", status, status);
+
+               /* we've read extra garbage, timed out, etc */
+               if (status < 0)
+                       return status;
+
+               /* low four bits are an R2 subset, fifth seems to be
+                * vendor specific ... map them all to generic error..
+                */
+               return -EIO;
+       }
+
+       if (host->mmc->use_spi_crc) {
+               u16 crc = crc_itu_t(0, t->rx_buf, t->len);
+
+               be16_to_cpus(&scratch->crc_val);
+               if (scratch->crc_val != crc) {
+                       dev_dbg(&spi->dev, "read - crc error: crc_val=0x%04x, "
+                                       "computed=0x%04x len=%d\n",
+                                       scratch->crc_val, crc, t->len);
+                       return -EILSEQ;
+               }
+       }
+
+       t->rx_buf += t->len;
+       if (host->dma_dev)
+               t->rx_dma += t->len;
+
+       return 0;
+}
+
+/*
+ * An MMC/SD data stage includes one or more blocks, optional CRCs,
+ * and inline handshaking.  That handhaking makes it unlike most
+ * other SPI protocol stacks.
+ */
+static void
+mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
+               struct mmc_data *data, u32 blk_size)
+{
+       struct spi_device       *spi = host->spi;
+       struct device           *dma_dev = host->dma_dev;
+       struct spi_transfer     *t;
+       enum dma_data_direction direction;
+       struct scatterlist      *sg;
+       unsigned                n_sg;
+       int                     multiple = (data->blocks > 1);
+
+       if (data->flags & MMC_DATA_READ)
+               direction = DMA_FROM_DEVICE;
+       else
+               direction = DMA_TO_DEVICE;
+       mmc_spi_setup_data_message(host, multiple, direction);
+       t = &host->t;
+
+       /* Handle scatterlist segments one at a time, with synch for
+        * each 512-byte block
+        */
+       for (sg = data->sg, n_sg = data->sg_len; n_sg; n_sg--, sg++) {
+               int                     status = 0;
+               dma_addr_t              dma_addr = 0;
+               void                    *kmap_addr;
+               unsigned                length = sg->length;
+               enum dma_data_direction dir = direction;
+
+               /* set up dma mapping for controller drivers that might
+                * use DMA ... though they may fall back to PIO
+                */
+               if (dma_dev) {
+                       /* never invalidate whole *shared* pages ... */
+                       if ((sg->offset != 0 || length != PAGE_SIZE)
+                                       && dir == DMA_FROM_DEVICE)
+                               dir = DMA_BIDIRECTIONAL;
+
+                       dma_addr = dma_map_page(dma_dev, sg->page, 0,
+                                               PAGE_SIZE, dir);
+                       if (direction == DMA_TO_DEVICE)
+                               t->tx_dma = dma_addr + sg->offset;
+                       else
+                               t->rx_dma = dma_addr + sg->offset;
+               }
+
+               /* allow pio too; we don't allow highmem */
+               kmap_addr = kmap(sg->page);
+               if (direction == DMA_TO_DEVICE)
+                       t->tx_buf = kmap_addr + sg->offset;
+               else
+                       t->rx_buf = kmap_addr + sg->offset;
+
+               /* transfer each block, and update request status */
+               while (length) {
+                       t->len = min(length, blk_size);
+
+                       dev_dbg(&host->spi->dev,
+                               "    mmc_spi: %s block, %d bytes\n",
+                               (direction == DMA_TO_DEVICE)
+                               ? "write"
+                               : "read",
+                               t->len);
+
+                       if (direction == DMA_TO_DEVICE)
+                               status = mmc_spi_writeblock(host, t);
+                       else
+                               status = mmc_spi_readblock(host, t);
+                       if (status < 0)
+                               break;
+
+                       data->bytes_xfered += t->len;
+                       length -= t->len;
+
+                       if (!multiple)
+                               break;
+               }
+
+               /* discard mappings */
+               if (direction == DMA_FROM_DEVICE)
+                       flush_kernel_dcache_page(sg->page);
+               kunmap(sg->page);
+               if (dma_dev)
+                       dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
+
+               if (status < 0) {
+                       data->error = status;
+                       dev_dbg(&spi->dev, "%s status %d\n",
+                               (direction == DMA_TO_DEVICE)
+                                       ? "write" : "read",
+                               status);
+                       break;
+               }
+       }
+
+       /* NOTE some docs describe an MMC-only SET_BLOCK_COUNT (CMD23) that
+        * can be issued before multiblock writes.  Unlike its more widely
+        * documented analogue for SD cards (SET_WR_BLK_ERASE_COUNT, ACMD23),
+        * that can affect the STOP_TRAN logic.   Complete (and current)
+        * MMC specs should sort that out before Linux starts using CMD23.
+        */
+       if (direction == DMA_TO_DEVICE && multiple) {
+               struct scratch  *scratch = host->data;
+               int             tmp;
+               const unsigned  statlen = sizeof(scratch->status);
+
+               dev_dbg(&spi->dev, "    mmc_spi: STOP_TRAN\n");
+
+               /* Tweak the per-block message we set up earlier by morphing
+                * it to hold single buffer with the token followed by some
+                * all-ones bytes ... skip N(BR) (0..1), scan the rest for
+                * "not busy any longer" status, and leave chip selected.
+                */
+               INIT_LIST_HEAD(&host->m.transfers);
+               list_add(&host->early_status.transfer_list,
+                               &host->m.transfers);
+
+               memset(scratch->status, 0xff, statlen);
+               scratch->status[0] = SPI_TOKEN_STOP_TRAN;
+
+               host->early_status.tx_buf = host->early_status.rx_buf;
+               host->early_status.tx_dma = host->early_status.rx_dma;
+               host->early_status.len = statlen;
+
+               if (host->dma_dev)
+                       dma_sync_single_for_device(host->dma_dev,
+                                       host->data_dma, sizeof(*scratch),
+                                       DMA_BIDIRECTIONAL);
+
+               tmp = spi_sync(spi, &host->m);
+               if (tmp == 0)
+                       tmp = host->m.status;
+
+               if (host->dma_dev)
+                       dma_sync_single_for_cpu(host->dma_dev,
+                                       host->data_dma, sizeof(*scratch),
+                                       DMA_BIDIRECTIONAL);
+
+               if (tmp < 0) {
+                       if (!data->error)
+                               data->error = tmp;
+                       return;
+               }
+
+               /* Ideally we collected "not busy" status with one I/O,
+                * avoiding wasteful byte-at-a-time scanning... but more
+                * I/O is often needed.
+                */
+               for (tmp = 2; tmp < statlen; tmp++) {
+                       if (scratch->status[tmp] != 0)
+                               return;
+               }
+               tmp = mmc_spi_wait_unbusy(host, writeblock_timeout);
+               if (tmp < 0 && !data->error)
+                       data->error = tmp;
+       }
+}
+
+/****************************************************************************/
+
+/*
+ * MMC driver implementation -- the interface to the MMC stack
+ */
+
+static void mmc_spi_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+       struct mmc_spi_host     *host = mmc_priv(mmc);
+       int                     status = -EINVAL;
+
+#ifdef DEBUG
+       /* MMC core and layered drivers *MUST* issue SPI-aware commands */
+       {
+               struct mmc_command      *cmd;
+               int                     invalid = 0;
+
+               cmd = mrq->cmd;
+               if (!mmc_spi_resp_type(cmd)) {
+                       dev_dbg(&host->spi->dev, "bogus command\n");
+                       cmd->error = -EINVAL;
+                       invalid = 1;
+               }
+
+               cmd = mrq->stop;
+               if (cmd && !mmc_spi_resp_type(cmd)) {
+                       dev_dbg(&host->spi->dev, "bogus STOP command\n");
+                       cmd->error = -EINVAL;
+                       invalid = 1;
+               }
+
+               if (invalid) {
+                       dump_stack();
+                       mmc_request_done(host->mmc, mrq);
+                       return;
+               }
+       }
+#endif
+
+       /* issue command; then optionally data and stop */
+       status = mmc_spi_command_send(host, mrq, mrq->cmd, mrq->data != NULL);
+       if (status == 0 && mrq->data) {
+               mmc_spi_data_do(host, mrq->cmd, mrq->data, mrq->data->blksz);
+               if (mrq->stop)
+                       status = mmc_spi_command_send(host, mrq, mrq->stop, 0);
+               else
+                       mmc_cs_off(host);
+       }
+
+       mmc_request_done(host->mmc, mrq);
+}
+
+/* See Section 6.4.1, in SD "Simplified Physical Layer Specification 2.0"
+ *
+ * NOTE that here we can't know that the card has just been powered up;
+ * not all MMC/SD sockets support power switching.
+ *
+ * FIXME when the card is still in SPI mode, e.g. from a previous kernel,
+ * this doesn't seem to do the right thing at all...
+ */
+static void mmc_spi_initsequence(struct mmc_spi_host *host)
+{
+       /* Try to be very sure any previous command has completed;
+        * wait till not-busy, skip debris from any old commands.
+        */
+       mmc_spi_wait_unbusy(host, r1b_timeout);
+       mmc_spi_readbytes(host, 10);
+
+       /*
+        * Do a burst with chipselect active-high.  We need to do this to
+        * meet the requirement of 74 clock cycles with both chipselect
+        * and CMD (MOSI) high before CMD0 ... after the card has been
+        * powered up to Vdd(min), and so is ready to take commands.
+        *
+        * Some cards are particularly needy of this (e.g. Viking "SD256")
+        * while most others don't seem to care.
+        *
+        * Note that this is one of the places MMC/SD plays games with the
+        * SPI protocol.  Another is that when chipselect is released while
+        * the card returns BUSY status, the clock must issue several cycles
+        * with chipselect high before the card will stop driving its output.
+        */
+       host->spi->mode |= SPI_CS_HIGH;
+       if (spi_setup(host->spi) != 0) {
+               /* Just warn; most cards work without it. */
+               dev_warn(&host->spi->dev,
+                               "can't change chip-select polarity\n");
+               host->spi->mode &= ~SPI_CS_HIGH;
+       } else {
+               mmc_spi_readbytes(host, 18);
+
+               host->spi->mode &= ~SPI_CS_HIGH;
+               if (spi_setup(host->spi) != 0) {
+                       /* Wot, we can't get the same setup we had before? */
+                       dev_err(&host->spi->dev,
+                                       "can't restore chip-select polarity\n");
+               }
+       }
+}
+
+static char *mmc_powerstring(u8 power_mode)
+{
+       switch (power_mode) {
+       case MMC_POWER_OFF: return "off";
+       case MMC_POWER_UP:  return "up";
+       case MMC_POWER_ON:  return "on";
+       }
+       return "?";
+}
+
+static void mmc_spi_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+       struct mmc_spi_host *host = mmc_priv(mmc);
+
+       if (host->power_mode != ios->power_mode) {
+               int             canpower;
+
+               canpower = host->pdata && host->pdata->setpower;
+
+               dev_dbg(&host->spi->dev, "mmc_spi: power %s (%d)%s\n",
+                               mmc_powerstring(ios->power_mode),
+                               ios->vdd,
+                               canpower ? ", can switch" : "");
+
+               /* switch power on/off if possible, accounting for
+                * max 250msec powerup time if needed.
+                */
+               if (canpower) {
+                       switch (ios->power_mode) {
+                       case MMC_POWER_OFF:
+                       case MMC_POWER_UP:
+                               host->pdata->setpower(&host->spi->dev,
+                                               ios->vdd);
+                               if (ios->power_mode == MMC_POWER_UP)
+                                       msleep(host->powerup_msecs);
+                       }
+               }
+
+               /* See 6.4.1 in the simplified SD card physical spec 2.0 */
+               if (ios->power_mode == MMC_POWER_ON)
+                       mmc_spi_initsequence(host);
+
+               /* If powering down, ground all card inputs to avoid power
+                * delivery from data lines!  On a shared SPI bus, this
+                * will probably be temporary; 6.4.2 of the simplified SD
+                * spec says this must last at least 1msec.
+                *
+                *   - Clock low means CPOL 0, e.g. mode 0
+                *   - MOSI low comes from writing zero
+                *   - Chipselect is usually active low...
+                */
+               if (canpower && ios->power_mode == MMC_POWER_OFF) {
+                       int mres;
+
+                       host->spi->mode &= ~(SPI_CPOL|SPI_CPHA);
+                       mres = spi_setup(host->spi);
+                       if (mres < 0)
+                               dev_dbg(&host->spi->dev,
+                                       "switch to SPI mode 0 failed\n");
+
+                       if (spi_w8r8(host->spi, 0x00) < 0)
+                               dev_dbg(&host->spi->dev,
+                                       "put spi signals to low failed\n");
+
+                       /*
+                        * Now clock should be low due to spi mode 0;
+                        * MOSI should be low because of written 0x00;
+                        * chipselect should be low (it is active low)
+                        * power supply is off, so now MMC is off too!
+                        *
+                        * FIXME no, chipselect can be high since the
+                        * device is inactive and SPI_CS_HIGH is clear...
+                        */
+                       msleep(10);
+                       if (mres == 0) {
+                               host->spi->mode |= (SPI_CPOL|SPI_CPHA);
+                               mres = spi_setup(host->spi);
+                               if (mres < 0)
+                                       dev_dbg(&host->spi->dev,
+                                               "switch back to SPI mode 3"
+                                               " failed\n");
+                       }
+               }
+
+               host->power_mode = ios->power_mode;
+       }
+
+       if (host->spi->max_speed_hz != ios->clock && ios->clock != 0) {
+               int             status;
+
+               host->spi->max_speed_hz = ios->clock;
+               status = spi_setup(host->spi);
+               dev_dbg(&host->spi->dev,
+                       "mmc_spi:  clock to %d Hz, %d\n",
+                       host->spi->max_speed_hz, status);
+       }
+}
+
+static int mmc_spi_get_ro(struct mmc_host *mmc)
+{
+       struct mmc_spi_host *host = mmc_priv(mmc);
+
+       if (host->pdata && host->pdata->get_ro)
+               return host->pdata->get_ro(mmc->parent);
+       /* board doesn't support read only detection; assume writeable */
+       return 0;
+}
+
+
+static const struct mmc_host_ops mmc_spi_ops = {
+       .request        = mmc_spi_request,
+       .set_ios        = mmc_spi_set_ios,
+       .get_ro         = mmc_spi_get_ro,
+};
+
+
+/****************************************************************************/
+
+/*
+ * SPI driver implementation
+ */
+
+static irqreturn_t
+mmc_spi_detect_irq(int irq, void *mmc)
+{
+       struct mmc_spi_host *host = mmc_priv(mmc);
+       u16 delay_msec = max(host->pdata->detect_delay, (u16)100);
+
+       mmc_detect_change(mmc, msecs_to_jiffies(delay_msec));
+       return IRQ_HANDLED;
+}
+
+static int mmc_spi_probe(struct spi_device *spi)
+{
+       void                    *ones;
+       struct mmc_host         *mmc;
+       struct mmc_spi_host     *host;
+       int                     status;
+
+       /* MMC and SD specs only seem to care that sampling is on the
+        * rising edge ... meaning SPI modes 0 or 3.  So either SPI mode
+        * should be legit.  We'll use mode 0 since it seems to be a
+        * bit less troublesome on some hardware ... unclear why.
+        */
+       spi->mode = SPI_MODE_0;
+       spi->bits_per_word = 8;
+
+       status = spi_setup(spi);
+       if (status < 0) {
+               dev_dbg(&spi->dev, "needs SPI mode %02x, %d KHz; %d\n",
+                               spi->mode, spi->max_speed_hz / 1000,
+                               status);
+               return status;
+       }
+
+       /* We can use the bus safely iff nobody else will interfere with
+        * us.  That is, either we have the experimental exclusive access
+        * primitives ... or else there's nobody to share it with.
+        */
+       if (spi->master->num_chipselect > 1) {
+               struct device   *parent = spi->dev.parent;
+
+               /* If there are multiple devices on this bus, we
+                * can't proceed.
+                */
+               spin_lock(&parent->klist_children.k_lock);
+               if (parent->klist_children.k_list.next
+                               != parent->klist_children.k_list.prev)
+                       status = -EMLINK;
+               else
+                       status = 0;
+               spin_unlock(&parent->klist_children.k_lock);
+               if (status < 0) {
+                       dev_err(&spi->dev, "can't share SPI bus\n");
+                       return status;
+               }
+
+               /* REVISIT we can't guarantee another device won't
+                * be added later.  It's uncommon though ... for now,
+                * work as if this is safe.
+                */
+               dev_warn(&spi->dev, "ASSUMING unshared SPI bus!\n");
+       }
+
+       /* We need a supply of ones to transmit.  This is the only time
+        * the CPU touches these, so cache coherency isn't a concern.
+        *
+        * NOTE if many systems use more than one MMC-over-SPI connector
+        * it'd save some memory to share this.  That's evidently rare.
+        */
+       status = -ENOMEM;
+       ones = kmalloc(MMC_SPI_BLOCKSIZE, GFP_KERNEL);
+       if (!ones)
+               goto nomem;
+       memset(ones, 0xff, MMC_SPI_BLOCKSIZE);
+
+       mmc = mmc_alloc_host(sizeof(*host), &spi->dev);
+       if (!mmc)
+               goto nomem;
+
+       mmc->ops = &mmc_spi_ops;
+       mmc->max_blk_size = MMC_SPI_BLOCKSIZE;
+
+       /* As long as we keep track of the number of successfully
+        * transmitted blocks, we're good for multiwrite.
+        */
+       mmc->caps = MMC_CAP_SPI | MMC_CAP_MULTIWRITE;
+
+       /* SPI doesn't need the lowspeed device identification thing for
+        * MMC or SD cards, since it never comes up in open drain mode.
+        * That's good; some SPI masters can't handle very low speeds!
+        *
+        * However, low speed SDIO cards need not handle over 400 KHz;
+        * that's the only reason not to use a few MHz for f_min (until
+        * the upper layer reads the target frequency from the CSD).
+        */
+       mmc->f_min = 400000;
+       mmc->f_max = spi->max_speed_hz;
+
+       host = mmc_priv(mmc);
+       host->mmc = mmc;
+       host->spi = spi;
+
+       host->ones = ones;
+
+       /* Platform data is used to hook up things like card sensing
+        * and power switching gpios.
+        */
+       host->pdata = spi->dev.platform_data;
+       if (host->pdata)
+               mmc->ocr_avail = host->pdata->ocr_mask;
+       if (!mmc->ocr_avail) {
+               dev_warn(&spi->dev, "ASSUMING 3.2-3.4 V slot power\n");
+               mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
+       }
+       if (host->pdata && host->pdata->setpower) {
+               host->powerup_msecs = host->pdata->powerup_msecs;
+               if (!host->powerup_msecs || host->powerup_msecs > 250)
+                       host->powerup_msecs = 250;
+       }
+
+       dev_set_drvdata(&spi->dev, mmc);
+
+       /* preallocate dma buffers */
+       host->data = kmalloc(sizeof(*host->data), GFP_KERNEL);
+       if (!host->data)
+               goto fail_nobuf1;
+
+       if (spi->master->cdev.dev->dma_mask) {
+               struct device   *dev = spi->master->cdev.dev;
+
+               host->dma_dev = dev;
+               host->ones_dma = dma_map_single(dev, ones,
+                               MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
+               host->data_dma = dma_map_single(dev, host->data,
+                               sizeof(*host->data), DMA_BIDIRECTIONAL);
+
+               /* REVISIT in theory those map operations can fail... */
+
+               dma_sync_single_for_cpu(host->dma_dev,
+                               host->data_dma, sizeof(*host->data),
+                               DMA_BIDIRECTIONAL);
+       }
+
+       /* setup message for status/busy readback */
+       spi_message_init(&host->readback);
+       host->readback.is_dma_mapped = (host->dma_dev != NULL);
+
+       spi_message_add_tail(&host->status, &host->readback);
+       host->status.tx_buf = host->ones;
+       host->status.tx_dma = host->ones_dma;
+       host->status.rx_buf = &host->data->status;
+       host->status.rx_dma = host->data_dma + offsetof(struct scratch, status);
+       host->status.cs_change = 1;
+
+       /* register card detect irq */
+       if (host->pdata && host->pdata->init) {
+               status = host->pdata->init(&spi->dev, mmc_spi_detect_irq, mmc);
+               if (status != 0)
+                       goto fail_glue_init;
+       }
+
+       status = mmc_add_host(mmc);
+       if (status != 0)
+               goto fail_add_host;
+
+       dev_info(&spi->dev, "SD/MMC host %s%s%s%s\n",
+                       mmc->class_dev.bus_id,
+                       host->dma_dev ? "" : ", no DMA",
+                       (host->pdata && host->pdata->get_ro)
+                               ? "" : ", no WP",
+                       (host->pdata && host->pdata->setpower)
+                               ? "" : ", no poweroff");
+       return 0;
+
+fail_add_host:
+       mmc_remove_host (mmc);
+fail_glue_init:
+       if (host->dma_dev)
+               dma_unmap_single(host->dma_dev, host->data_dma,
+                               sizeof(*host->data), DMA_BIDIRECTIONAL);
+       kfree(host->data);
+
+fail_nobuf1:
+       mmc_free_host(mmc);
+       dev_set_drvdata(&spi->dev, NULL);
+
+nomem:
+       kfree(ones);
+       return status;
+}
+
+
+static int __devexit mmc_spi_remove(struct spi_device *spi)
+{
+       struct mmc_host         *mmc = dev_get_drvdata(&spi->dev);
+       struct mmc_spi_host     *host;
+
+       if (mmc) {
+               host = mmc_priv(mmc);
+
+               /* prevent new mmc_detect_change() calls */
+               if (host->pdata && host->pdata->exit)
+                       host->pdata->exit(&spi->dev, mmc);
+
+               mmc_remove_host(mmc);
+
+               if (host->dma_dev) {
+                       dma_unmap_single(host->dma_dev, host->ones_dma,
+                               MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
+                       dma_unmap_single(host->dma_dev, host->data_dma,
+                               sizeof(*host->data), DMA_BIDIRECTIONAL);
+               }
+
+               kfree(host->data);
+               kfree(host->ones);
+
+               spi->max_speed_hz = mmc->f_max;
+               mmc_free_host(mmc);
+               dev_set_drvdata(&spi->dev, NULL);
+       }
+       return 0;
+}
+
+
+static struct spi_driver mmc_spi_driver = {
+       .driver = {
+               .name =         "mmc_spi",
+               .bus =          &spi_bus_type,
+               .owner =        THIS_MODULE,
+       },
+       .probe =        mmc_spi_probe,
+       .remove =       __devexit_p(mmc_spi_remove),
+};
+
+
+static int __init mmc_spi_init(void)
+{
+       return spi_register_driver(&mmc_spi_driver);
+}
+module_init(mmc_spi_init);
+
+
+static void __exit mmc_spi_exit(void)
+{
+       spi_unregister_driver(&mmc_spi_driver);
+}
+module_exit(mmc_spi_exit);
+
+
+MODULE_AUTHOR("Mike Lavender, David Brownell, "
+               "Hans-Peter Nilsson, Jan Nikitenko");
+MODULE_DESCRIPTION("SPI SD/MMC host driver");
+MODULE_LICENSE("GPL");
index be730c0a0352a6f942fb001ad8866b42ab84d666..d0eb0a2abf4dd272484949e5a0a14c27a681d143 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/highmem.h>
+#include <linux/log2.h>
 #include <linux/mmc/host.h>
 #include <linux/amba/bus.h>
 #include <linux/clk.h>
@@ -154,11 +155,11 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
        }
        if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
                if (status & MCI_DATACRCFAIL)
-                       data->error = MMC_ERR_BADCRC;
+                       data->error = -EILSEQ;
                else if (status & MCI_DATATIMEOUT)
-                       data->error = MMC_ERR_TIMEOUT;
+                       data->error = -ETIMEDOUT;
                else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
-                       data->error = MMC_ERR_FIFO;
+                       data->error = -EIO;
                status |= MCI_DATAEND;
 
                /*
@@ -193,12 +194,12 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
        cmd->resp[3] = readl(base + MMCIRESPONSE3);
 
        if (status & MCI_CMDTIMEOUT) {
-               cmd->error = MMC_ERR_TIMEOUT;
+               cmd->error = -ETIMEDOUT;
        } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) {
-               cmd->error = MMC_ERR_BADCRC;
+               cmd->error = -EILSEQ;
        }
 
-       if (!cmd->data || cmd->error != MMC_ERR_NONE) {
+       if (!cmd->data || cmd->error) {
                if (host->data)
                        mmci_stop_data(host);
                mmci_request_end(host, cmd->mrq);
@@ -391,6 +392,14 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
        WARN_ON(host->mrq != NULL);
 
+       if (mrq->data && !is_power_of_2(mrq->data->blksz)) {
+               printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n",
+                       mmc_hostname(mmc), mrq->data->blksz);
+               mrq->cmd->error = -EINVAL;
+               mmc_request_done(mmc, mrq);
+               return;
+       }
+
        spin_lock_irq(&host->lock);
 
        host->mrq = mrq;
index 0cf97edc5f58f978437f49da8cb1323c3599bc41..60a67dfcda6a86a0d786c33799124981f19f49db 100644 (file)
@@ -263,7 +263,7 @@ mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
                enum dma_data_direction dma_data_dir;
 
                BUG_ON(host->dma_ch < 0);
-               if (data->error != MMC_ERR_NONE)
+               if (data->error)
                        omap_stop_dma(host->dma_ch);
                /* Release DMA channel lazily */
                mod_timer(&host->dma_timer, jiffies + HZ);
@@ -368,7 +368,7 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
                }
        }
 
-       if (host->data == NULL || cmd->error != MMC_ERR_NONE) {
+       if (host->data == NULL || cmd->error) {
                host->mrq = NULL;
                clk_disable(host->fclk);
                mmc_request_done(host->mmc, cmd->mrq);
@@ -475,14 +475,14 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
                if (status & OMAP_MMC_STAT_DATA_TOUT) {
                        dev_dbg(mmc_dev(host->mmc), "data timeout\n");
                        if (host->data) {
-                               host->data->error |= MMC_ERR_TIMEOUT;
+                               host->data->error = -ETIMEDOUT;
                                transfer_error = 1;
                        }
                }
 
                if (status & OMAP_MMC_STAT_DATA_CRC) {
                        if (host->data) {
-                               host->data->error |= MMC_ERR_BADCRC;
+                               host->data->error = -EILSEQ;
                                dev_dbg(mmc_dev(host->mmc),
                                         "data CRC error, bytes left %d\n",
                                        host->total_bytes_left);
@@ -504,7 +504,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
                                        dev_err(mmc_dev(host->mmc),
                                                "command timeout, CMD %d\n",
                                                host->cmd->opcode);
-                               host->cmd->error = MMC_ERR_TIMEOUT;
+                               host->cmd->error = -ETIMEDOUT;
                                end_command = 1;
                        }
                }
@@ -514,7 +514,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
                                dev_err(mmc_dev(host->mmc),
                                        "command CRC error (CMD%d, arg 0x%08x)\n",
                                        host->cmd->opcode, host->cmd->arg);
-                               host->cmd->error = MMC_ERR_BADCRC;
+                               host->cmd->error = -EILSEQ;
                                end_command = 1;
                        } else
                                dev_err(mmc_dev(host->mmc),
index ff960334b337d814e72bd1fc5446d80aa4294ea0..657901eecfced1b6222d2f772a81415a5b836eaa 100644 (file)
@@ -142,6 +142,10 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
                                   host->dma_dir);
 
        for (i = 0; i < host->dma_len; i++) {
+               unsigned int length = sg_dma_len(&data->sg[i]);
+               host->sg_cpu[i].dcmd = dcmd | length;
+               if (length & 31 && !(data->flags & MMC_DATA_READ))
+                       host->sg_cpu[i].dcmd |= DCMD_ENDIRQEN;
                if (data->flags & MMC_DATA_READ) {
                        host->sg_cpu[i].dsadr = host->res->start + MMC_RXFIFO;
                        host->sg_cpu[i].dtadr = sg_dma_address(&data->sg[i]);
@@ -149,7 +153,6 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
                        host->sg_cpu[i].dsadr = sg_dma_address(&data->sg[i]);
                        host->sg_cpu[i].dtadr = host->res->start + MMC_TXFIFO;
                }
-               host->sg_cpu[i].dcmd = dcmd | sg_dma_len(&data->sg[i]);
                host->sg_cpu[i].ddadr = host->sg_dma + (i + 1) *
                                        sizeof(struct pxa_dma_desc);
        }
@@ -226,7 +229,7 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
        }
 
        if (stat & STAT_TIME_OUT_RESPONSE) {
-               cmd->error = MMC_ERR_TIMEOUT;
+               cmd->error = -ETIMEDOUT;
        } else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
 #ifdef CONFIG_PXA27x
                /*
@@ -239,11 +242,11 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
                        pr_debug("ignoring CRC from command %d - *risky*\n", cmd->opcode);
                } else
 #endif
-               cmd->error = MMC_ERR_BADCRC;
+               cmd->error = -EILSEQ;
        }
 
        pxamci_disable_irq(host, END_CMD_RES);
-       if (host->data && cmd->error == MMC_ERR_NONE) {
+       if (host->data && !cmd->error) {
                pxamci_enable_irq(host, DATA_TRAN_DONE);
        } else {
                pxamci_finish_request(host, host->mrq);
@@ -264,9 +267,9 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat)
                     host->dma_dir);
 
        if (stat & STAT_READ_TIME_OUT)
-               data->error = MMC_ERR_TIMEOUT;
+               data->error = -ETIMEDOUT;
        else if (stat & (STAT_CRC_READ_ERROR|STAT_CRC_WRITE_ERROR))
-               data->error = MMC_ERR_BADCRC;
+               data->error = -EILSEQ;
 
        /*
         * There appears to be a hardware design bug here.  There seems to
@@ -274,7 +277,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat)
         * This means that if there was an error on any block, we mark all
         * data blocks as being in error.
         */
-       if (data->error == MMC_ERR_NONE)
+       if (!data->error)
                data->bytes_xfered = data->blocks * data->blksz;
        else
                data->bytes_xfered = 0;
@@ -284,7 +287,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat)
        host->data = NULL;
        if (host->mrq->stop) {
                pxamci_stop_clock(host);
-               pxamci_start_cmd(host, host->mrq->stop, 0);
+               pxamci_start_cmd(host, host->mrq->stop, host->cmdat);
        } else {
                pxamci_finish_request(host, host->mrq);
        }
@@ -298,7 +301,7 @@ static irqreturn_t pxamci_irq(int irq, void *devid)
        unsigned int ireg;
        int handled = 0;
 
-       ireg = readl(host->base + MMC_I_REG);
+       ireg = readl(host->base + MMC_I_REG) & ~readl(host->base + MMC_I_MASK);
 
        if (ireg) {
                unsigned stat = readl(host->base + MMC_STAT);
@@ -309,6 +312,10 @@ static irqreturn_t pxamci_irq(int irq, void *devid)
                        handled |= pxamci_cmd_done(host, stat);
                if (ireg & DATA_TRAN_DONE)
                        handled |= pxamci_data_done(host, stat);
+               if (ireg & SDIO_INT) {
+                       mmc_signal_sdio_irq(host->mmc);
+                       handled = 1;
+               }
        }
 
        return IRQ_RETVAL(handled);
@@ -382,20 +389,46 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                        host->cmdat |= CMDAT_INIT;
        }
 
+       if (ios->bus_width == MMC_BUS_WIDTH_4)
+               host->cmdat |= CMDAT_SD_4DAT;
+       else
+               host->cmdat &= ~CMDAT_SD_4DAT;
+
        pr_debug("PXAMCI: clkrt = %x cmdat = %x\n",
                 host->clkrt, host->cmdat);
 }
 
+static void pxamci_enable_sdio_irq(struct mmc_host *host, int enable)
+{
+       struct pxamci_host *pxa_host = mmc_priv(host);
+
+       if (enable)
+               pxamci_enable_irq(pxa_host, SDIO_INT);
+       else
+               pxamci_disable_irq(pxa_host, SDIO_INT);
+}
+
 static const struct mmc_host_ops pxamci_ops = {
-       .request        = pxamci_request,
-       .get_ro         = pxamci_get_ro,
-       .set_ios        = pxamci_set_ios,
+       .request                = pxamci_request,
+       .get_ro                 = pxamci_get_ro,
+       .set_ios                = pxamci_set_ios,
+       .enable_sdio_irq        = pxamci_enable_sdio_irq,
 };
 
 static void pxamci_dma_irq(int dma, void *devid)
 {
-       printk(KERN_ERR "DMA%d: IRQ???\n", dma);
-       DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+       struct pxamci_host *host = devid;
+       int dcsr = DCSR(dma);
+       DCSR(dma) = dcsr & ~DCSR_STOPIRQEN;
+
+       if (dcsr & DCSR_ENDINTR) {
+               writel(BUF_PART_FULL, host->base + MMC_PRTBUF);
+       } else {
+               printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
+                      mmc_hostname(host->mmc), dma, dcsr);
+               host->data->error = -EIO;
+               pxamci_data_done(host, 0);
+       }
 }
 
 static irqreturn_t pxamci_detect_irq(int irq, void *devid)
@@ -444,9 +477,9 @@ static int pxamci_probe(struct platform_device *pdev)
        mmc->max_seg_size = PAGE_SIZE;
 
        /*
-        * Block length register is 10 bits.
+        * Block length register is only 10 bits before PXA27x.
         */
-       mmc->max_blk_size = 1023;
+       mmc->max_blk_size = (cpu_is_pxa21x() || cpu_is_pxa25x()) ? 1023 : 2048;
 
        /*
         * Block count register is 16 bits.
@@ -460,6 +493,12 @@ static int pxamci_probe(struct platform_device *pdev)
        mmc->ocr_avail = host->pdata ?
                         host->pdata->ocr_mask :
                         MMC_VDD_32_33|MMC_VDD_33_34;
+       mmc->caps = 0;
+       host->cmdat = 0;
+       if (!cpu_is_pxa21x() && !cpu_is_pxa25x()) {
+               mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+               host->cmdat |= CMDAT_SDIO_INT_EN;
+       }
 
        host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
        if (!host->sg_cpu) {
index df17c281278a68d272a21756b1be5eb1f1d9c82f..3153e779d46a9edbd481249871d2779cf988e432 100644 (file)
@@ -25,6 +25,8 @@
 #define SPI_EN                 (1 << 0)
 
 #define MMC_CMDAT      0x0010
+#define CMDAT_SDIO_INT_EN      (1 << 11)
+#define CMDAT_SD_4DAT          (1 << 8)
 #define CMDAT_DMAEN            (1 << 7)
 #define CMDAT_INIT             (1 << 6)
 #define CMDAT_BUSY             (1 << 5)
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c
new file mode 100644 (file)
index 0000000..1e87045
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ *  ricoh_mmc.c - Dummy driver to disable the Rioch MMC controller.
+ *
+ *  Copyright (C) 2007 Philip Langdale, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+/*
+ * This is a conceptually ridiculous driver, but it is required by the way
+ * the Ricoh multi-function R5C832 works. This chip implements firewire
+ * and four different memory card controllers. Two of those controllers are
+ * an SDHCI controller and a proprietary MMC controller. The linux SDHCI
+ * driver supports MMC cards but the chip detects MMC cards in hardware
+ * and directs them to the MMC controller - so the SDHCI driver never sees
+ * them. To get around this, we must disable the useless MMC controller.
+ * At that point, the SDHCI controller will start seeing them. As a bonus,
+ * a detection event occurs immediately, even if the MMC card is already
+ * in the reader.
+ *
+ * The relevant registers live on the firewire function, so this is unavoidably
+ * ugly. Such is life.
+ */
+
+#include <linux/pci.h>
+
+#define DRIVER_NAME "ricoh-mmc"
+
+static const struct pci_device_id pci_ids[] __devinitdata = {
+       {
+               .vendor         = PCI_VENDOR_ID_RICOH,
+               .device         = PCI_DEVICE_ID_RICOH_R5C843,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+       },
+       { /* end: all zeroes */ },
+};
+
+MODULE_DEVICE_TABLE(pci, pci_ids);
+
+static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
+                                    const struct pci_device_id *ent)
+{
+       u8 rev;
+
+       struct pci_dev *fw_dev = NULL;
+
+       BUG_ON(pdev == NULL);
+       BUG_ON(ent == NULL);
+
+       pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev);
+
+       printk(KERN_INFO DRIVER_NAME
+               ": Ricoh MMC controller found at %s [%04x:%04x] (rev %x)\n",
+               pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
+               (int)rev);
+
+       while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {
+               if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
+                   pdev->bus == fw_dev->bus) {
+                       u8 write_enable;
+                       u8 disable;
+
+                       pci_read_config_byte(fw_dev, 0xCB, &disable);
+                       if (disable & 0x02) {
+                               printk(KERN_INFO DRIVER_NAME
+                                      ": Controller already disabled. Nothing to do.\n");
+                               return -ENODEV;
+                       }
+
+                       pci_read_config_byte(fw_dev, 0xCA, &write_enable);
+                       pci_write_config_byte(fw_dev, 0xCA, 0x57);
+                       pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
+                       pci_write_config_byte(fw_dev, 0xCA, write_enable);
+
+                       pci_set_drvdata(pdev, fw_dev);
+
+                       printk(KERN_INFO DRIVER_NAME
+                              ": Controller is now disabled.\n");
+
+                       break;
+               }
+       }
+
+       if (pci_get_drvdata(pdev) == NULL) {
+               printk(KERN_WARNING DRIVER_NAME
+                      ": Main firewire function not found. Cannot disable controller.\n");
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
+{
+       u8 write_enable;
+       u8 disable;
+       struct pci_dev *fw_dev = NULL;
+
+       fw_dev = pci_get_drvdata(pdev);
+       BUG_ON(fw_dev == NULL);
+
+       pci_read_config_byte(fw_dev, 0xCA, &write_enable);
+       pci_read_config_byte(fw_dev, 0xCB, &disable);
+       pci_write_config_byte(fw_dev, 0xCA, 0x57);
+       pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
+       pci_write_config_byte(fw_dev, 0xCA, write_enable);
+
+       printk(KERN_INFO DRIVER_NAME
+              ": Controller is now re-enabled.\n");
+
+       pci_set_drvdata(pdev, NULL);
+}
+
+static struct pci_driver ricoh_mmc_driver = {
+       .name =         DRIVER_NAME,
+       .id_table =     pci_ids,
+       .probe =        ricoh_mmc_probe,
+       .remove =       __devexit_p(ricoh_mmc_remove),
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Driver init/exit                                                          *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __init ricoh_mmc_drv_init(void)
+{
+       printk(KERN_INFO DRIVER_NAME
+               ": Ricoh MMC Controller disabling driver\n");
+       printk(KERN_INFO DRIVER_NAME ": Copyright(c) Philip Langdale\n");
+
+       return pci_register_driver(&ricoh_mmc_driver);
+}
+
+static void __exit ricoh_mmc_drv_exit(void)
+{
+       pci_unregister_driver(&ricoh_mmc_driver);
+}
+
+module_init(ricoh_mmc_drv_init);
+module_exit(ricoh_mmc_drv_exit);
+
+MODULE_AUTHOR("Philip Langdale <philipl@alumni.utexas.net>");
+MODULE_DESCRIPTION("Ricoh MMC Controller disabling driver");
+MODULE_LICENSE("GPL");
+
index 20a7d89e01bac08032fa874ecc081fc7a44a322d..b397121b947d5acf78b764c06c486a30a8fe1797 100644 (file)
@@ -25,8 +25,6 @@
 #define DBG(f, x...) \
        pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
 
-static unsigned int debug_nodma = 0;
-static unsigned int debug_forcedma = 0;
 static unsigned int debug_quirks = 0;
 
 #define SDHCI_QUIRK_CLOCK_BEFORE_RESET                 (1<<0)
@@ -35,6 +33,7 @@ static unsigned int debug_quirks = 0;
 #define SDHCI_QUIRK_NO_CARD_NO_RESET                   (1<<2)
 #define SDHCI_QUIRK_SINGLE_POWER_WRITE                 (1<<3)
 #define SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS              (1<<4)
+#define SDHCI_QUIRK_BROKEN_DMA                         (1<<5)
 
 static const struct pci_device_id pci_ids[] __devinitdata = {
        {
@@ -68,7 +67,8 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
                .device         = PCI_DEVICE_ID_ENE_CB712_SD,
                .subvendor      = PCI_ANY_ID,
                .subdevice      = PCI_ANY_ID,
-               .driver_data    = SDHCI_QUIRK_SINGLE_POWER_WRITE,
+               .driver_data    = SDHCI_QUIRK_SINGLE_POWER_WRITE |
+                                 SDHCI_QUIRK_BROKEN_DMA,
        },
 
        {
@@ -76,7 +76,8 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
                .device         = PCI_DEVICE_ID_ENE_CB712_SD_2,
                .subvendor      = PCI_ANY_ID,
                .subdevice      = PCI_ANY_ID,
-               .driver_data    = SDHCI_QUIRK_SINGLE_POWER_WRITE,
+               .driver_data    = SDHCI_QUIRK_SINGLE_POWER_WRITE |
+                                 SDHCI_QUIRK_BROKEN_DMA,
        },
 
        {
@@ -132,7 +133,7 @@ static void sdhci_dumpregs(struct sdhci_host *host)
                readb(host->ioaddr + SDHCI_POWER_CONTROL),
                readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
        printk(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
-               readb(host->ioaddr + SDHCI_WALK_UP_CONTROL),
+               readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL),
                readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
        printk(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
                readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
@@ -481,16 +482,16 @@ static void sdhci_finish_data(struct sdhci_host *host)
         * Controller doesn't count down when in single block mode.
         */
        if (data->blocks == 1)
-               blocks = (data->error == MMC_ERR_NONE) ? 0 : 1;
+               blocks = (data->error == 0) ? 0 : 1;
        else
                blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT);
        data->bytes_xfered = data->blksz * (data->blocks - blocks);
 
-       if ((data->error == MMC_ERR_NONE) && blocks) {
+       if (!data->error && blocks) {
                printk(KERN_ERR "%s: Controller signalled completion even "
                        "though there were blocks left.\n",
                        mmc_hostname(host->mmc));
-               data->error = MMC_ERR_FAILED;
+               data->error = -EIO;
        }
 
        if (data->stop) {
@@ -498,7 +499,7 @@ static void sdhci_finish_data(struct sdhci_host *host)
                 * The controller needs a reset of internal state machines
                 * upon error conditions.
                 */
-               if (data->error != MMC_ERR_NONE) {
+               if (data->error) {
                        sdhci_reset(host, SDHCI_RESET_CMD);
                        sdhci_reset(host, SDHCI_RESET_DATA);
                }
@@ -533,7 +534,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
                        printk(KERN_ERR "%s: Controller never released "
                                "inhibit bit(s).\n", mmc_hostname(host->mmc));
                        sdhci_dumpregs(host);
-                       cmd->error = MMC_ERR_FAILED;
+                       cmd->error = -EIO;
                        tasklet_schedule(&host->finish_tasklet);
                        return;
                }
@@ -554,7 +555,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
        if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
                printk(KERN_ERR "%s: Unsupported response type!\n",
                        mmc_hostname(host->mmc));
-               cmd->error = MMC_ERR_INVALID;
+               cmd->error = -EINVAL;
                tasklet_schedule(&host->finish_tasklet);
                return;
        }
@@ -601,7 +602,7 @@ static void sdhci_finish_command(struct sdhci_host *host)
                }
        }
 
-       host->cmd->error = MMC_ERR_NONE;
+       host->cmd->error = 0;
 
        if (host->data && host->data_early)
                sdhci_finish_data(host);
@@ -722,7 +723,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
        host->mrq = mrq;
 
        if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
-               host->mrq->cmd->error = MMC_ERR_TIMEOUT;
+               host->mrq->cmd->error = -ENOMEDIUM;
                tasklet_schedule(&host->finish_tasklet);
        } else
                sdhci_send_command(host, mrq->cmd);
@@ -800,10 +801,35 @@ static int sdhci_get_ro(struct mmc_host *mmc)
        return !(present & SDHCI_WRITE_PROTECT);
 }
 
+static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+       struct sdhci_host *host;
+       unsigned long flags;
+       u32 ier;
+
+       host = mmc_priv(mmc);
+
+       spin_lock_irqsave(&host->lock, flags);
+
+       ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
+
+       ier &= ~SDHCI_INT_CARD_INT;
+       if (enable)
+               ier |= SDHCI_INT_CARD_INT;
+
+       writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
+       writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+
+       mmiowb();
+
+       spin_unlock_irqrestore(&host->lock, flags);
+}
+
 static const struct mmc_host_ops sdhci_ops = {
        .request        = sdhci_request,
        .set_ios        = sdhci_set_ios,
        .get_ro         = sdhci_get_ro,
+       .enable_sdio_irq = sdhci_enable_sdio_irq,
 };
 
 /*****************************************************************************\
@@ -831,7 +857,7 @@ static void sdhci_tasklet_card(unsigned long param)
                        sdhci_reset(host, SDHCI_RESET_CMD);
                        sdhci_reset(host, SDHCI_RESET_DATA);
 
-                       host->mrq->cmd->error = MMC_ERR_FAILED;
+                       host->mrq->cmd->error = -ENOMEDIUM;
                        tasklet_schedule(&host->finish_tasklet);
                }
        }
@@ -859,9 +885,9 @@ static void sdhci_tasklet_finish(unsigned long param)
         * The controller needs a reset of internal state machines
         * upon error conditions.
         */
-       if ((mrq->cmd->error != MMC_ERR_NONE) ||
-               (mrq->data && ((mrq->data->error != MMC_ERR_NONE) ||
-               (mrq->data->stop && (mrq->data->stop->error != MMC_ERR_NONE))))) {
+       if (mrq->cmd->error ||
+               (mrq->data && (mrq->data->error ||
+               (mrq->data->stop && mrq->data->stop->error)))) {
 
                /* Some controllers need this kick or reset won't work here */
                if (host->chip->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) {
@@ -906,13 +932,13 @@ static void sdhci_timeout_timer(unsigned long data)
                sdhci_dumpregs(host);
 
                if (host->data) {
-                       host->data->error = MMC_ERR_TIMEOUT;
+                       host->data->error = -ETIMEDOUT;
                        sdhci_finish_data(host);
                } else {
                        if (host->cmd)
-                               host->cmd->error = MMC_ERR_TIMEOUT;
+                               host->cmd->error = -ETIMEDOUT;
                        else
-                               host->mrq->cmd->error = MMC_ERR_TIMEOUT;
+                               host->mrq->cmd->error = -ETIMEDOUT;
 
                        tasklet_schedule(&host->finish_tasklet);
                }
@@ -941,13 +967,12 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
        }
 
        if (intmask & SDHCI_INT_TIMEOUT)
-               host->cmd->error = MMC_ERR_TIMEOUT;
-       else if (intmask & SDHCI_INT_CRC)
-               host->cmd->error = MMC_ERR_BADCRC;
-       else if (intmask & (SDHCI_INT_END_BIT | SDHCI_INT_INDEX))
-               host->cmd->error = MMC_ERR_FAILED;
+               host->cmd->error = -ETIMEDOUT;
+       else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
+                       SDHCI_INT_INDEX))
+               host->cmd->error = -EILSEQ;
 
-       if (host->cmd->error != MMC_ERR_NONE)
+       if (host->cmd->error)
                tasklet_schedule(&host->finish_tasklet);
        else if (intmask & SDHCI_INT_RESPONSE)
                sdhci_finish_command(host);
@@ -974,13 +999,11 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
        }
 
        if (intmask & SDHCI_INT_DATA_TIMEOUT)
-               host->data->error = MMC_ERR_TIMEOUT;
-       else if (intmask & SDHCI_INT_DATA_CRC)
-               host->data->error = MMC_ERR_BADCRC;
-       else if (intmask & SDHCI_INT_DATA_END_BIT)
-               host->data->error = MMC_ERR_FAILED;
+               host->data->error = -ETIMEDOUT;
+       else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT))
+               host->data->error = -EILSEQ;
 
-       if (host->data->error != MMC_ERR_NONE)
+       if (host->data->error)
                sdhci_finish_data(host);
        else {
                if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
@@ -1015,6 +1038,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
        irqreturn_t result;
        struct sdhci_host* host = dev_id;
        u32 intmask;
+       int cardint = 0;
 
        spin_lock(&host->lock);
 
@@ -1059,6 +1083,11 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 
        intmask &= ~SDHCI_INT_BUS_POWER;
 
+       if (intmask & SDHCI_INT_CARD_INT)
+               cardint = 1;
+
+       intmask &= ~SDHCI_INT_CARD_INT;
+
        if (intmask) {
                printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
                        mmc_hostname(host->mmc), intmask);
@@ -1073,6 +1102,12 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 out:
        spin_unlock(&host->lock);
 
+       /*
+        * We have to delay this as it calls back into the driver.
+        */
+       if (cardint)
+               mmc_signal_sdio_irq(host->mmc);
+
        return result;
 }
 
@@ -1258,20 +1293,26 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
 
        caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
 
-       if (debug_nodma)
-               DBG("DMA forced off\n");
-       else if (debug_forcedma) {
-               DBG("DMA forced on\n");
-               host->flags |= SDHCI_USE_DMA;
-       } else if (chip->quirks & SDHCI_QUIRK_FORCE_DMA)
+       if (chip->quirks & SDHCI_QUIRK_FORCE_DMA)
                host->flags |= SDHCI_USE_DMA;
-       else if ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA)
-               DBG("Controller doesn't have DMA interface\n");
        else if (!(caps & SDHCI_CAN_DO_DMA))
                DBG("Controller doesn't have DMA capability\n");
        else
                host->flags |= SDHCI_USE_DMA;
 
+       if ((chip->quirks & SDHCI_QUIRK_BROKEN_DMA) &&
+               (host->flags & SDHCI_USE_DMA)) {
+               DBG("Disabling DMA as it is marked broken");
+               host->flags &= ~SDHCI_USE_DMA;
+       }
+
+       if (((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) &&
+               (host->flags & SDHCI_USE_DMA)) {
+               printk(KERN_WARNING "%s: Will use DMA "
+                       "mode even though HW doesn't fully "
+                       "claim to support it.\n", host->slot_descr);
+       }
+
        if (host->flags & SDHCI_USE_DMA) {
                if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
                        printk(KERN_WARNING "%s: No suitable DMA available. "
@@ -1312,7 +1353,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
        mmc->ops = &sdhci_ops;
        mmc->f_min = host->max_clk / 256;
        mmc->f_max = host->max_clk;
-       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
+       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_SDIO_IRQ;
 
        if (caps & SDHCI_CAN_DO_HISPD)
                mmc->caps |= MMC_CAP_SD_HIGHSPEED;
@@ -1565,14 +1606,10 @@ static void __exit sdhci_drv_exit(void)
 module_init(sdhci_drv_init);
 module_exit(sdhci_drv_exit);
 
-module_param(debug_nodma, uint, 0444);
-module_param(debug_forcedma, uint, 0444);
 module_param(debug_quirks, uint, 0444);
 
 MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
 MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM_DESC(debug_nodma, "Forcefully disable DMA transfers. (default 0)");
-MODULE_PARM_DESC(debug_forcedma, "Forcefully enable DMA transfers. (default 0)");
 MODULE_PARM_DESC(debug_quirks, "Force certain quirks.");
index e28987d6d2ebf4f12d9ea180916d811571fc63e2..05195ea900f490e1884a72de5a3d4081e61f38b5 100644 (file)
@@ -81,7 +81,7 @@
 
 #define SDHCI_BLOCK_GAP_CONTROL        0x2A
 
-#define SDHCI_WALK_UP_CONTROL  0x2B
+#define SDHCI_WAKE_UP_CONTROL  0x2B
 
 #define SDHCI_CLOCK_CONTROL    0x2C
 #define  SDHCI_DIVIDER_SHIFT   8
index 8b736e9684477236604e54932f1cf788a90db858..9b904795eb77acd5cb887dbbbf96dec51a742339 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mmc/host.h>
 #include <linux/highmem.h>
 #include <linux/scatterlist.h>
+#include <linux/log2.h>
 #include <asm/io.h>
 
 #define DRIVER_NAME "tifm_sd"
@@ -404,14 +405,14 @@ static void tifm_sd_check_status(struct tifm_sd *host)
        struct tifm_dev *sock = host->dev;
        struct mmc_command *cmd = host->req->cmd;
 
-       if (cmd->error != MMC_ERR_NONE)
+       if (cmd->error)
                goto finish_request;
 
        if (!(host->cmd_flags & CMD_READY))
                return;
 
        if (cmd->data) {
-               if (cmd->data->error != MMC_ERR_NONE) {
+               if (cmd->data->error) {
                        if ((host->cmd_flags & SCMD_ACTIVE)
                            && !(host->cmd_flags & SCMD_READY))
                                return;
@@ -504,7 +505,7 @@ static void tifm_sd_card_event(struct tifm_dev *sock)
 {
        struct tifm_sd *host;
        unsigned int host_status = 0;
-       int cmd_error = MMC_ERR_NONE;
+       int cmd_error = 0;
        struct mmc_command *cmd = NULL;
        unsigned long flags;
 
@@ -521,15 +522,15 @@ static void tifm_sd_card_event(struct tifm_dev *sock)
                        writel(host_status & TIFM_MMCSD_ERRMASK,
                               sock->addr + SOCK_MMCSD_STATUS);
                        if (host_status & TIFM_MMCSD_CTO)
-                               cmd_error = MMC_ERR_TIMEOUT;
+                               cmd_error = -ETIMEDOUT;
                        else if (host_status & TIFM_MMCSD_CCRC)
-                               cmd_error = MMC_ERR_BADCRC;
+                               cmd_error = -EILSEQ;
 
                        if (cmd->data) {
                                if (host_status & TIFM_MMCSD_DTO)
-                                       cmd->data->error = MMC_ERR_TIMEOUT;
+                                       cmd->data->error = -ETIMEDOUT;
                                else if (host_status & TIFM_MMCSD_DCRC)
-                                       cmd->data->error = MMC_ERR_BADCRC;
+                                       cmd->data->error = -EILSEQ;
                        }
 
                        writel(TIFM_FIFO_INT_SETALL,
@@ -626,14 +627,21 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
        spin_lock_irqsave(&sock->lock, flags);
        if (host->eject) {
-               spin_unlock_irqrestore(&sock->lock, flags);
+               mrq->cmd->error = -ENOMEDIUM;
                goto err_out;
        }
 
        if (host->req) {
                printk(KERN_ERR "%s : unfinished request detected\n",
                       sock->dev.bus_id);
-               spin_unlock_irqrestore(&sock->lock, flags);
+               mrq->cmd->error = -ETIMEDOUT;
+               goto err_out;
+       }
+
+       if (mrq->data && !is_power_of_2(mrq->data->blksz)) {
+               printk(KERN_ERR "%s: Unsupported block size (%d bytes)\n",
+                       sock->dev.bus_id, mrq->data->blksz);
+               mrq->cmd->error = -EINVAL;
                goto err_out;
        }
 
@@ -722,7 +730,7 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
        return;
 
 err_out:
-       mrq->cmd->error = MMC_ERR_TIMEOUT;
+       spin_unlock_irqrestore(&sock->lock, flags);
        mmc_request_done(mmc, mrq);
 }
 
@@ -1012,9 +1020,9 @@ static void tifm_sd_remove(struct tifm_dev *sock)
                writel(TIFM_FIFO_INT_SETALL,
                       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
                writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
-               host->req->cmd->error = MMC_ERR_TIMEOUT;
+               host->req->cmd->error = -ENOMEDIUM;
                if (host->req->stop)
-                       host->req->stop->error = MMC_ERR_TIMEOUT;
+                       host->req->stop->error = -ENOMEDIUM;
                tasklet_schedule(&host->finish_tasklet);
        }
        spin_unlock_irqrestore(&sock->lock, flags);
index 9bf2a877113bf0a55cf8bc21904158990c24ca39..80db11c05f2a6e91ab155d9036338448dad2f44f 100644 (file)
@@ -317,7 +317,7 @@ static inline void wbsd_get_short_reply(struct wbsd_host *host,
         * Correct response type?
         */
        if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT) {
-               cmd->error = MMC_ERR_INVALID;
+               cmd->error = -EILSEQ;
                return;
        }
 
@@ -337,7 +337,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host *host,
         * Correct response type?
         */
        if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG) {
-               cmd->error = MMC_ERR_INVALID;
+               cmd->error = -EILSEQ;
                return;
        }
 
@@ -372,7 +372,7 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd)
        for (i = 3; i >= 0; i--)
                outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR);
 
-       cmd->error = MMC_ERR_NONE;
+       cmd->error = 0;
 
        /*
         * Wait for the request to complete.
@@ -392,13 +392,13 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd)
 
                /* Card removed? */
                if (isr & WBSD_INT_CARD)
-                       cmd->error = MMC_ERR_TIMEOUT;
+                       cmd->error = -ENOMEDIUM;
                /* Timeout? */
                else if (isr & WBSD_INT_TIMEOUT)
-                       cmd->error = MMC_ERR_TIMEOUT;
+                       cmd->error = -ETIMEDOUT;
                /* CRC? */
                else if ((cmd->flags & MMC_RSP_CRC) && (isr & WBSD_INT_CRC))
-                       cmd->error = MMC_ERR_BADCRC;
+                       cmd->error = -EILSEQ;
                /* All ok */
                else {
                        if (cmd->flags & MMC_RSP_136)
@@ -585,7 +585,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
                        ((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH);
                wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
        } else {
-               data->error = MMC_ERR_INVALID;
+               data->error = -EINVAL;
                return;
        }
 
@@ -607,7 +607,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
                 */
                BUG_ON(size > 0x10000);
                if (size > 0x10000) {
-                       data->error = MMC_ERR_INVALID;
+                       data->error = -EINVAL;
                        return;
                }
 
@@ -669,7 +669,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
                }
        }
 
-       data->error = MMC_ERR_NONE;
+       data->error = 0;
 }
 
 static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data)
@@ -724,8 +724,8 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data)
                                "%d bytes left.\n",
                                mmc_hostname(host->mmc), count);
 
-                       if (data->error == MMC_ERR_NONE)
-                               data->error = MMC_ERR_FAILED;
+                       if (!data->error)
+                               data->error = -EIO;
                } else {
                        /*
                         * Transfer data from DMA buffer to
@@ -735,7 +735,7 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data)
                                wbsd_dma_to_sg(host, data);
                }
 
-               if (data->error != MMC_ERR_NONE) {
+               if (data->error) {
                        if (data->bytes_xfered)
                                data->bytes_xfered -= data->blksz;
                }
@@ -767,11 +767,10 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
        host->mrq = mrq;
 
        /*
-        * If there is no card in the slot then
-        * timeout immediatly.
+        * Check that there is actually a card in the slot.
         */
        if (!(host->flags & WBSD_FCARD_PRESENT)) {
-               cmd->error = MMC_ERR_TIMEOUT;
+               cmd->error = -ENOMEDIUM;
                goto done;
        }
 
@@ -807,7 +806,7 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
                                "supported by this controller.\n",
                                mmc_hostname(host->mmc), cmd->opcode);
 #endif
-                       cmd->error = MMC_ERR_INVALID;
+                       cmd->error = -EINVAL;
 
                        goto done;
                };
@@ -819,7 +818,7 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
        if (cmd->data) {
                wbsd_prepare_data(host, cmd->data);
 
-               if (cmd->data->error != MMC_ERR_NONE)
+               if (cmd->data->error)
                        goto done;
        }
 
@@ -830,7 +829,7 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
         * will be finished after the data has
         * transfered.
         */
-       if (cmd->data && (cmd->error == MMC_ERR_NONE)) {
+       if (cmd->data && !cmd->error) {
                /*
                 * Dirty fix for hardware bug.
                 */
@@ -1033,7 +1032,7 @@ static void wbsd_tasklet_card(unsigned long param)
                                mmc_hostname(host->mmc));
                        wbsd_reset(host);
 
-                       host->mrq->cmd->error = MMC_ERR_FAILED;
+                       host->mrq->cmd->error = -ENOMEDIUM;
                        tasklet_schedule(&host->finish_tasklet);
                }
 
@@ -1097,7 +1096,7 @@ static void wbsd_tasklet_crc(unsigned long param)
 
        DBGF("CRC error\n");
 
-       data->error = MMC_ERR_BADCRC;
+       data->error = -EILSEQ;
 
        tasklet_schedule(&host->finish_tasklet);
 
@@ -1121,7 +1120,7 @@ static void wbsd_tasklet_timeout(unsigned long param)
 
        DBGF("Timeout\n");
 
-       data->error = MMC_ERR_TIMEOUT;
+       data->error = -ETIMEDOUT;
 
        tasklet_schedule(&host->finish_tasklet);
 
@@ -1220,7 +1219,7 @@ static int __devinit wbsd_alloc_mmc(struct device *dev)
        mmc->f_min = 375000;
        mmc->f_max = 24000000;
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
+       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE;
 
        spin_lock_init(&host->lock);
 
index d590a99930fa5a762f2d327faca4d10ecb7373d3..2305cc450a4572da1d9dc0a57783a500db3a91a0 100644 (file)
@@ -45,7 +45,7 @@
 
 #include "cpqphp.h"
 #include "cpqphp_nvram.h"
-#include "../../../arch/i386/pci/pci.h"        /* horrible hack showing how processor dependent we are... */
+#include "../../../arch/x86/pci/pci.h" /* horrible hack showing how processor dependent we are... */
 
 
 /* Global variables */
index fc7c74d725955794141093e7a41217bd3964dd06..3f6cd20e95d2f187d2caaa9747a0d90f0c77f9b7 100644 (file)
@@ -37,7 +37,7 @@
 #include "../pci.h"
 #include "cpqphp.h"
 #include "cpqphp_nvram.h"
-#include "../../../arch/i386/pci/pci.h"        /* horrible hack showing how processor dependent we are... */
+#include "../../../arch/x86/pci/pci.h" /* horrible hack showing how processor dependent we are... */
 
 
 u8 cpqhp_nic_irq;
index 0316eeaaeb29cb288f45066dbf6e746610db66b1..a90c28d0c69df75c3cb62b2ca19d3073b49839d1 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/delay.h>
 #include <linux/wait.h>
 #include "../pci.h"
-#include "../../../arch/i386/pci/pci.h"        /* for struct irq_routing_table */
+#include "../../../arch/x86/pci/pci.h" /* for struct irq_routing_table */
 #include "ibmphp.h"
 
 #define attn_on(sl)  ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON)
index 66c92bc36f3d1ae51cabbada195a73300dccbf27..6f475b6098643751cf630dd7e26cb3294645182c 100644 (file)
@@ -86,10 +86,8 @@ static void bfin_serial_stop_tx(struct uart_port *port)
 {
        struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
 
-#ifdef CONFIG_BF54x
        while (!(UART_GET_LSR(uart) & TEMT))
                continue;
-#endif
 
 #ifdef CONFIG_SERIAL_BFIN_DMA
        disable_dma(uart->tx_dma_channel);
@@ -128,8 +126,8 @@ static void bfin_serial_start_tx(struct uart_port *port)
        ier = UART_GET_IER(uart);
        ier |= ETBEI;
        UART_PUT_IER(uart, ier);
-       bfin_serial_tx_chars(uart);
 #endif
+       bfin_serial_tx_chars(uart);
 #endif
 }
 
@@ -139,18 +137,21 @@ static void bfin_serial_start_tx(struct uart_port *port)
 static void bfin_serial_stop_rx(struct uart_port *port)
 {
        struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+#ifdef CONFIG_KGDB_UART
+       if (uart->port.line != CONFIG_KGDB_UART_PORT) {
+#endif
 #ifdef CONFIG_BF54x
        UART_CLEAR_IER(uart, ERBFI);
 #else
        unsigned short ier;
 
        ier = UART_GET_IER(uart);
-#ifdef CONFIG_KGDB_UART
-       if (uart->port.line != CONFIG_KGDB_UART_PORT)
-#endif
        ier &= ~ERBFI;
        UART_PUT_IER(uart, ier);
 #endif
+#ifdef CONFIG_KGDB_UART
+       }
+#endif
 }
 
 /*
@@ -173,12 +174,15 @@ void kgdb_put_debug_char(int chr)
                uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
        
        while (!(UART_GET_LSR(uart) & THRE)) {
-               __builtin_bfin_ssync();
+               SSYNC();
        }
+
+#ifndef CONFIG_BF54x
        UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
-       __builtin_bfin_ssync();
+       SSYNC();
+#endif
        UART_PUT_CHAR(uart, (unsigned char)chr);
-       __builtin_bfin_ssync();
+       SSYNC();
 }
 
 int kgdb_get_debug_char(void)
@@ -192,12 +196,14 @@ int kgdb_get_debug_char(void)
                uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
        
        while(!(UART_GET_LSR(uart) & DR)) {
-               __builtin_bfin_ssync();
+               SSYNC();
        }
+#ifndef CONFIG_BF54x
        UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
-       __builtin_bfin_ssync();
+       SSYNC();
+#endif
        chr = UART_GET_CHAR(uart);
-       __builtin_bfin_ssync();
+       SSYNC();
 
        return chr;
 }
@@ -225,12 +231,10 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
 {
        struct tty_struct *tty = uart->port.info->tty;
        unsigned int status, ch, flg;
+       static int in_break = 0;
 #ifdef CONFIG_KGDB_UART
        struct pt_regs *regs = get_irq_regs();
 #endif
-#ifdef BF533_FAMILY
-       static int in_break = 0;
-#endif
 
        status = UART_GET_LSR(uart);
        ch = UART_GET_CHAR(uart);
@@ -256,29 +260,30 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
                }
        }
 #endif
-#ifdef BF533_FAMILY
-       /* The BF533 family of processors have a nice misbehavior where
-        * they continuously generate characters for a "single" break.
-        * We have to basically ignore this flood until the "next" valid
-        * character comes across.  All other Blackfin families operate
-        * properly though.
-        */
-       if (in_break) {
-               if (ch != 0) {
-                       in_break = 0;
-                       ch = UART_GET_CHAR(uart);
-                       if (bfin_revid() < 5)
+
+       if (ANOMALY_05000230) {
+               /* The BF533 family of processors have a nice misbehavior where
+                * they continuously generate characters for a "single" break.
+                * We have to basically ignore this flood until the "next" valid
+                * character comes across.  All other Blackfin families operate
+                * properly though.
+                * Note: While Anomaly 05000230 does not directly address this,
+                *       the changes that went in for it also fixed this issue.
+                */
+               if (in_break) {
+                       if (ch != 0) {
+                               in_break = 0;
+                               ch = UART_GET_CHAR(uart);
+                               if (bfin_revid() < 5)
+                                       return;
+                       } else
                                return;
-               } else
-                       return;
+               }
        }
-#endif
 
        if (status & BI) {
-#ifdef BF533_FAMILY
-               in_break = 1;
-#endif
+               if (ANOMALY_05000230)
+                       in_break = 1;
                uart->port.icount.brk++;
                if (uart_handle_break(&uart->port))
                        goto ignore_char;
@@ -697,17 +702,19 @@ static int bfin_serial_startup(struct uart_port *port)
        uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES;
        add_timer(&(uart->rx_dma_timer));
 #else
+       if (request_irq(uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED,
+            "BFIN_UART_RX", uart)) {
 # ifdef        CONFIG_KGDB_UART
-       if (uart->port.line != CONFIG_KGDB_UART_PORT && request_irq
-# else
-       if (request_irq
+               if (uart->port.line != CONFIG_KGDB_UART_PORT) {
 # endif
-           (uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED,
-            "BFIN_UART_RX", uart)) {
                printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n");
                return -EBUSY;
+# ifdef        CONFIG_KGDB_UART
+               }
+# endif
        }
 
+
        if (request_irq
            (uart->port.irq+1, bfin_serial_tx_int, IRQF_DISABLED,
             "BFIN_UART_TX", uart)) {
@@ -962,30 +969,6 @@ static void __init bfin_serial_init_ports(void)
 }
 
 #ifdef CONFIG_SERIAL_BFIN_CONSOLE
-static void bfin_serial_console_putchar(struct uart_port *port, int ch)
-{
-       struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
-       while (!(UART_GET_LSR(uart) & THRE))
-               barrier();
-       UART_PUT_CHAR(uart, ch);
-       SSYNC();
-}
-
-/*
- * Interrupts are disabled on entering
- */
-static void
-bfin_serial_console_write(struct console *co, const char *s, unsigned int count)
-{
-       struct bfin_serial_port *uart = &bfin_serial_ports[co->index];
-       int flags = 0;
-
-       spin_lock_irqsave(&uart->port.lock, flags);
-       uart_console_write(&uart->port, s, count, bfin_serial_console_putchar);
-       spin_unlock_irqrestore(&uart->port.lock, flags);
-
-}
-
 /*
  * If the port was already initialised (eg, by a boot loader),
  * try to determine the current setup.
@@ -1038,19 +1021,25 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
        }
        pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __FUNCTION__, *baud, *parity, *bits);
 }
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
+static struct uart_driver bfin_serial_reg;
 
 static int __init
 bfin_serial_console_setup(struct console *co, char *options)
 {
        struct bfin_serial_port *uart;
+# ifdef CONFIG_SERIAL_BFIN_CONSOLE
        int baud = 57600;
        int bits = 8;
        int parity = 'n';
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+#  ifdef CONFIG_SERIAL_BFIN_CTSRTS
        int flow = 'r';
-#else
+#  else
        int flow = 'n';
-#endif
+#  endif
+# endif
 
        /*
         * Check whether an invalid uart number has been specified, and
@@ -1061,15 +1050,45 @@ bfin_serial_console_setup(struct console *co, char *options)
                co->index = 0;
        uart = &bfin_serial_ports[co->index];
 
+# ifdef CONFIG_SERIAL_BFIN_CONSOLE
        if (options)
                uart_parse_options(options, &baud, &parity, &bits, &flow);
        else
                bfin_serial_console_get_options(uart, &baud, &parity, &bits);
 
        return uart_set_options(&uart->port, co, baud, parity, bits, flow);
+# else
+       return 0;
+# endif
+}
+#endif /* defined (CONFIG_SERIAL_BFIN_CONSOLE) ||
+                                defined (CONFIG_EARLY_PRINTK) */
+
+#ifdef CONFIG_SERIAL_BFIN_CONSOLE
+static void bfin_serial_console_putchar(struct uart_port *port, int ch)
+{
+       struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+       while (!(UART_GET_LSR(uart) & THRE))
+               barrier();
+       UART_PUT_CHAR(uart, ch);
+       SSYNC();
+}
+
+/*
+ * Interrupts are disabled on entering
+ */
+static void
+bfin_serial_console_write(struct console *co, const char *s, unsigned int count)
+{
+       struct bfin_serial_port *uart = &bfin_serial_ports[co->index];
+       int flags = 0;
+
+       spin_lock_irqsave(&uart->port.lock, flags);
+       uart_console_write(&uart->port, s, count, bfin_serial_console_putchar);
+       spin_unlock_irqrestore(&uart->port.lock, flags);
+
 }
 
-static struct uart_driver bfin_serial_reg;
 static struct console bfin_serial_console = {
        .name           = BFIN_SERIAL_NAME,
        .write          = bfin_serial_console_write,
@@ -1095,7 +1114,64 @@ console_initcall(bfin_serial_rs_console_init);
 #define BFIN_SERIAL_CONSOLE    &bfin_serial_console
 #else
 #define BFIN_SERIAL_CONSOLE    NULL
-#endif
+#endif /* CONFIG_SERIAL_BFIN_CONSOLE */
+
+
+#ifdef CONFIG_EARLY_PRINTK
+static __init void early_serial_putc(struct uart_port *port, int ch)
+{
+       unsigned timeout = 0xffff;
+       struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+
+       while ((!(UART_GET_LSR(uart) & THRE)) && --timeout)
+               cpu_relax();
+       UART_PUT_CHAR(uart, ch);
+}
+
+static __init void early_serial_write(struct console *con, const char *s,
+                                       unsigned int n)
+{
+       struct bfin_serial_port *uart = &bfin_serial_ports[con->index];
+       unsigned int i;
+
+       for (i = 0; i < n; i++, s++) {
+               if (*s == '\n')
+                       early_serial_putc(&uart->port, '\r');
+               early_serial_putc(&uart->port, *s);
+       }
+}
+
+static struct __init console bfin_early_serial_console = {
+       .name = "early_BFuart",
+       .write = early_serial_write,
+       .device = uart_console_device,
+       .flags = CON_PRINTBUFFER,
+       .setup = bfin_serial_console_setup,
+       .index = -1,
+       .data  = &bfin_serial_reg,
+};
+
+struct console __init *bfin_earlyserial_init(unsigned int port,
+                                               unsigned int cflag)
+{
+       struct bfin_serial_port *uart;
+       struct ktermios t;
+
+       if (port == -1 || port >= nr_ports)
+               port = 0;
+       bfin_serial_init_ports();
+       bfin_early_serial_console.index = port;
+       uart = &bfin_serial_ports[port];
+       t.c_cflag = cflag;
+       t.c_iflag = 0;
+       t.c_oflag = 0;
+       t.c_lflag = ICANON;
+       t.c_line = port;
+       bfin_serial_set_termios(&uart->port, &t, &t);
+       return &bfin_early_serial_console;
+}
+
+#endif /* CONFIG_SERIAL_BFIN_CONSOLE */
 
 static struct uart_driver bfin_serial_reg = {
        .owner                  = THIS_MODULE,
@@ -1182,7 +1258,7 @@ static int __init bfin_serial_init(void)
        int ret;
 #ifdef CONFIG_KGDB_UART
        struct bfin_serial_port *uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
-       struct termios t;
+       struct ktermios t;
 #endif
 
        pr_info("Serial: Blackfin serial driver\n");
@@ -1199,11 +1275,15 @@ static int __init bfin_serial_init(void)
        }
 #ifdef CONFIG_KGDB_UART
        if (uart->port.cons->index != CONFIG_KGDB_UART_PORT) {
-               request_irq(uart->port.irq, bfin_serial_int,
+               request_irq(uart->port.irq, bfin_serial_rx_int,
                        IRQF_DISABLED, "BFIN_UART_RX", uart);
                pr_info("Request irq for kgdb uart port\n");
+#ifdef CONFIG_BF54x
+               UART_SET_IER(uart, ERBFI);
+#else
                UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
-               __builtin_bfin_ssync();
+#endif
+               SSYNC();
                t.c_cflag = CS8|B57600;
                t.c_iflag = 0;
                t.c_oflag = 0;
index 84c726934ace3f029a55b1d150c0291383f3e1fd..4712f354dcca1e40dcfaa91eb5cb62a9572a70d9 100644 (file)
@@ -3,8 +3,11 @@
 
 #include <linux/mmc/host.h>
 
+struct device;
+
 struct imxmmc_platform_data {
-       int (*card_present)(void);
+       int (*card_present)(struct device *);
+       int (*get_ro)(struct device *);
 };
 
 extern void imx_set_mmc_info(struct imxmmc_platform_data *info);
index 0215965dc586d4db7037299ef56e735e9cb5a0b4..7dbd603c38cc3cf6e5a2244e547c90b45df46e7e 100644 (file)
@@ -6,6 +6,8 @@
 
 #include <linux/types.h>
 
+#define GPIO_PIN_NONE  (-1)
+
 /* Add basic devices: system manager, interrupt controller, portmuxes, etc. */
 void at32_add_system_devices(void);
 
@@ -36,6 +38,12 @@ struct platform_device *
 at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
                     unsigned long fbmem_start, unsigned long fbmem_len);
 
+struct usba_platform_data {
+       int vbus_pin;
+};
+struct platform_device *
+at32_add_device_usba(unsigned int id, struct usba_platform_data *data);
+
 /* depending on what's hooked up, not all SSC pins will be used */
 #define        ATMEL_SSC_TK            0x01
 #define        ATMEL_SSC_TF            0x02
index 9930871decde1e61bbb522b9d9243759263f773c..b1abe6b4e4efef469f8098dd2d1ebb04873d937d 100644 (file)
@@ -19,6 +19,7 @@
 #define AT32_GPIOF_OUTPUT      0x00000002      /* (OUT) Enable output driver */
 #define AT32_GPIOF_HIGH                0x00000004      /* (OUT) Set output high */
 #define AT32_GPIOF_DEGLITCH    0x00000008      /* (IN) Filter glitches */
+#define AT32_GPIOF_MULTIDRV    0x00000010      /* Enable multidriver option */
 
 void at32_select_periph(unsigned int pin, unsigned int periph,
                        unsigned long flags);
index 07152b7fd9c94da03f2c3d2fa1af3c9d00464b8c..c98eea44a70a08eba09b2d24b7f522dd6ea5b255 100644 (file)
 /*
  * All timing parameters are in nanoseconds.
  */
+struct smc_timing {
+       /* Delay from address valid to assertion of given strobe */
+       int ncs_read_setup;
+       int nrd_setup;
+       int ncs_write_setup;
+       int nwe_setup;
+
+       /* Pulse length of given strobe */
+       int ncs_read_pulse;
+       int nrd_pulse;
+       int ncs_write_pulse;
+       int nwe_pulse;
+
+       /* Total cycle length of given operation */
+       int read_cycle;
+       int write_cycle;
+
+       /* Minimal recovery times, will extend cycle if needed */
+       int ncs_read_recover;
+       int nrd_recover;
+       int ncs_write_recover;
+       int nwe_recover;
+};
+
+/*
+ * All timing parameters are in clock cycles.
+ */
 struct smc_config {
+
        /* Delay from address valid to assertion of given strobe */
-       u16             ncs_read_setup;
-       u16             nrd_setup;
-       u16             ncs_write_setup;
-       u16             nwe_setup;
+       u             ncs_read_setup;
+       u             nrd_setup;
+       u             ncs_write_setup;
+       u             nwe_setup;
 
        /* Pulse length of given strobe */
-       u16             ncs_read_pulse;
-       u16             nrd_pulse;
-       u16             ncs_write_pulse;
-       u16             nwe_pulse;
+       u             ncs_read_pulse;
+       u             nrd_pulse;
+       u             ncs_write_pulse;
+       u             nwe_pulse;
 
        /* Total cycle length of given operation */
-       u16             read_cycle;
-       u16             write_cycle;
+       u             read_cycle;
+       u             write_cycle;
 
        /* Bus width in bytes */
        u8              bus_width;
@@ -76,6 +104,9 @@ struct smc_config {
        unsigned int    tdf_mode:1;
 };
 
+extern void smc_set_timing(struct smc_config *config,
+                          const struct smc_timing *timing);
+
 extern int smc_set_configuration(int cs, const struct smc_config *config);
 extern struct smc_config *smc_get_configuration(int cs);
 
index 21bb60bbb9a1889e3eb058f5b4045238b45bf33a..81e342636ac4cb3d93fc612b9018f5895f57e2c7 100644 (file)
@@ -264,7 +264,11 @@ static inline void
 dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
                        size_t size, enum dma_data_direction direction)
 {
-       dma_cache_sync(dev, bus_to_virt(dma_handle), size, direction);
+       /*
+        * No need to do anything since the CPU isn't supposed to
+        * touch this memory after we flushed it at mapping- or
+        * sync-for-device time.
+        */
 }
 
 static inline void
@@ -309,12 +313,11 @@ static inline void
 dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
                    int nents, enum dma_data_direction direction)
 {
-       int i;
-
-       for (i = 0; i < nents; i++) {
-               dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-                              sg[i].length, direction);
-       }
+       /*
+        * No need to do anything since the CPU isn't supposed to
+        * touch this memory after we flushed it at mapping- or
+        * sync-for-device time.
+        */
 }
 
 static inline void
index a8236bacc8789133c573885d3065ba97005eebc3..dc2d527cef4132532db6bda322f66167618f1d7f 100644 (file)
@@ -73,11 +73,16 @@ extern struct task_struct *__switch_to(struct task_struct *,
 
 extern void __xchg_called_with_bad_pointer(void);
 
-#ifdef __CHECKER__
-extern unsigned long __builtin_xchg(void *ptr, unsigned long x);
-#endif
+static inline unsigned long xchg_u32(u32 val, volatile u32 *m)
+{
+       u32 ret;
 
-#define xchg_u32(val, m) __builtin_xchg((void *)m, val)
+       asm volatile("xchg %[ret], %[m], %[val]"
+                       : [ret] "=&r"(ret), "=m"(*m)
+                       : "m"(*m), [m] "r"(m), [val] "r"(val)
+                       : "memory");
+       return ret;
+}
 
 static inline unsigned long __xchg(unsigned long x,
                                       volatile void *ptr,
index 3b4e35b55c822299072a04496ef11c70ea82fa13..de09009593f84eb12d3e8fa38c0450df96777b7d 100644 (file)
 #ifdef __KERNEL__
 #define NR_syscalls            282
 
+/* Old stuff */
+#define __IGNORE_uselib
+#define __IGNORE_mmap
+
+/* NUMA stuff */
+#define __IGNORE_mbind
+#define __IGNORE_get_mempolicy
+#define __IGNORE_set_mempolicy
+#define __IGNORE_migrate_pages
+#define __IGNORE_move_pages
+
+/* SMP stuff */
+#define __IGNORE_getcpu
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_STAT64
index 95c1c952e7c1420a42c33f354fe11372affa4e79..f617d8765451dab134799589a1265b08e6e96fce 100644 (file)
@@ -21,8 +21,6 @@
 #ifndef _SPI_CHANNEL_H_
 #define _SPI_CHANNEL_H_
 
-#define SPI0_REGBASE       0xffc00500
-
 #define SPI_READ              0
 #define SPI_WRITE             1
 
index 25b934b7f829a2efa8a2594105323abcc37823b1..984b74f0a2ecdf1b76f713f9a597d9c48fb40cae 100644 (file)
 #define HI(con32) (((con32) >> 16) & 0xFFFF)
 #define hi(con32) (((con32) >> 16) & 0xFFFF)
 
-#include <asm/mach/blackfin.h>
-#include <asm/bfin-global.h>
+#include <asm/mach/anomaly.h>
 
 #ifndef __ASSEMBLY__
 
 /* SSYNC implementation for C file */
-#if defined(ANOMALY_05000312) && defined(ANOMALY_05000244)
-static inline void SSYNC (void)
-{
-       int _tmp;
-       __asm__ __volatile__ ("cli %0;\n\t"
-                       "nop;nop;\n\t"
-                       "ssync;\n\t"
-                       "sti %0;\n\t"
-                       :"=d"(_tmp):);
-}
-#elif defined(ANOMALY_05000312) && !defined(ANOMALY_05000244)
-static inline void SSYNC (void)
+static inline void SSYNC(void)
 {
        int _tmp;
-       __asm__ __volatile__ ("cli %0;\n\t"
-                       "ssync;\n\t"
-                       "sti %0;\n\t"
-                       :"=d"(_tmp):);
+       if (ANOMALY_05000312)
+               __asm__ __volatile__(
+                       "cli %0;"
+                       "nop;"
+                       "nop;"
+                       "ssync;"
+                       "sti %0;"
+                       : "=d" (_tmp)
+               );
+       else if (ANOMALY_05000244)
+               __asm__ __volatile__(
+                       "nop;"
+                       "nop;"
+                       "nop;"
+                       "ssync;"
+               );
+       else
+               __asm__ __volatile__("ssync;");
 }
-#elif !defined(ANOMALY_05000312) && defined(ANOMALY_05000244)
-static inline void SSYNC (void)
-{
-       __asm__ __volatile__ ("nop; nop; nop;\n\t"
-                       "ssync;\n\t"
-                       ::);
-}
-#elif !defined(ANOMALY_05000312) && !defined(ANOMALY_05000244)
-static inline void SSYNC (void)
-{
-       __asm__ __volatile__ ("ssync;\n\t");
-}
-#endif
 
 /* CSYNC implementation for C file */
-#if defined(ANOMALY_05000312) && defined(ANOMALY_05000244)
-static inline void CSYNC (void)
-{
-       int _tmp;
-       __asm__ __volatile__ ("cli %0;\n\t"
-                       "nop;nop;\n\t"
-                       "csync;\n\t"
-                       "sti %0;\n\t"
-                       :"=d"(_tmp):);
-}
-#elif defined(ANOMALY_05000312) && !defined(ANOMALY_05000244)
-static inline void CSYNC (void)
+static inline void CSYNC(void)
 {
        int _tmp;
-       __asm__ __volatile__ ("cli %0;\n\t"
-                       "csync;\n\t"
-                       "sti %0;\n\t"
-                       :"=d"(_tmp):);
-}
-#elif !defined(ANOMALY_05000312) && defined(ANOMALY_05000244)
-static inline void CSYNC (void)
-{
-       __asm__ __volatile__ ("nop; nop; nop;\n\t"
-                       "ssync;\n\t"
-                       ::);
+       if (ANOMALY_05000312)
+               __asm__ __volatile__(
+                       "cli %0;"
+                       "nop;"
+                       "nop;"
+                       "csync;"
+                       "sti %0;"
+                       : "=d" (_tmp)
+               );
+       else if (ANOMALY_05000244)
+               __asm__ __volatile__(
+                       "nop;"
+                       "nop;"
+                       "nop;"
+                       "csync;"
+               );
+       else
+               __asm__ __volatile__("csync;");
 }
-#elif !defined(ANOMALY_05000312) && !defined(ANOMALY_05000244)
-static inline void CSYNC (void)
-{
-       __asm__ __volatile__ ("csync;\n\t");
-}
-#endif
 
 #else  /* __ASSEMBLY__ */
 
@@ -91,19 +70,15 @@ static inline void CSYNC (void)
 #define ssync(x) SSYNC(x)
 #define csync(x) CSYNC(x)
 
-#if defined(ANOMALY_05000312) && defined(ANOMALY_05000244)
+#if ANOMALY_05000312
 #define SSYNC(scratch) cli scratch; nop; nop; SSYNC; sti scratch;
 #define CSYNC(scratch) cli scratch; nop; nop; CSYNC; sti scratch;
 
-#elif defined(ANOMALY_05000312) && !defined(ANOMALY_05000244)
-#define SSYNC(scratch) cli scratch; nop; nop; SSYNC; sti scratch;
-#define CSYNC(scratch) cli scratch; nop; nop; CSYNC; sti scratch;
-
-#elif !defined(ANOMALY_05000312) && defined(ANOMALY_05000244)
+#elif ANOMALY_05000244
 #define SSYNC(scratch) nop; nop; nop; SSYNC;
 #define CSYNC(scratch) nop; nop; nop; CSYNC;
 
-#elif !defined(ANOMALY_05000312) && !defined(ANOMALY_05000244)
+#else
 #define SSYNC(scratch) SSYNC;
 #define CSYNC(scratch) CSYNC;
 
@@ -111,4 +86,7 @@ static inline void CSYNC (void)
 
 #endif /* __ASSEMBLY__ */
 
+#include <asm/mach/blackfin.h>
+#include <asm/bfin-global.h>
+
 #endif                         /* _BLACKFIN_H_ */
index e5e000de3c36f719fdcd0677d7d81088708da1d2..d81a77545a04a6a88414d11ec6e9e00604475d23 100644 (file)
@@ -48,9 +48,9 @@ extern void blackfin_dflush_page(void *);
 
 static inline void flush_icache_range(unsigned start, unsigned end)
 {
-#if defined(CONFIG_BLKFIN_DCACHE) && defined(CONFIG_BLKFIN_CACHE)
+#if defined(CONFIG_BFIN_DCACHE) && defined(CONFIG_BFIN_ICACHE)
 
-# if defined(CONFIG_BLKFIN_WT)
+# if defined(CONFIG_BFIN_WT)
        blackfin_icache_flush_range((start), (end));
 # else
        blackfin_icache_dcache_flush_range((start), (end));
@@ -58,10 +58,10 @@ static inline void flush_icache_range(unsigned start, unsigned end)
 
 #else
 
-# if defined(CONFIG_BLKFIN_CACHE)
+# if defined(CONFIG_BFIN_ICACHE)
        blackfin_icache_flush_range((start), (end));
 # endif
-# if defined(CONFIG_BLKFIN_DCACHE)
+# if defined(CONFIG_BFIN_DCACHE)
        blackfin_dcache_flush_range((start), (end));
 # endif
 
@@ -74,12 +74,12 @@ do { memcpy(dst, src, len); \
 } while (0)
 #define copy_from_user_page(vma, page, vaddr, dst, src, len)   memcpy(dst, src, len)
 
-#if defined(CONFIG_BLKFIN_DCACHE)
+#if defined(CONFIG_BFIN_DCACHE)
 # define invalidate_dcache_range(start,end)    blackfin_dcache_invalidate_range((start), (end))
 #else
 # define invalidate_dcache_range(start,end)    do { } while (0)
 #endif
-#if defined(CONFIG_BLKFIN_DCACHE) && defined(CONFIG_BLKFIN_WB)
+#if defined(CONFIG_BFIN_DCACHE) && defined(CONFIG_BFIN_WB)
 # define flush_dcache_range(start,end)         blackfin_dcache_flush_range((start), (end))
 # define flush_dcache_page(page)                       blackfin_dflush_page(page_address(page))
 #else
@@ -87,4 +87,4 @@ do { memcpy(dst, src, len); \
 # define flush_dcache_page(page)                       do { } while (0)
 #endif
 
-#endif                         /* _BLACKFIN_CACHEFLUSH_H */
+#endif                         /* _BLACKFIN_ICACHEFLUSH_H */
index e0dd56bfa4c7b289956ab39ed25cf7ee4ba839ec..06828d77a58ff4c4583da3f71376d942e3fd381c 100644 (file)
-/************************************************************************
+/*
+ * File:         include/asm-blackfin/cplb.h
+ * Based on:     include/asm-blackfin/mach-bf537/bf537.h
+ * Author:       Robin Getz <rgetz@blackfin.uclinux.org>
  *
- * cplb.h
+ * Created:      2000
+ * Description:  Common CPLB definitions for CPLB init
  *
- * (c) Copyright 2002-2003 Analog Devices, Inc.  All rights reserved.
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
  *
- ************************************************************************/
-
-/* Defines necessary for cplb initialisation routines. */
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
 
 #ifndef _CPLB_H
 #define _CPLB_H
 
-# include <asm/blackfin.h>
+#include <asm/blackfin.h>
+#include <asm/mach/anomaly.h>
+
+#define SDRAM_IGENERIC    (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
+#define SDRAM_IKERNEL     (SDRAM_IGENERIC | CPLB_LOCK)
+#define L1_IMEMORY        (               CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
+#define SDRAM_INON_CHBL   (               CPLB_USER_RD | CPLB_VALID)
+
+/*Use the menuconfig cache policy here - CONFIG_BFIN_WT/CONFIG_BFIN_WB*/
+
+#if ANOMALY_05000158
+#define ANOMALY_05000158_WORKAROUND             0x200
+#else
+#define ANOMALY_05000158_WORKAROUND             0x0
+#endif
+
+#define CPLB_COMMON    (CPLB_DIRTY | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
+
+#ifdef CONFIG_BFIN_WB         /*Write Back Policy */
+#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_COMMON)
+#else                           /*Write Through */
+#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW  | CPLB_COMMON)
+#endif
+
+#define L1_DMEMORY       (CPLB_LOCK | CPLB_COMMON)
+#define L2_MEMORY        (CPLB_COMMON)
+#define SDRAM_DNON_CHBL  (CPLB_COMMON)
+#define SDRAM_EBIU       (CPLB_COMMON)
+#define SDRAM_OOPS       (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
+
+#define SIZE_1K 0x00000400      /* 1K */
+#define SIZE_4K 0x00001000      /* 4K */
+#define SIZE_1M 0x00100000      /* 1M */
+#define SIZE_4M 0x00400000      /* 4M */
+
+#define MAX_CPLBS (16 * 2)
+
+#define ASYNC_MEMORY_CPLB_COVERAGE     ((ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
+                                ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE) / SIZE_4M)
+
+/*
+* Number of required data CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 16 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Data Memory
+* possibly 1 for L2 Data Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+* 1 for ASYNC Memory
+*/
+
+
+#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1 \
+                                + ASYNC_MEMORY_CPLB_COVERAGE) * 2)
+
+/*
+* Number of required instruction CPLB switchtable entries
+* MEMSIZE / 4 (we mostly install 4M page size CPLBs
+* approx 12 for smaller 1MB page size CPLBs for allignment purposes
+* 1 for L1 Instruction Memory
+* possibly 1 for L2 Instruction Memory
+* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
+*/
+
+#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1 + 1) * 2)
+
 
 #define CPLB_ENABLE_ICACHE_P   0
 #define CPLB_ENABLE_DCACHE_P   1
 #define CPLB_DEF_CACHE         CPLB_L1_CHBL | CPLB_WT
 #define CPLB_CACHE_ENABLED     CPLB_L1_CHBL | CPLB_DIRTY
 
-#define CPLB_ALL_ACCESS        CPLB_SUPV_WR | CPLB_USER_RD | CPLB_USER_WR
-
 #define CPLB_I_PAGE_MGMT       CPLB_LOCK | CPLB_VALID
 #define CPLB_D_PAGE_MGMT       CPLB_LOCK | CPLB_ALL_ACCESS | CPLB_VALID
 #define CPLB_DNOCACHE          CPLB_ALL_ACCESS | CPLB_VALID
index be0d913e5516271b240d1c691c074344bfc6cf36..b42a531e7a1b9d90497652897e6ca7d4cd104f3f 100644 (file)
@@ -152,6 +152,7 @@ struct dma_channel {
 /* functions to set register mode */
 void set_dma_start_addr(unsigned int channel, unsigned long addr);
 void set_dma_next_desc_addr(unsigned int channel, unsigned long addr);
+void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr);
 void set_dma_x_count(unsigned int channel, unsigned short x_count);
 void set_dma_x_modify(unsigned int channel, short x_modify);
 void set_dma_y_count(unsigned int channel, unsigned short y_count);
@@ -159,6 +160,7 @@ void set_dma_y_modify(unsigned int channel, short y_modify);
 void set_dma_config(unsigned int channel, unsigned short config);
 unsigned short set_bfin_dma_config(char direction, char flow_mode,
                                   char intr_mode, char dma_mode, char width);
+void set_dma_curr_addr(unsigned int channel, unsigned long addr);
 
 /* get curr status for polling */
 unsigned short get_dma_curr_irqstat(unsigned int channel);
diff --git a/include/asm-blackfin/early_printk.h b/include/asm-blackfin/early_printk.h
new file mode 100644 (file)
index 0000000..110f1c1
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * File:         include/asm-blackfin/early_printk.h
+ * Author:       Robin Getz <rgetz@blackfin.uclinux.org
+ *
+ * Created:      14Aug2007
+ * Description:  function prototpyes for early printk
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifdef CONFIG_EARLY_PRINTK
+extern int setup_early_printk(char *);
+#else
+#define setup_early_printk(fmt) do { } while (0)
+#endif /* CONFIG_EARLY_PRINTK */
index 7480cfa7e2d64304c58ff924b05fbfc385ad8bf6..dd203cd93796fa1f88c5e5eceb63ed18330e3e92 100644 (file)
 
 #ifdef BF533_FAMILY
 #define MAX_BLACKFIN_GPIOS 16
+
+#define        GPIO_PF0        0
+#define        GPIO_PF1        1
+#define        GPIO_PF2        2
+#define        GPIO_PF3        3
+#define        GPIO_PF4        4
+#define        GPIO_PF5        5
+#define        GPIO_PF6        6
+#define        GPIO_PF7        7
+#define        GPIO_PF8        8
+#define        GPIO_PF9        9
+#define        GPIO_PF10       10
+#define        GPIO_PF11       11
+#define        GPIO_PF12       12
+#define        GPIO_PF13       13
+#define        GPIO_PF14       14
+#define        GPIO_PF15       15
+
 #endif
 
 #ifdef BF537_FAMILY
@@ -421,6 +439,19 @@ unsigned short gpio_get_value(unsigned short gpio);
 void gpio_direction_input(unsigned short gpio);
 void gpio_direction_output(unsigned short gpio);
 
+#include <asm-generic/gpio.h>          /* cansleep wrappers */
+#include <asm/irq.h>
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+       return (gpio + GPIO_IRQ_BASE);
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+       return (irq - GPIO_IRQ_BASE);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ARCH_BLACKFIN_GPIO_H__ */
index 142cb333db29830b3b5740ef8eb36229db9a56af..525179bf43d70368fe1406ee926f70c18ffe5523 100644 (file)
@@ -115,21 +115,21 @@ static inline unsigned int readl(const volatile void __iomem *addr)
 
 #ifndef __ASSEMBLY__
 
-extern void outsb(void __iomem *port, const void *addr, unsigned short count);
-extern void outsw(void __iomem *port, const void *addr, unsigned short count);
-extern void outsl(void __iomem *port, const void *addr, unsigned short count);
+extern void outsb(unsigned long port, const void *addr, unsigned long count);
+extern void outsw(unsigned long port, const void *addr, unsigned long count);
+extern void outsl(unsigned long port, const void *addr, unsigned long count);
 
-extern void insb(const void __iomem *port, void *addr, unsigned short count);
-extern void insw(const void __iomem *port, void *addr, unsigned short count);
-extern void insl(const void __iomem *port, void *addr, unsigned short count);
+extern void insb(unsigned long port, void *addr, unsigned long count);
+extern void insw(unsigned long port, void *addr, unsigned long count);
+extern void insl(unsigned long port, void *addr, unsigned long count);
 
-extern void dma_outsb(void __iomem *port, const void *addr, unsigned short count);
-extern void dma_outsw(void __iomem *port, const void *addr, unsigned short count);
-extern void dma_outsl(void __iomem *port, const void *addr, unsigned short count);
+extern void dma_outsb(unsigned long port, const void *addr, unsigned short count);
+extern void dma_outsw(unsigned long port, const void *addr, unsigned short count);
+extern void dma_outsl(unsigned long port, const void *addr, unsigned short count);
 
-extern void dma_insb(const void __iomem *port, void *addr, unsigned short count);
-extern void dma_insw(const void __iomem *port, void *addr, unsigned short count);
-extern void dma_insl(const void __iomem *port, void *addr, unsigned short count);
+extern void dma_insb(unsigned long port, void *addr, unsigned short count);
+extern void dma_insw(unsigned long port, void *addr, unsigned short count);
+extern void dma_insl(unsigned long port, void *addr, unsigned short count);
 
 /*
  * Map some physical address range into the kernel address space.
index 8356204151db86dcad11cdd3e67adb348510c708..895e3173165d9310d3332fb664ee2da430ae0b9d 100644 (file)
 #define TIOCSBRK       0x5427  /* BSD compatibility */
 #define TIOCCBRK       0x5428  /* BSD compatibility */
 #define TIOCGSID       0x5429  /* Return the session ID of FD */
-#define TIOCGPTN       _IOR('T',0x30, unsigned int)    /* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK     _IOW('T',0x31, int)     /* Lock/unlock Pty */
+#define TCGETS2                _IOR('T', 0x2A, struct termios2)
+#define TCSETS2                _IOW('T', 0x2B, struct termios2)
+#define TCSETSW2       _IOW('T', 0x2C, struct termios2)
+#define TCSETSF2       _IOW('T', 0x2D, struct termios2)
+/* Get Pty Number (of pty-mux device) */
+#define TIOCGPTN       _IOR('T', 0x30, unsigned int)
+#define TIOCSPTLCK     _IOW('T', 0x31, int)    /* Lock/unlock Pty */
 
 #define FIONCLEX       0x5450  /* these numbers need to be adjusted. */
 #define FIOCLEX                0x5451
index d830f0a49a1cb289ff3e1660f68151fe46a95c6f..139b5208f9d8506a1c691345f05519e6c2a33109 100644 (file)
@@ -1,13 +1,15 @@
 #ifndef _IRQ_HANDLER_H
 #define _IRQ_HANDLER_H
 
+#include <linux/types.h>
+#include <linux/linkage.h>
+
 /* BASE LEVEL interrupt handler routines */
-asmlinkage void evt_emulation(void);
 asmlinkage void evt_exception(void);
 asmlinkage void trap(void);
 asmlinkage void evt_ivhw(void);
 asmlinkage void evt_timer(void);
-asmlinkage void evt_evt2(void);
+asmlinkage void evt_nmi(void);
 asmlinkage void evt_evt7(void);
 asmlinkage void evt_evt8(void);
 asmlinkage void evt_evt9(void);
@@ -18,5 +20,14 @@ asmlinkage void evt_evt13(void);
 asmlinkage void evt_soft_int1(void);
 asmlinkage void evt_system_call(void);
 asmlinkage void init_exception_buff(void);
+asmlinkage void trap_c(struct pt_regs *fp);
+asmlinkage void ex_replaceable(void);
+asmlinkage void early_trap(void);
+
+extern void *ex_table[];
+extern void return_from_exception(void);
+
+extern int bfin_request_exception(unsigned int exception, void (*handler)(void));
+extern int bfin_free_exception(unsigned int exception, void (*handler)(void));
 
 #endif
index 532bd90520044629c4c7184ea913a2bf44a82fa7..0f73847fd6bc53f4d90538477c814d632d777ab2 100644 (file)
@@ -179,5 +179,6 @@ enum regnames {
 #define STATDA1                0x80
 
 extern void kgdb_print(const char *fmt, ...);
+extern void init_kgdb_uart(void);
 
 #endif
diff --git a/include/asm-blackfin/mach-bf527/anomaly.h b/include/asm-blackfin/mach-bf527/anomaly.h
new file mode 100644 (file)
index 0000000..991db98
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * File: include/asm-blackfin/mach-bf527/anomaly.h
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Copyright (C) 2004-2007 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
+ */
+
+/* This file shoule be up to date with:
+ *  - Revision A, May 30, 2007; ADSP-BF527 Blackfin Processor Anomaly List
+ */
+
+#ifndef _MACH_ANOMALY_H_
+#define _MACH_ANOMALY_H_
+
+/* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot2 Not Supported */
+#define ANOMALY_05000074 (1)
+/* DMA_RUN Bit Is Not Valid after a Peripheral Receive Channel DMA Stops */
+#define ANOMALY_05000119 (1)
+/* Rx.H Cannot Be Used to Access 16-bit System MMR Registers */
+#define ANOMALY_05000122 (1)
+/* Spurious Hardware Error from an Access in the Shadow of a Conditional Branch */
+#define ANOMALY_05000245 (1)
+/* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */
+#define ANOMALY_05000265 (1)
+/* Memory-To-Memory DMA Source/Destination Descriptors Must Be in Same Memory Space */
+#define ANOMALY_05000301 (1)
+/* Errors When SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted */
+#define ANOMALY_05000312 (1)
+/* Incorrect Access of OTP_STATUS During otp_write() Function */
+#define ANOMALY_05000328 (1)
+/* Disallowed Configuration Prevents Subsequent Allowed Configuration on Host DMA Port */
+#define ANOMALY_05000337 (1)
+/* TWI Does Not Operate Correctly Under Certain Signal Termination Conditions */
+#define ANOMALY_05000342 (1)
+/* Boot ROM Kernel Incorrectly Alters Reset Value of USB Register */
+#define ANOMALY_05000347 (1)
+
+/* Anomalies that don't exist on this proc */
+#define ANOMALY_05000323 (0)
+#endif
index 0b2fb5036ed0c9fcecc648da595db762815b6d61..b1ff67db01f8e78f23283613fb2457000908e6fd 100644 (file)
 
 
 /* SPI Controller                      (0xFFC00500 - 0xFFC005FF)                                                               */
+#define SPI0_REGBASE                   0xFFC00500
 #define SPI_CTL                                0xFFC00500      /* SPI Control Register                                         */
 #define SPI_FLG                                0xFFC00504      /* SPI Flag register                                            */
 #define SPI_STAT                       0xFFC00508      /* SPI Status register                                          */
 
 
 /* Two-Wire Interface          (0xFFC01400 - 0xFFC014FF)                                                               */
+#define TWI0_REGBASE                   0xFFC01400
 #define TWI_CLKDIV                     0xFFC01400      /* Serial Clock Divider Register                        */
 #define TWI_CONTROL                    0xFFC01404      /* TWI Control Register                                         */
 #define TWI_SLAVE_CTL          0xFFC01408      /* Slave Mode Control Register                          */
index 7302f290b93dbb999cb65022f1c0ac1b523139d2..f36ff5af1b91f54284c1c1eaacf48f84708d472c 100644 (file)
 /*
- * File:         include/asm-blackfin/mach-bf533/anomaly.h
- * Based on:
- * Author:
+ * File: include/asm-blackfin/mach-bf533/anomaly.h
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
  *
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Copyright (C) 2004-2007 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
  */
 
 /* This file shoule be up to date with:
- *  - Revision U, May 17, 2006; ADSP-BF533 Blackfin Processor Anomaly List
- *  - Revision Y, May 17, 2006; ADSP-BF532 Blackfin Processor Anomaly List
- *  - Revision T, May 17, 2006; ADSP-BF531 Blackfin Processor Anomaly List
+ *  - Revision X,  March 23, 2007; ADSP-BF533 Blackfin Processor Anomaly List
+ *  - Revision AB, March 23, 2007; ADSP-BF532 Blackfin Processor Anomaly List
+ *  - Revision W,  March 23, 2007; ADSP-BF531 Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
 #define _MACH_ANOMALY_H_
 
 /* We do not support 0.1 or 0.2 silicon - sorry */
-#if (defined(CONFIG_BF_REV_0_1) || defined(CONFIG_BF_REV_0_2))
-#error Kernel will not work on BF533 Version 0.1 or 0.2
+#if __SILICON_REVISION__ < 3
+# error Kernel will not work on BF533 silicon version 0.0, 0.1, or 0.2
 #endif
 
-/* Issues that are common to 0.5, 0.4, and 0.3 silicon */
-#if  (defined(CONFIG_BF_REV_0_5) || defined(CONFIG_BF_REV_0_4) \
-               || defined(CONFIG_BF_REV_0_3))
-#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in
-                            slot1 and store of a P register in slot 2 is not
-                            supported */
-#define ANOMALY_05000105 /* Watchpoint Status Register (WPSTAT) bits are set on
-                            every corresponding match */
-#define ANOMALY_05000119 /* DMA_RUN bit is not valid after a Peripheral Receive
-                            Channel DMA stops */
-#define ANOMALY_05000122 /* Rx.H can not be used to access 16-bit System MMR
-                            registers. */
-#define ANOMALY_05000166 /* PPI Data Lengths Between 8 and 16 do not zero out
-                            upper bits*/
-#define ANOMALY_05000167 /* Turning Serial Ports on With External Frame Syncs */
-#define ANOMALY_05000180 /* PPI_DELAY not functional in PPI modes with 0 frame
-                            syncs */
-#define ANOMALY_05000208 /* VSTAT status bit in PLL_STAT register is not
-                            functional */
-#define ANOMALY_05000219 /* NMI event at boot time results in unpredictable
-                            state */
-#define ANOMALY_05000229 /* SPI Slave Boot Mode modifies registers */
-#define ANOMALY_05000272 /* Certain data cache write through modes fail for
-                            VDDint <=0.9V */
-#define ANOMALY_05000273 /* Writes to Synchronous SDRAM memory may be lost */
-#define ANOMALY_05000277 /* Writes to a flag data register one SCLK cycle after
-                            an edge is detected may clear interrupt */
-#define ANOMALY_05000278 /* Disabling Peripherals with DMA running may cause
-                            DMA system instability */
-#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is
-                            not restored */
-#define ANOMALY_05000282 /* Memory DMA corruption with 32-bit data and traffic
-                            control */
-#define ANOMALY_05000283 /* A system MMR write is stalled indefinitely when
-                            killed in a particular stage*/
-#define ANOMALY_05000311 /* Erroneous flag pin operations under specific
-                           sequences */
-#define ANOMALY_05000312 /* Errors when SSYNC, CSYNC, or loads to LT, LB and LC
-                           registers are interrupted */
-#define ANOMALY_05000313 /* PPI Is Level-Sensitive on First Transfer  */
-#define ANOMALY_05000315 /* Killed System MMR Write Completes Erroneously On
-                         *  Next System MMR Access */
-#define ANOMALY_05000319 /* Internal Voltage Regulator Values of 1.05V, 1.10V
-                         *  and 1.15V Not Allowed for LQFP Packages */
-#endif /* Issues that are common to 0.5, 0.4, and 0.3 silicon */
+#if defined(__ADSPBF531__)
+# define ANOMALY_BF531 1
+#else
+# define ANOMALY_BF531 0
+#endif
+#if defined(__ADSPBF532__)
+# define ANOMALY_BF532 1
+#else
+# define ANOMALY_BF532 0
+#endif
+#if defined(__ADSPBF533__)
+# define ANOMALY_BF533 1
+#else
+# define ANOMALY_BF533 0
+#endif
 
-/* These issues only occur on 0.3 or 0.4 BF533 */
-#if (defined(CONFIG_BF_REV_0_4) || defined(CONFIG_BF_REV_0_3))
-#define ANOMALY_05000099 /* UART Line Status Register (UART_LSR) bits are not
-                            updated at the same time. */
-#define ANOMALY_05000158 /* Boot fails when data cache enabled: Data from a Data
-                           Cache Fill can be corrupted after or during
-                            Instruction DMA if certain core stalls exist */
-#define ANOMALY_05000179 /* PPI_COUNT cannot be programmed to 0 in General
-                            Purpose TX or RX modes */
-#define ANOMALY_05000198 /* Failing SYSTEM MMR accesses when stalled by
-                            preceding memory read */
-#define ANOMALY_05000200 /* SPORT TFS and DT are incorrectly driven during
-                            inactive channels in certain conditions */
-#define ANOMALY_05000202 /* Possible infinite stall with specific dual dag
-                            situation */
-#define ANOMALY_05000215 /* UART TX Interrupt masked erroneously */
-#define ANOMALY_05000225 /* Incorrect pulse-width of UART start-bit */
-#define ANOMALY_05000227 /* Scratchpad memory bank reads may return incorrect
-                            data*/
-#define ANOMALY_05000230 /* UART Receiver is less robust against Baudrate
-                            Differences in certain Conditions */
-#define ANOMALY_05000231 /* UART STB bit incorrectly affects receiver setting */
-#define ANOMALY_05000242 /* DF bit in PLL_CTL register does not respond to
-                            hardware reset */
-#define ANOMALY_05000244 /* With instruction cache enabled, a CSYNC or SSYNC or
-                            IDLE around a Change of Control causes
-                            unpredictable results */
-#define ANOMALY_05000245 /* Spurious Hardware Error from an access in the
-                            shadow of a conditional branch */
-#define ANOMALY_05000246 /* Data CPLB's should prevent spurious hardware
-                            errors */
-#define ANOMALY_05000253 /* Maximum external clock speed for Timers */
-#define ANOMALY_05000255 /* Entering Hibernate Mode with RTC Seconds event
-                            interrupt not functional */
-#define ANOMALY_05000257 /* An interrupt or exception during short Hardware
-                            loops may cause the instruction fetch unit to
-                            malfunction */
-#define ANOMALY_05000258 /* Instruction Cache is corrupted when bit 9 and 12 of
-                            the ICPLB Data registers differ */
-#define ANOMALY_05000260 /* ICPLB_STATUS MMR register may be corrupted */
-#define ANOMALY_05000261 /* DCPLB_FAULT_ADDR MMR register may be corrupted */
-#define ANOMALY_05000262 /* Stores to data cache may be lost */
-#define ANOMALY_05000263 /* Hardware loop corrupted when taking an ICPLB exception */
-#define ANOMALY_05000264 /* A Sync instruction (CSYNC, SSYNC) or an IDLE
-                            instruction will cause an infinite stall in the
-                            second to last instruction in a hardware loop */
-#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on
-                            SPORT external receive and transmit clocks. */
-#define ANOMALY_05000269 /* High I/O activity causes the output voltage of the
-                            internal voltage regulator (VDDint) to increase. */
-#define ANOMALY_05000270 /* High I/O activity causes the output voltage of the
-                            internal voltage regulator (VDDint) to decrease */
-#endif /* issues only occur on 0.3 or 0.4 BF533 */
+/* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot 2 Not Supported */
+#define ANOMALY_05000074 (1)
+/* UART Line Status Register (UART_LSR) Bits Are Not Updated at the Same Time */
+#define ANOMALY_05000099 (__SILICON_REVISION__ < 5)
+/* Watchpoint Status Register (WPSTAT) Bits Are Set on Every Corresponding Match */
+#define ANOMALY_05000105 (1)
+/* DMA_RUN Bit Is Not Valid after a Peripheral Receive Channel DMA Stops */
+#define ANOMALY_05000119 (1)
+/* Rx.H Cannot Be Used to Access 16-bit System MMR Registers */
+#define ANOMALY_05000122 (1)
+/* Instruction DMA Can Cause Data Cache Fills to Fail (Boot Implications) */
+#define ANOMALY_05000158 (__SILICON_REVISION__ < 5)
+/* PPI Data Lengths Between 8 and 16 Do Not Zero Out Upper Bits */
+#define ANOMALY_05000166 (1)
+/* Turning Serial Ports on with External Frame Syncs */
+#define ANOMALY_05000167 (1)
+/* PPI_COUNT Cannot Be Programmed to 0 in General Purpose TX or RX Modes */
+#define ANOMALY_05000179 (__SILICON_REVISION__ < 5)
+/* PPI_DELAY Not Functional in PPI Modes with 0 Frame Syncs */
+#define ANOMALY_05000180 (1)
+/* Timer Pin Limitations for PPI TX Modes with External Frame Syncs */
+#define ANOMALY_05000183 (__SILICON_REVISION__ < 4)
+/* False Protection Exceptions */
+#define ANOMALY_05000189 (__SILICON_REVISION__ < 4)
+/* False I/O Pin Interrupts on Edge-Sensitive Inputs When Polarity Setting Is Changed */
+#define ANOMALY_05000193 (__SILICON_REVISION__ < 4)
+/* Restarting SPORT in Specific Modes May Cause Data Corruption */
+#define ANOMALY_05000194 (__SILICON_REVISION__ < 4)
+/* Failing MMR Accesses When Stalled by Preceding Memory Read */
+#define ANOMALY_05000198 (__SILICON_REVISION__ < 5)
+/* Current DMA Address Shows Wrong Value During Carry Fix */
+#define ANOMALY_05000199 (__SILICON_REVISION__ < 4)
+/* SPORT TFS and DT Are Incorrectly Driven During Inactive Channels in Certain Conditions */
+#define ANOMALY_05000200 (__SILICON_REVISION__ < 5)
+/* Receive Frame Sync Not Ignored During Active Frames in SPORT Multi-Channel Mode */
+#define ANOMALY_05000201 (__SILICON_REVISION__ < 4)
+/* Possible Infinite Stall with Specific Dual-DAG Situation */
+#define ANOMALY_05000202 (__SILICON_REVISION__ < 5)
+/* Specific Sequence That Can Cause DMA Error or DMA Stopping */
+#define ANOMALY_05000203 (__SILICON_REVISION__ < 4)
+/* Incorrect data read with write-through cache and allocate cache lines on reads only mode */
+#define ANOMALY_05000204 (__SILICON_REVISION__ < 4 && ANOMALY_BF533)
+/* Recovery from "Brown-Out" Condition */
+#define ANOMALY_05000207 (__SILICON_REVISION__ < 4)
+/* VSTAT Status Bit in PLL_STAT Register Is Not Functional */
+#define ANOMALY_05000208 (1)
+/* Speed Path in Computational Unit Affects Certain Instructions */
+#define ANOMALY_05000209 (__SILICON_REVISION__ < 4)
+/* UART TX Interrupt Masked Erroneously */
+#define ANOMALY_05000215 (__SILICON_REVISION__ < 5)
+/* NMI Event at Boot Time Results in Unpredictable State */
+#define ANOMALY_05000219 (1)
+/* Incorrect Pulse-Width of UART Start Bit */
+#define ANOMALY_05000225 (__SILICON_REVISION__ < 5)
+/* Scratchpad Memory Bank Reads May Return Incorrect Data */
+#define ANOMALY_05000227 (__SILICON_REVISION__ < 5)
+/* SPI Slave Boot Mode Modifies Registers from Reset Value */
+#define ANOMALY_05000229 (1)
+/* UART Receiver is Less Robust Against Baudrate Differences in Certain Conditions */
+#define ANOMALY_05000230 (__SILICON_REVISION__ < 5)
+/* UART STB Bit Incorrectly Affects Receiver Setting */
+#define ANOMALY_05000231 (__SILICON_REVISION__ < 5)
+/* PPI_FS3 Is Not Driven in 2 or 3 Internal Frame Sync Transmit Modes */
+#define ANOMALY_05000233 (__SILICON_REVISION__ < 4)
+/* Incorrect Revision Number in DSPID Register */
+#define ANOMALY_05000234 (__SILICON_REVISION__ == 4)
+/* DF Bit in PLL_CTL Register Does Not Respond to Hardware Reset */
+#define ANOMALY_05000242 (__SILICON_REVISION__ < 4)
+/* If I-Cache Is On, CSYNC/SSYNC/IDLE Around Change of Control Causes Failures */
+#define ANOMALY_05000244 (__SILICON_REVISION__ < 5)
+/* Spurious Hardware Error from an Access in the Shadow of a Conditional Branch */
+#define ANOMALY_05000245 (1)
+/* Data CPLBs Should Prevent Spurious Hardware Errors */
+#define ANOMALY_05000246 (__SILICON_REVISION__ < 5)
+/* Incorrect Bit Shift of Data Word in Multichannel (TDM) Mode in Certain Conditions */
+#define ANOMALY_05000250 (__SILICON_REVISION__ == 4)
+/* Maximum External Clock Speed for Timers */
+#define ANOMALY_05000253 (__SILICON_REVISION__ < 5)
+/* Incorrect Timer Pulse Width in Single-Shot PWM_OUT Mode with External Clock */
+#define ANOMALY_05000254 (__SILICON_REVISION__ > 4)
+/* Entering Hibernate State with RTC Seconds Interrupt Not Functional */
+#define ANOMALY_05000255 (__SILICON_REVISION__ < 5)
+/* Interrupt/Exception During Short Hardware Loop May Cause Bad Instruction Fetches */
+#define ANOMALY_05000257 (__SILICON_REVISION__ < 5)
+/* Instruction Cache Is Corrupted When Bits 9 and 12 of the ICPLB Data Registers Differ */
+#define ANOMALY_05000258 (__SILICON_REVISION__ < 5)
+/* ICPLB_STATUS MMR Register May Be Corrupted */
+#define ANOMALY_05000260 (__SILICON_REVISION__ < 5)
+/* DCPLB_FAULT_ADDR MMR Register May Be Corrupted */
+#define ANOMALY_05000261 (__SILICON_REVISION__ < 5)
+/* Stores To Data Cache May Be Lost */
+#define ANOMALY_05000262 (__SILICON_REVISION__ < 5)
+/* Hardware Loop Corrupted When Taking an ICPLB Exception */
+#define ANOMALY_05000263 (__SILICON_REVISION__ < 5)
+/* CSYNC/SSYNC/IDLE Causes Infinite Stall in Penultimate Instruction in Hardware Loop */
+#define ANOMALY_05000264 (__SILICON_REVISION__ < 5)
+/* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */
+#define ANOMALY_05000265 (__SILICON_REVISION__ < 5)
+/* High I/O Activity Causes Output Voltage of Internal Voltage Regulator (Vddint) to Increase */
+#define ANOMALY_05000269 (__SILICON_REVISION__ < 5)
+/* High I/O Activity Causes Output Voltage of Internal Voltage Regulator (Vddint) to Decrease */
+#define ANOMALY_05000270 (__SILICON_REVISION__ < 5)
+/* Spontaneous Reset of Internal Voltage Regulator */
+#define ANOMALY_05000271 (__SILICON_REVISION__ < 4)
+/* Certain Data Cache Writethrough Modes Fail for Vddint <= 0.9V */
+#define ANOMALY_05000272 (1)
+/* Writes to Synchronous SDRAM Memory May Be Lost */
+#define ANOMALY_05000273 (1)
+/* Timing Requirements Change for External Frame Sync PPI Modes with Non-Zero PPI_DELAY */
+#define ANOMALY_05000276 (1)
+/* Writes to an I/O Data Register One SCLK Cycle after an Edge Is Detected May Clear Interrupt */
+#define ANOMALY_05000277 (1)
+/* Disabling Peripherals with DMA Running May Cause DMA System Instability */
+#define ANOMALY_05000278 (1)
+/* False Hardware Error Exception When ISR Context Is Not Restored */
+#define ANOMALY_05000281 (1)
+/* Memory DMA Corruption with 32-Bit Data and Traffic Control */
+#define ANOMALY_05000282 (1)
+/* System MMR Write Is Stalled Indefinitely When Killed in a Particular Stage */
+#define ANOMALY_05000283 (1)
+/* SPORTs May Receive Bad Data If FIFOs Fill Up */
+#define ANOMALY_05000288 (1)
+/* Memory-To-Memory DMA Source/Destination Descriptors Must Be in Same Memory Space */
+#define ANOMALY_05000301 (1)
+/* SSYNCs After Writes To DMA MMR Registers May Not Be Handled Correctly */
+#define ANOMALY_05000302 (__SILICON_REVISION__ < 5)
+/* New Feature: Additional Hysteresis on SPORT Input Pins (Not Available On Older Silicon) */
+#define ANOMALY_05000305 (__SILICON_REVISION__ < 5)
+/* New Feature: Additional PPI Frame Sync Sampling Options (Not Available On Older Silicon) */
+#define ANOMALY_05000306 (__SILICON_REVISION__ < 5)
+/* False Hardware Errors Caused by Fetches at the Boundary of Reserved Memory */
+#define ANOMALY_05000310 (1)
+/* Erroneous Flag (GPIO) Pin Operations under Specific Sequences */
+#define ANOMALY_05000311 (1)
+/* Errors When SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted */
+#define ANOMALY_05000312 (1)
+/* PPI Is Level-Sensitive on First Transfer */
+#define ANOMALY_05000313 (1)
+/* Killed System MMR Write Completes Erroneously On Next System MMR Access */
+#define ANOMALY_05000315 (1)
+/* Internal Voltage Regulator Values of 1.05V, 1.10V and 1.15V Not Allowed for LQFP Packages */
+#define ANOMALY_05000319 (ANOMALY_BF531 || ANOMALY_BF532)
 
-/* These issues are only on 0.4 silicon */
-#if (defined(CONFIG_BF_REV_0_4))
-#define ANOMALY_05000234 /* Incorrect Revision Number in DSPID Register */
-#define ANOMALY_05000250 /* Incorrect Bit-Shift of Data Word in Multichannel
-                            (TDM) */
-#endif /* issues are only on 0.4 silicon */
+/* These anomalies have been "phased" out of analog.com anomaly sheets and are
+ * here to show running on older silicon just isn't feasible.
+ */
 
-/* These issues are only on 0.3 silicon */
-#if defined(CONFIG_BF_REV_0_3)
-#define ANOMALY_05000183 /* Timer Pin limitations for PPI TX Modes with
-                            External Frame Syncs */
-#define ANOMALY_05000189 /* False Protection Exceptions caused by Speculative
-                            Instruction or Data Fetches, or by Fetches at the
-                            boundary of reserved memory space */
-#define ANOMALY_05000193 /* False Flag Pin Interrupts on Edge Sensitive Inputs
-                            when polarity setting is changed */
-#define ANOMALY_05000194 /* Sport Restarting in specific modes may cause data
-                            corruption */
-#define ANOMALY_05000199 /* DMA current address shows wrong value during carry
-                            fix */
-#define ANOMALY_05000201 /* Receive frame sync not ignored during active
-                            frames in sport MCM */
-#define ANOMALY_05000203 /* Specific sequence that can cause DMA error or DMA
-                            stopping */
-#if defined(CONFIG_BF533)
-#define ANOMALY_05000204 /* Incorrect data read with write-through cache and
-                            allocate cache lines on reads only mode */
-#endif /* CONFIG_BF533 */
-#define ANOMALY_05000207 /* Recovery from "brown-out" condition */
-#define ANOMALY_05000209 /* Speed-Path in computational unit affects certain
-                            instructions */
-#define ANOMALY_05000233 /* PPI_FS3 is not driven in 2 or 3 internal Frame
-                            Sync Transmit Mode */
-#define ANOMALY_05000271 /* Spontaneous reset of Internal Voltage Regulator */
-#endif /* only on 0.3 silicon */
+/* Watchpoints (Hardware Breakpoints) are not supported */
+#define ANOMALY_05000067 (__SILICON_REVISION__ < 3)
+/* Reserved bits in SYSCFG register not set at power on */
+#define ANOMALY_05000109 (__SILICON_REVISION__ < 3)
+/* Trace Buffers may record discontinuities into emulation mode and/or exception, NMI, reset handlers */
+#define ANOMALY_05000116 (__SILICON_REVISION__ < 3)
+/* DTEST_COMMAND initiated memory access may be incorrect if data cache or DMA is active */
+#define ANOMALY_05000123 (__SILICON_REVISION__ < 3)
+/* DMA Lock-up at CCLK to SCLK ratios of 4:1, 2:1, or 1:1 */
+#define ANOMALY_05000124 (__SILICON_REVISION__ < 3)
+/* Erroneous exception when enabling cache */
+#define ANOMALY_05000125 (__SILICON_REVISION__ < 3)
+/* SPI clock polarity and phase bits incorrect during booting */
+#define ANOMALY_05000126 (__SILICON_REVISION__ < 3)
+/* DMEM_CONTROL is not set on Reset */
+#define ANOMALY_05000137 (__SILICON_REVISION__ < 3)
+/* SPI boot will not complete if there is a zero fill block in the loader file */
+#define ANOMALY_05000138 (__SILICON_REVISION__ < 3)
+/* Allowing the SPORT RX FIFO to fill will cause an overflow */
+#define ANOMALY_05000140 (__SILICON_REVISION__ < 3)
+/* An Infinite Stall occurs with a particular sequence of consecutive dual dag events */
+#define ANOMALY_05000141 (__SILICON_REVISION__ < 3)
+/* Interrupts may be lost when a programmable input flag is configured to be edge sensitive */
+#define ANOMALY_05000142 (__SILICON_REVISION__ < 3)
+/* A read from external memory may return a wrong value with data cache enabled */
+#define ANOMALY_05000143 (__SILICON_REVISION__ < 3)
+/* DMA and TESTSET conflict when both are accessing external memory */
+#define ANOMALY_05000144 (__SILICON_REVISION__ < 3)
+/* In PWM_OUT mode, you must enable the PPI block to generate a waveform from PPI_CLK */
+#define ANOMALY_05000145 (__SILICON_REVISION__ < 3)
+/* MDMA may lose the first few words of a descriptor chain */
+#define ANOMALY_05000146 (__SILICON_REVISION__ < 3)
+/* The source MDMA descriptor may stop with a DMA Error */
+#define ANOMALY_05000147 (__SILICON_REVISION__ < 3)
+/* When booting from a 16-bit asynchronous memory device, the upper 8-bits of each word must be 0x00 */
+#define ANOMALY_05000148 (__SILICON_REVISION__ < 3)
+/* Frame Delay in SPORT Multichannel Mode */
+#define ANOMALY_05000153 (__SILICON_REVISION__ < 3)
+/* SPORT TFS signal is active in Multi-channel mode outside of valid channels */
+#define ANOMALY_05000154 (__SILICON_REVISION__ < 3)
+/* Timer1 can not be used for PWMOUT mode when a certain PPI mode is in use */
+#define ANOMALY_05000155 (__SILICON_REVISION__ < 3)
+/* A killed 32-bit System MMR write will lead to the next system MMR access thinking it should be 32-bit. */
+#define ANOMALY_05000157 (__SILICON_REVISION__ < 3)
+/* SPORT transmit data is not gated by external frame sync in certain conditions */
+#define ANOMALY_05000163 (__SILICON_REVISION__ < 3)
+/* SDRAM auto-refresh and subsequent Power Ups */
+#define ANOMALY_05000168 (__SILICON_REVISION__ < 3)
+/* DATA CPLB page miss can result in lost write-through cache data writes */
+#define ANOMALY_05000169 (__SILICON_REVISION__ < 3)
+/* DMA vs Core accesses to external memory */
+#define ANOMALY_05000173 (__SILICON_REVISION__ < 3)
+/* Cache Fill Buffer Data lost */
+#define ANOMALY_05000174 (__SILICON_REVISION__ < 3)
+/* Overlapping Sequencer and Memory Stalls */
+#define ANOMALY_05000175 (__SILICON_REVISION__ < 3)
+/* Multiplication of (-1) by (-1) followed by an accumulator saturation */
+#define ANOMALY_05000176 (__SILICON_REVISION__ < 3)
+/* Disabling the PPI resets the PPI configuration registers */
+#define ANOMALY_05000181 (__SILICON_REVISION__ < 3)
+/* PPI TX Mode with 2 External Frame Syncs */
+#define ANOMALY_05000185 (__SILICON_REVISION__ < 3)
+/* PPI does not invert the Driving PPICLK edge in Transmit Modes */
+#define ANOMALY_05000191 (__SILICON_REVISION__ < 3)
+/* In PPI Transmit Modes with External Frame Syncs POLC */
+#define ANOMALY_05000192 (__SILICON_REVISION__ < 3)
+/* Internal Voltage Regulator may not start up */
+#define ANOMALY_05000206 (__SILICON_REVISION__ < 3)
 
-#if defined(CONFIG_BF_REV_0_2)
-#define ANOMALY_05000067 /* Watchpoints (Hardware Breakpoints) are not
-                         *  supported */
-#define ANOMALY_05000109 /* Reserved bits in SYSCFG register not set at
-                         *  power on */
-#define ANOMALY_05000116 /* Trace Buffers may record discontinuities into
-                         *  emulation mode and/or exception, NMI, reset
-                         *  handlers */
-#define ANOMALY_05000123 /* DTEST_COMMAND initiated memory access may be
-                         *  incorrect if data cache or DMA is active */
-#define ANOMALY_05000124 /* DMA Lock-up at CCLK to SCLK ratios of 4:1, 2:1,
-                         *  or 1:1 */
-#define ANOMALY_05000125 /* Erroneous exception when enabling cache */
-#define ANOMALY_05000126 /* SPI clock polarity and phase bits incorrect
-                         *  during booting */
-#define ANOMALY_05000137 /* DMEM_CONTROL is not set on Reset */
-#define ANOMALY_05000138 /* SPI boot will not complete if there is a zero fill
-                         * block in the loader file */
-#define ANOMALY_05000140 /* Allowing the SPORT RX FIFO to fill will cause an
-                         *  overflow */
-#define ANOMALY_05000141 /* An Infinite Stall occurs with a particular sequence
-                         *  of consecutive dual dag events */
-#define ANOMALY_05000142 /* Interrupts may be lost when a programmable input
-                         *  flag is configured to be edge sensitive */
-#define ANOMALY_05000143 /* A read from external memory may return a wrong
-                         *  value with data cache enabled */
-#define ANOMALY_05000144 /* DMA and TESTSET conflict when both are accessing
-                         *  external memory */
-#define ANOMALY_05000145 /* In PWM_OUT mode, you must enable the PPI block to
-                         *  generate a waveform from PPI_CLK */
-#define ANOMALY_05000146 /* MDMA may lose the first few words of a descriptor
-                         *  chain */
-#define ANOMALY_05000147 /* The source MDMA descriptor may stop with a DMA
-                         *  Error */
-#define ANOMALY_05000148 /* When booting from a 16-bit asynchronous memory
-                         *  device, the upper 8-bits of each word must be
-                         *  0x00 */
-#define ANOMALY_05000153 /* Frame Delay in SPORT Multichannel Mode */
-#define ANOMALY_05000154 /* SPORT TFS signal is active in Multi-channel mode
-                         *  outside of valid channels */
-#define ANOMALY_05000155 /* Timer1 can not be used for PWMOUT mode when a
-                         *  certain PPI mode is in use */
-#define ANOMALY_05000157 /* A killed 32-bit System MMR write will lead to
-                         *  the next system MMR access thinking it should be
-                         *  32-bit. */
-#define ANOMALY_05000163 /* SPORT transmit data is not gated by external frame
-                         *  sync in certain conditions */
-#define ANOMALY_05000168 /* SDRAM auto-refresh and subsequent Power Ups */
-#define ANOMALY_05000169 /* DATA CPLB page miss can result in lost
-                         *  write-through cache data writes */
-#define ANOMALY_05000173 /* DMA vs Core accesses to external memory */
-#define ANOMALY_05000174 /* Cache Fill Buffer Data lost */
-#define ANOMALY_05000175 /* Overlapping Sequencer and Memory Stalls */
-#define ANOMALY_05000176 /* Multiplication of (-1) by (-1) followed by an
-                         *  accumulator saturation */
-#define ANOMALY_05000181 /* Disabling the PPI resets the PPI configuration
-                         *  registers */
-#define ANOMALY_05000185 /* PPI TX Mode with 2 External Frame Syncs */
-#define ANOMALY_05000191 /* PPI does not invert the Driving PPICLK edge in
-                         *  Transmit Modes */
-#define ANOMALY_05000192 /* In PPI Transmit Modes with External Frame Syncs
-                         *  POLC */
-#define ANOMALY_05000206 /* Internal Voltage Regulator may not start up */
+/* Anomalies that don't exist on this proc */
+#define ANOMALY_05000266 (0)
+#define ANOMALY_05000323 (0)
 
 #endif
-
-#endif /*  _MACH_ANOMALY_H_ */
index 185fc12848589fac1cb4f623e074f969383d3bc9..12a4169319916ae58cecedcebea0f6f783e08438 100644 (file)
 /***************************/
 
 
-#define BLKFIN_DSUBBANKS       4
-#define BLKFIN_DWAYS           2
-#define BLKFIN_DLINES          64
-#define BLKFIN_ISUBBANKS       4
-#define BLKFIN_IWAYS           4
-#define BLKFIN_ILINES          32
+#define BFIN_DSUBBANKS 4
+#define BFIN_DWAYS             2
+#define BFIN_DLINES            64
+#define BFIN_ISUBBANKS 4
+#define BFIN_IWAYS             4
+#define BFIN_ILINES            32
 
 #define WAY0_L                 0x1
 #define WAY1_L                 0x2
 
 #define AMGCTLVAL      (V_AMBEN | V_AMCKEN | V_CDPRIO)
 
-#define MAX_VC 650000000
-#define MIN_VC 50000000
-
-#ifdef CONFIG_BFIN_KERNEL_CLOCK
-/********************************PLL Settings **************************************/
-#if (CONFIG_VCO_MULT < 0)
-#error "VCO Multiplier is less than 0. Please select a different value"
-#endif
-
-#if (CONFIG_VCO_MULT == 0)
-#error "VCO Multiplier should be greater than 0. Please select a different value"
-#endif
-
-#if (CONFIG_VCO_MULT > 64)
-#error "VCO Multiplier is more than 64. Please select a different value"
-#endif
-
-#ifndef CONFIG_CLKIN_HALF
-#define CONFIG_VCO_HZ  (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)
-#else
-#define CONFIG_VCO_HZ  ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2)
-#endif
-
-#ifndef CONFIG_PLL_BYPASS
-#define CONFIG_CCLK_HZ (CONFIG_VCO_HZ/CONFIG_CCLK_DIV)
-#define CONFIG_SCLK_HZ (CONFIG_VCO_HZ/CONFIG_SCLK_DIV)
-#else
-#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ
-#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ
-#endif
-
-#if (CONFIG_SCLK_DIV < 1)
-#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
-#endif
-
-#if (CONFIG_SCLK_DIV > 15)
-#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
-#endif
-
-#if (CONFIG_CCLK_DIV != 1)
-#if (CONFIG_CCLK_DIV != 2)
-#if (CONFIG_CCLK_DIV != 4)
-#if (CONFIG_CCLK_DIV != 8)
-#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value"
-#endif
-#endif
-#endif
-#endif
-
-#if (CONFIG_VCO_HZ > MAX_VC)
-#error "VCO selected is more than maximum value. Please change the VCO multipler"
-#endif
-
-#if (CONFIG_SCLK_HZ > 133000000)
-#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier"
-#endif
-
-#if (CONFIG_SCLK_HZ < 27000000)
-#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier"
-#endif
-
-#if (CONFIG_SCLK_HZ > CONFIG_CCLK_HZ)
-#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ)
-#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ)
-#error "Please select sclk less than cclk"
-#endif
-#endif
-#endif
-
-#if (CONFIG_CCLK_DIV == 1)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV1
-#endif
-#if (CONFIG_CCLK_DIV == 2)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV2
-#endif
-#if (CONFIG_CCLK_DIV == 4)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV4
-#endif
-#if (CONFIG_CCLK_DIV == 8)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV8
-#endif
-#ifndef CONFIG_CCLK_ACT_DIV
-#define CONFIG_CCLK_ACT_DIV   CONFIG_CCLK_DIV_not_defined_properly
-#endif
-
-#if defined(ANOMALY_05000273) && (CONFIG_CCLK_DIV == 1)
-#error ANOMALY 05000273, please make sure CCLK is at least 2x SCLK
-#endif
-
-#endif                         /* CONFIG_BFIN_KERNEL_CLOCK */
-
 #ifdef CONFIG_BF533
 #define CPU "BF533"
 #define CPUID 0x027a5000
 #define CPUID 0x0
 #endif
 
-#if (CONFIG_MEM_SIZE % 4)
-#error "SDRAM mem size must be multible of 4MB"
-#endif
-
-#define SDRAM_IGENERIC    (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
-#define SDRAM_IKERNEL     (SDRAM_IGENERIC | CPLB_LOCK)
-#define L1_IMEMORY        (               CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
-#define SDRAM_INON_CHBL   (               CPLB_USER_RD | CPLB_VALID)
-
-/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/
-
-#define ANOMALY_05000158_WORKAROUND            0x200
-#ifdef CONFIG_BLKFIN_WB                /*Write Back Policy */
-#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_DIRTY \
-                       | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
-#else                          /*Write Through */
-#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW  | CPLB_DIRTY \
-                       | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
-#endif
-
-#define L1_DMEMORY       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
-#define SDRAM_DNON_CHBL  (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)
-#define SDRAM_EBIU       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)
-#define SDRAM_OOPS      (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
-
-#define SIZE_1K 0x00000400     /* 1K */
-#define SIZE_4K 0x00001000     /* 4K */
-#define SIZE_1M 0x00100000     /* 1M */
-#define SIZE_4M 0x00400000     /* 4M */
-
-#define MAX_CPLBS (16 * 2)
-
-/*
-* Number of required data CPLB switchtable entries
-* MEMSIZE / 4 (we mostly install 4M page size CPLBs
-* approx 16 for smaller 1MB page size CPLBs for allignment purposes
-* 1 for L1 Data Memory
-* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
-* 1 for ASYNC Memory
-*/
-
-
-#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1) * 2)
-
-/*
-* Number of required instruction CPLB switchtable entries
-* MEMSIZE / 4 (we mostly install 4M page size CPLBs
-* approx 12 for smaller 1MB page size CPLBs for allignment purposes
-* 1 for L1 Instruction Memory
-* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
-*/
-
-#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1) * 2)
-
 #endif                         /* __MACH_BF533_H__  */
index e4384491e97288308fdcd8ee8998de2285d69034..f3b240abf170b550d58496d1d8948e9ba3f9d96c 100644 (file)
@@ -38,7 +38,7 @@
 #include "defBF532.h"
 #include "anomaly.h"
 
-#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY))
+#if !defined(__ASSEMBLY__)
 #include "cdefBF532.h"
 #endif
 
index 74f967b235e2a776f43b50f60fab26e41d1e6104..c803e14b529c4aef65cee494d54193e08ae152bb 100644 (file)
 
 #ifndef _CDEF_BF532_H
 #define _CDEF_BF532_H
-/*
-#if !defined(__ADSPLPBLACKFIN__)
-#warning cdefBF532.h should only be included for 532 compatible chips.
-#endif
-*/
+
+#include <asm/blackfin.h>
+
 /*include all Core registers and bit definitions*/
 #include "defBF532.h"
 
@@ -65,7 +63,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        bfin_write32(SIC_IWR, IWR_ENABLE(0));
 
        bfin_write16(VR_CTL, val);
-       __builtin_bfin_ssync();
+       SSYNC();
 
        local_irq_save(flags);
        asm("IDLE;");
@@ -132,10 +130,6 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
 /* General Purpose IO (0xFFC0 2400-0xFFC0 27FF) */
 #define bfin_read_FIO_DIR()                  bfin_read16(FIO_DIR)
 #define bfin_write_FIO_DIR(val)              bfin_write16(FIO_DIR,val)
-#define bfin_read_FIO_FLAG_C()               bfin_read16(FIO_FLAG_C)
-#define bfin_write_FIO_FLAG_C(val)           bfin_write16(FIO_FLAG_C,val)
-#define bfin_read_FIO_FLAG_S()               bfin_read16(FIO_FLAG_S)
-#define bfin_write_FIO_FLAG_S(val)           bfin_write16(FIO_FLAG_S,val)
 #define bfin_read_FIO_MASKA_C()              bfin_read16(FIO_MASKA_C)
 #define bfin_write_FIO_MASKA_C(val)          bfin_write16(FIO_MASKA_C,val)
 #define bfin_read_FIO_MASKA_S()              bfin_read16(FIO_MASKA_S)
@@ -152,10 +146,6 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
 #define bfin_write_FIO_BOTH(val)             bfin_write16(FIO_BOTH,val)
 #define bfin_read_FIO_INEN()                 bfin_read16(FIO_INEN)
 #define bfin_write_FIO_INEN(val)             bfin_write16(FIO_INEN,val)
-#define bfin_read_FIO_FLAG_D()               bfin_read16(FIO_FLAG_D)
-#define bfin_write_FIO_FLAG_D(val)           bfin_write16(FIO_FLAG_D,val)
-#define bfin_read_FIO_FLAG_T()               bfin_read16(FIO_FLAG_T)
-#define bfin_write_FIO_FLAG_T(val)           bfin_write16(FIO_FLAG_T,val)
 #define bfin_read_FIO_MASKA_D()              bfin_read16(FIO_MASKA_D)
 #define bfin_write_FIO_MASKA_D(val)          bfin_write16(FIO_MASKA_D,val)
 #define bfin_read_FIO_MASKA_T()              bfin_read16(FIO_MASKA_T)
@@ -165,6 +155,50 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
 #define bfin_read_FIO_MASKB_T()              bfin_read16(FIO_MASKB_T)
 #define bfin_write_FIO_MASKB_T(val)          bfin_write16(FIO_MASKB_T,val)
 
+
+#if ANOMALY_05000311
+#define BFIN_WRITE_FIO_FLAG(name) \
+static __inline__ void bfin_write_FIO_FLAG_ ## name (unsigned short val)\
+{\
+       unsigned long flags;\
+       local_irq_save(flags);\
+       bfin_write16(FIO_FLAG_ ## name,val);\
+       bfin_read_CHIPID();\
+       local_irq_restore(flags);\
+}
+BFIN_WRITE_FIO_FLAG(D)
+BFIN_WRITE_FIO_FLAG(C)
+BFIN_WRITE_FIO_FLAG(S)
+BFIN_WRITE_FIO_FLAG(T)
+
+#define BFIN_READ_FIO_FLAG(name) \
+static __inline__ unsigned short bfin_read_FIO_FLAG_ ## name (void)\
+{\
+       unsigned long flags;\
+       unsigned short ret;\
+       local_irq_save(flags);\
+       ret = bfin_read16(FIO_FLAG_ ## name);\
+       bfin_read_CHIPID();\
+       local_irq_restore(flags);\
+       return ret;\
+}
+BFIN_READ_FIO_FLAG(D)
+BFIN_READ_FIO_FLAG(C)
+BFIN_READ_FIO_FLAG(S)
+BFIN_READ_FIO_FLAG(T)
+
+#else
+#define bfin_write_FIO_FLAG_D(val)           bfin_write16(FIO_FLAG_D,val)
+#define bfin_write_FIO_FLAG_C(val)           bfin_write16(FIO_FLAG_C,val)
+#define bfin_write_FIO_FLAG_S(val)           bfin_write16(FIO_FLAG_S,val)
+#define bfin_write_FIO_FLAG_T(val)           bfin_write16(FIO_FLAG_T,val)
+#define bfin_read_FIO_FLAG_T()               bfin_read16(FIO_FLAG_T)
+#define bfin_read_FIO_FLAG_C()               bfin_read16(FIO_FLAG_C)
+#define bfin_read_FIO_FLAG_S()               bfin_read16(FIO_FLAG_S)
+#define bfin_read_FIO_FLAG_D()               bfin_read16(FIO_FLAG_D)
+#endif
+
+
 /* DMA Controller */
 #define bfin_read_DMA0_CONFIG()              bfin_read16(DMA0_CONFIG)
 #define bfin_write_DMA0_CONFIG(val)          bfin_write16(DMA0_CONFIG,val)
index 6a3cf93f8b577c2efcef0e2657da785bcd1658df..37134aaf9954f8fcaa2343f45406e9e0f00ae667 100644 (file)
 #define UART_GCTL                               0xFFC00424     /* Global Control Register */
 
 /* SPI Controller (0xFFC00500 - 0xFFC005FF) */
+#define SPI0_REGBASE                   0xFFC00500
 #define SPI_CTL                        0xFFC00500      /* SPI Control Register */
 #define SPI_FLG                        0xFFC00504      /* SPI Flag register */
 #define SPI_STAT                       0xFFC00508      /* SPI Status register */
 #define GM                     0x00000008      /* When RDBR full, get more (=1) data or discard (=0) incoming Data */
 #define PSSE                   0x00000010      /* Enable (=1) Slave-Select input for Master. */
 #define EMISO                  0x00000020      /* Enable (=1) MISO pin as an output. */
-#define SPI_LEN                0x00000100      /* Word length (0 => 8 bits, 1 => 16 bits) */
+#define SIZE                   0x00000100      /* Word length (0 => 8 bits, 1 => 16 bits) */
 #define LSBF                   0x00000200      /* Data format (0 => MSB sent/received first 1 => LSB sent/received first) */
 #define CPHA                   0x00000400      /* Clock phase (0 => SPICLK starts toggling in middle of xfer, 1 => SPICLK toggles at the beginning of xfer. */
 #define CPOL                   0x00000800      /* Clock polarity (0 => active-high, 1 => active-low) */
index 9879e68e315c71a5c7afc8b26b60e4f9101c1c75..452fb825d891122ce674eda8b169538dcfdc0f85 100644 (file)
@@ -128,6 +128,8 @@ Core        Emulation               **
 #define IRQ_PF14               47
 #define IRQ_PF15               48
 
+#define GPIO_IRQ_BASE          IRQ_PF0
+
 #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
 #define        NR_IRQS         (IRQ_PF15+1)
 #else
index e84baa3e939d84f015dcd37b4ef2cd61e08cfa95..94d8c4062eb7c154207131f1085d034c4080e11e 100644 (file)
 
 /* Level 1 Memory */
 
-#ifdef CONFIG_BLKFIN_CACHE
-#define BLKFIN_ICACHESIZE      (16*1024)
+#ifdef CONFIG_BFIN_ICACHE
+#define BFIN_ICACHESIZE        (16*1024)
 #else
-#define BLKFIN_ICACHESIZE      (0*1024)
+#define BFIN_ICACHESIZE        (0*1024)
 #endif
 
 /* Memory Map for ADSP-BF533 processors */
 #define L1_DATA_A_START     0xFF800000
 #define L1_DATA_B_START     0xFF900000
 
-#ifdef CONFIG_BLKFIN_CACHE
+#ifdef CONFIG_BFIN_ICACHE
 #define L1_CODE_LENGTH      (0x14000 - 0x4000)
 #else
 #define L1_CODE_LENGTH      0x14000
 #endif
 
-#ifdef CONFIG_BLKFIN_DCACHE
+#ifdef CONFIG_BFIN_DCACHE
 
-#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#ifdef CONFIG_BFIN_DCACHE_BANKA
 #define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
 #define L1_DATA_B_LENGTH      0x8000
-#define BLKFIN_DCACHESIZE      (16*1024)
-#define BLKFIN_DSUPBANKS       1
+#define BFIN_DCACHESIZE        (16*1024)
+#define BFIN_DSUPBANKS 1
 #else
 #define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
 #define L1_DATA_B_LENGTH      (0x8000 - 0x4000)
-#define BLKFIN_DCACHESIZE      (32*1024)
-#define BLKFIN_DSUPBANKS       2
+#define BFIN_DCACHESIZE        (32*1024)
+#define BFIN_DSUPBANKS 2
 #endif
 
 #else
 #define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      0x8000
 #define L1_DATA_B_LENGTH      0x8000
-#define BLKFIN_DCACHESIZE      (0*1024)
-#define BLKFIN_DSUPBANKS       0
-#endif /*CONFIG_BLKFIN_DCACHE*/
+#define BFIN_DCACHESIZE        (0*1024)
+#define BFIN_DSUPBANKS 0
+#endif /*CONFIG_BFIN_DCACHE*/
 #endif
 
 /* Memory Map for ADSP-BF532 processors */
 #define L1_DATA_A_START     0xFF804000
 #define L1_DATA_B_START     0xFF904000
 
-#ifdef CONFIG_BLKFIN_CACHE
+#ifdef CONFIG_BFIN_ICACHE
 #define L1_CODE_LENGTH      (0xC000 - 0x4000)
 #else
 #define L1_CODE_LENGTH      0xC000
 #endif
 
-#ifdef CONFIG_BLKFIN_DCACHE
+#ifdef CONFIG_BFIN_DCACHE
 
-#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#ifdef CONFIG_BFIN_DCACHE_BANKA
 #define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x4000 - 0x4000)
 #define L1_DATA_B_LENGTH      0x4000
-#define BLKFIN_DCACHESIZE      (16*1024)
-#define BLKFIN_DSUPBANKS       1
+#define BFIN_DCACHESIZE        (16*1024)
+#define BFIN_DSUPBANKS 1
 
 #else
 #define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x4000 - 0x4000)
 #define L1_DATA_B_LENGTH      (0x4000 - 0x4000)
-#define BLKFIN_DCACHESIZE      (32*1024)
-#define BLKFIN_DSUPBANKS       2
+#define BFIN_DCACHESIZE        (32*1024)
+#define BFIN_DSUPBANKS 2
 #endif
 
 #else
 #define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      0x4000
 #define L1_DATA_B_LENGTH      0x4000
-#define BLKFIN_DCACHESIZE      (0*1024)
-#define BLKFIN_DSUPBANKS       0
-#endif /*CONFIG_BLKFIN_DCACHE*/
+#define BFIN_DCACHESIZE        (0*1024)
+#define BFIN_DSUPBANKS 0
+#endif /*CONFIG_BFIN_DCACHE*/
 #endif
 
 /* Memory Map for ADSP-BF531 processors */
 #define L1_DATA_B_LENGTH      0x0000
 
 
-#ifdef CONFIG_BLKFIN_DCACHE
+#ifdef CONFIG_BFIN_DCACHE
 #define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB  | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x4000 - 0x4000)
-#define BLKFIN_DCACHESIZE      (16*1024)
-#define BLKFIN_DSUPBANKS       1
+#define BFIN_DCACHESIZE        (16*1024)
+#define BFIN_DSUPBANKS 1
 #else
 #define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB  | PORT_PREF0)
 #define L1_DATA_A_LENGTH      0x4000
-#define BLKFIN_DCACHESIZE      (0*1024)
-#define BLKFIN_DSUPBANKS       0
+#define BFIN_DCACHESIZE        (0*1024)
+#define BFIN_DSUPBANKS 0
 #endif
 
 #endif
index 4453e614c3b1b31ba91d7fa588aa2421f2bd8ee3..2b66ecf489f7ba0a9cc3bbba545236559be0b6b8 100644 (file)
-
 /*
- * File:         include/asm-blackfin/mach-bf537/anomaly.h
- * Based on:
- * Author:
- *
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
+ * File: include/asm-blackfin/mach-bf537/anomaly.h
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Copyright (C) 2004-2007 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
  */
 
 /* This file shoule be up to date with:
- *  - Revision J, June 1, 2006; ADSP-BF537 Blackfin Processor Anomaly List
- *  - Revision I, June 1, 2006; ADSP-BF536 Blackfin Processor Anomaly List
- *  - Revision J, June 1, 2006; ADSP-BF534 Blackfin Processor Anomaly List
+ *  - Revision M, March 13, 2007; ADSP-BF537 Blackfin Processor Anomaly List
+ *  - Revision L, March 13, 2007; ADSP-BF536 Blackfin Processor Anomaly List
+ *  - Revision M, March 13, 2007; ADSP-BF534 Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
 #define _MACH_ANOMALY_H_
 
 /* We do not support 0.1 silicon - sorry */
-#if (defined(CONFIG_BF_REV_0_1))
-#error Kernel will not work on BF537/6/4 Version 0.1
+#if __SILICON_REVISION__ < 2
+# error Kernel will not work on BF537 silicon version 0.0 or 0.1
 #endif
 
-#if (defined(CONFIG_BF_REV_0_3) || defined(CONFIG_BF_REV_0_2))
-#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in
-                            slot1 and store of a P register in slot 2 is not
-                            supported */
-#define ANOMALY_05000119 /* DMA_RUN bit is not valid after a Peripheral Receive
-                            Channel DMA stops */
-#define ANOMALY_05000122 /* Rx.H can not be used to access 16-bit System MMR
-                            registers. */
-#define ANOMALY_05000166 /* PPI Data Lengths Between 8 and 16 do not zero out
-                            upper bits*/
-#define ANOMALY_05000180 /* PPI_DELAY not functional in PPI modes with 0 frame
-                            syncs */
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
-#define ANOMALY_05000247 /* CLKIN Buffer Output Enable Reset Behavior Is
-                            Changed */
-#endif
-#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on
-                            SPORT external receive and transmit clocks. */
-#define ANOMALY_05000272 /* Certain data cache write through modes fail for
-                            VDDint <=0.9V */
-#define ANOMALY_05000273 /* Writes to Synchronous SDRAM memory may be lost */
-#define ANOMALY_05000277 /* Writes to a flag data register one SCLK cycle after
-                            an edge is detected may clear interrupt */
-#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is
-                            not restored */
-#define ANOMALY_05000282 /* Memory DMA corruption with 32-bit data and traffic
-                            control */
-#define ANOMALY_05000283 /* A system MMR write is stalled indefinitely when
-                            killed in a particular stage*/
-#define ANOMALY_05000310 /* False hardware errors caused by fetches at the
-                         *  boundary of reserved memory */
-#define ANOMALY_05000312 /* Errors when SSYNC, CSYNC, or loads to LT, LB and LC
-                           registers are interrupted */
-#define ANOMALY_05000313 /* PPI is level sensitive on first transfer */
-#define ANOMALY_05000322 /* EMAC RMII mode at 10-Base-T speed: RX frames not
-                         *  received properly */
+#if defined(__ADSPBF534__)
+# define ANOMALY_BF534 1
+#else
+# define ANOMALY_BF534 0
 #endif
-
-#if defined(CONFIG_BF_REV_0_2)
-#define ANOMALY_05000244 /* With instruction cache enabled, a CSYNC or SSYNC or
-                            IDLE around a Change of Control causes
-                            unpredictable results */
-#define ANOMALY_05000250 /* Incorrect Bit-Shift of Data Word in Multichannel
-                            (TDM) */
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
-#define ANOMALY_05000252 /* EMAC Tx DMA error after an early frame abort */
+#if defined(__ADSPBF536__)
+# define ANOMALY_BF536 1
+#else
+# define ANOMALY_BF536 0
 #endif
-#define ANOMALY_05000253 /* Maximum external clock speed for Timers */
-#define ANOMALY_05000255 /* Entering Hibernate Mode with RTC Seconds event
-                            interrupt not functional */
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
-#define ANOMALY_05000256 /* EMAC MDIO input latched on wrong MDC edge */
+#if defined(__ADSPBF537__)
+# define ANOMALY_BF537 1
+#else
+# define ANOMALY_BF537 0
 #endif
-#define ANOMALY_05000257 /* An interrupt or exception during short Hardware
-                            loops may cause the instruction fetch unit to
-                            malfunction */
-#define ANOMALY_05000258 /* Instruction Cache is corrupted when bit 9 and 12 of
-                            the ICPLB Data registers differ */
-#define ANOMALY_05000260 /* ICPLB_STATUS MMR register may be corrupted */
-#define ANOMALY_05000261 /* DCPLB_FAULT_ADDR MMR register may be corrupted */
-#define ANOMALY_05000262 /* Stores to data cache may be lost */
-#define ANOMALY_05000263 /* Hardware loop corrupted when taking an ICPLB exception */
-#define ANOMALY_05000264 /* A Sync instruction (CSYNC, SSYNC) or an IDLE
-                            instruction will cause an infinite stall in the
-                            second to last instruction in a hardware loop */
-#define ANOMALY_05000268 /* Memory DMA error when peripheral DMA is running
-                            and non-zero DEB_TRAFFIC_PERIOD value */
-#define ANOMALY_05000270 /* High I/O activity causes the output voltage of the
-                            internal voltage regulator (VDDint) to decrease */
-#define ANOMALY_05000277 /* Writes to a flag data register one SCLK cycle after
-                            an edge is detected may clear interrupt */
-#define ANOMALY_05000278 /* Disabling Peripherals with DMA running may cause
-                            DMA system instability */
-#define ANOMALY_05000280 /* SPI Master boot mode does not work well with
-                            Atmel Dataflash devices */
-#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context
-                         *  is not restored */
-#define ANOMALY_05000282 /* Memory DMA corruption with 32-bit data and traffic
-                         *  control */
-#define ANOMALY_05000283 /* System MMR Write Is Stalled Indefinitely When
-                         *  Killed in a Particular Stage */
-#define ANOMALY_05000285 /* New Feature: EMAC TX DMA Word Alignment
-                         *  (Not Available On Older Silicon) */
-#define ANOMALY_05000288 /* SPORTs may receive bad data if FIFOs fill up */
-#define ANOMALY_05000315 /* Killed System MMR Write Completes Erroneously
-                         *  On Next System MMR Access */
-#define ANOMALY_05000316 /* EMAC RMII mode: collisions occur in Full Duplex
-                         *  mode */
-#define ANOMALY_05000321 /* EMAC RMII mode: TX frames in half duplex fail with
-                         *  status No Carrier */
-#endif  /* CONFIG_BF_REV_0_2 */
 
-#endif /* _MACH_ANOMALY_H_ */
+/* Multi-issue instruction with dsp32shiftimm in slot1 and P-reg store in slot 2 not supported */
+#define ANOMALY_05000074 (1)
+/* DMA_RUN bit is not valid after a Peripheral Receive Channel DMA stops */
+#define ANOMALY_05000119 (1)
+/* Rx.H cannot be used to access 16-bit System MMR registers */
+#define ANOMALY_05000122 (1)
+/* Killed 32-bit MMR write leads to next system MMR access thinking it should be 32-bit */
+#define ANOMALY_05000157 (__SILICON_REVISION__ < 2)
+/* PPI_DELAY not functional in PPI modes with 0 frame syncs */
+#define ANOMALY_05000180 (1)
+/* Instruction Cache Is Not Functional */
+#define ANOMALY_05000237 (__SILICON_REVISION__ < 2)
+/* If i-cache is on, CSYNC/SSYNC/IDLE around Change of Control causes failures */
+#define ANOMALY_05000244 (__SILICON_REVISION__ < 3)
+/* Spurious Hardware Error from an access in the shadow of a conditional branch */
+#define ANOMALY_05000245 (1)
+/* CLKIN Buffer Output Enable Reset Behavior Is Changed */
+#define ANOMALY_05000247 (1)
+/* Incorrect Bit-Shift of Data Word in Multichannel (TDM) mode in certain conditions */
+#define ANOMALY_05000250 (__SILICON_REVISION__ < 3)
+/* EMAC Tx DMA error after an early frame abort */
+#define ANOMALY_05000252 (__SILICON_REVISION__ < 3)
+/* Maximum external clock speed for Timers */
+#define ANOMALY_05000253 (__SILICON_REVISION__ < 3)
+/* Incorrect Timer Pulse Width in Single-Shot PWM_OUT mode with external clock */
+#define ANOMALY_05000254 (__SILICON_REVISION__ > 2)
+/* Entering Hibernate Mode with RTC Seconds event interrupt not functional */
+#define ANOMALY_05000255 (__SILICON_REVISION__ < 3)
+/* EMAC MDIO input latched on wrong MDC edge */
+#define ANOMALY_05000256 (__SILICON_REVISION__ < 3)
+/* Interrupt/Exception during short hardware loop may cause bad instruction fetches */
+#define ANOMALY_05000257 (__SILICON_REVISION__ < 3)
+/* Instruction Cache is corrupted when bits 9 and 12 of the ICPLB Data registers differ */
+#define ANOMALY_05000258 (((ANOMALY_BF536 || ANOMALY_BF537) && __SILICON_REVISION__ == 1) || __SILICON_REVISION__ == 2)
+/* ICPLB_STATUS MMR register may be corrupted */
+#define ANOMALY_05000260 (__SILICON_REVISION__ == 2)
+/* DCPLB_FAULT_ADDR MMR register may be corrupted */
+#define ANOMALY_05000261 (__SILICON_REVISION__ < 3)
+/* Stores to data cache may be lost */
+#define ANOMALY_05000262 (__SILICON_REVISION__ < 3)
+/* Hardware loop corrupted when taking an ICPLB exception */
+#define ANOMALY_05000263 (__SILICON_REVISION__ == 2)
+/* CSYNC/SSYNC/IDLE causes infinite stall in second to last instruction in hardware loop */
+#define ANOMALY_05000264 (__SILICON_REVISION__ < 3)
+/* Sensitivity to noise with slow input edge rates on external SPORT TX and RX clocks */
+#define ANOMALY_05000265 (1)
+/* Memory DMA error when peripheral DMA is running with non-zero DEB_TRAFFIC_PERIOD */
+#define ANOMALY_05000268 (__SILICON_REVISION__ < 3)
+/* High I/O activity causes output voltage of internal voltage regulator (VDDint) to decrease */
+#define ANOMALY_05000270 (__SILICON_REVISION__ < 3)
+/* Certain data cache write through modes fail for VDDint <=0.9V */
+#define ANOMALY_05000272 (1)
+/* Writes to Synchronous SDRAM memory may be lost */
+#define ANOMALY_05000273 (__SILICON_REVISION__ < 3)
+/* Writes to an I/O data register one SCLK cycle after an edge is detected may clear interrupt */
+#define ANOMALY_05000277 (__SILICON_REVISION__ < 3)
+/* Disabling Peripherals with DMA running may cause DMA system instability */
+#define ANOMALY_05000278 (((ANOMALY_BF536 || ANOMALY_BF537) && __SILICON_REVISION__ < 3) || (ANOMALY_BF534 && __SILICON_REVISION__ < 2))
+/* SPI Master boot mode does not work well with Atmel Data flash devices */
+#define ANOMALY_05000280 (1)
+/* False Hardware Error Exception when ISR context is not restored */
+#define ANOMALY_05000281 (__SILICON_REVISION__ < 3)
+/* Memory DMA corruption with 32-bit data and traffic control */
+#define ANOMALY_05000282 (__SILICON_REVISION__ < 3)
+/* System MMR Write Is Stalled Indefinitely When Killed in a Particular Stage */
+#define ANOMALY_05000283 (__SILICON_REVISION__ < 3)
+/* New Feature: EMAC TX DMA Word Alignment (Not Available On Older Silicon) */
+#define ANOMALY_05000285 (__SILICON_REVISION__ < 3)
+/* SPORTs may receive bad data if FIFOs fill up */
+#define ANOMALY_05000288 (__SILICON_REVISION__ < 3)
+/* Memory to memory DMA source/destination descriptors must be in same memory space */
+#define ANOMALY_05000301 (1)
+/* SSYNCs After Writes To CAN/DMA MMR Registers Are Not Always Handled Correctly */
+#define ANOMALY_05000304 (__SILICON_REVISION__ < 3)
+/* New Feature: Additional Hysteresis on SPORT Input Pins (Not Available On Older Silicon) */
+#define ANOMALY_05000305 (__SILICON_REVISION__ < 3)
+/* SCKELOW Bit Does Not Maintain State Through Hibernate */
+#define ANOMALY_05000307 (__SILICON_REVISION__ < 3)
+/* Writing UART_THR while UART clock is disabled sends erroneous start bit */
+#define ANOMALY_05000309 (__SILICON_REVISION__ < 3)
+/* False hardware errors caused by fetches at the boundary of reserved memory */
+#define ANOMALY_05000310 (1)
+/* Errors when SSYNC, CSYNC, or loads to LT, LB and LC registers are interrupted */
+#define ANOMALY_05000312 (1)
+/* PPI is level sensitive on first transfer */
+#define ANOMALY_05000313 (1)
+/* Killed System MMR Write Completes Erroneously On Next System MMR Access */
+#define ANOMALY_05000315 (__SILICON_REVISION__ < 3)
+/* EMAC RMII mode: collisions occur in Full Duplex mode */
+#define ANOMALY_05000316 (__SILICON_REVISION__ < 3)
+/* EMAC RMII mode: TX frames in half duplex fail with status No Carrier */
+#define ANOMALY_05000321 (__SILICON_REVISION__ < 3)
+/* EMAC RMII mode at 10-Base-T speed: RX frames not received properly */
+#define ANOMALY_05000322 (1)
+
+/* Anomalies that don't exist on this proc */
+#define ANOMALY_05000125 (0)
+#define ANOMALY_05000158 (0)
+#define ANOMALY_05000183 (0)
+#define ANOMALY_05000198 (0)
+#define ANOMALY_05000230 (0)
+#define ANOMALY_05000266 (0)
+#define ANOMALY_05000311 (0)
+#define ANOMALY_05000323 (0)
+
+#endif
index b8924cd7730c62ff17220bd4c59ad3697f953f24..cfe2a221112ef12ec97a8fbda0790310e55cb016 100644 (file)
 /***************************/
 
 
-#define BLKFIN_DSUBBANKS       4
-#define BLKFIN_DWAYS           2
-#define BLKFIN_DLINES          64
-#define BLKFIN_ISUBBANKS       4
-#define BLKFIN_IWAYS           4
-#define BLKFIN_ILINES          32
+#define BFIN_DSUBBANKS 4
+#define BFIN_DWAYS             2
+#define BFIN_DLINES            64
+#define BFIN_ISUBBANKS 4
+#define BFIN_IWAYS             4
+#define BFIN_ILINES            32
 
 #define WAY0_L                 0x1
 #define WAY1_L                 0x2
 
 #define AMGCTLVAL      (V_AMBEN | V_AMCKEN | V_CDPRIO)
 
-#define MAX_VC 650000000
-#define MIN_VC 50000000
-
-/********************************PLL Settings **************************************/
-#ifdef CONFIG_BFIN_KERNEL_CLOCK
-#if (CONFIG_VCO_MULT < 0)
-#error "VCO Multiplier is less than 0. Please select a different value"
-#endif
-
-#if (CONFIG_VCO_MULT == 0)
-#error "VCO Multiplier should be greater than 0. Please select a different value"
-#endif
-
-#if (CONFIG_VCO_MULT > 64)
-#error "VCO Multiplier is more than 64. Please select a different value"
-#endif
-
-#ifndef CONFIG_CLKIN_HALF
-#define CONFIG_VCO_HZ  (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)
-#else
-#define CONFIG_VCO_HZ  ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2)
-#endif
-
-#ifndef CONFIG_PLL_BYPASS
-#define CONFIG_CCLK_HZ (CONFIG_VCO_HZ/CONFIG_CCLK_DIV)
-#define CONFIG_SCLK_HZ (CONFIG_VCO_HZ/CONFIG_SCLK_DIV)
-#else
-#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ
-#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ
-#endif
-
-#if (CONFIG_SCLK_DIV < 1)
-#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
-#endif
-
-#if (CONFIG_SCLK_DIV > 15)
-#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
-#endif
-
-#if (CONFIG_CCLK_DIV != 1)
-#if (CONFIG_CCLK_DIV != 2)
-#if (CONFIG_CCLK_DIV != 4)
-#if (CONFIG_CCLK_DIV != 8)
-#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value"
-#endif
-#endif
-#endif
-#endif
-
-#if (CONFIG_VCO_HZ > MAX_VC)
-#error "VCO selected is more than maximum value. Please change the VCO multipler"
-#endif
-
-#if (CONFIG_SCLK_HZ > 133000000)
-#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier"
-#endif
-
-#if (CONFIG_SCLK_HZ < 27000000)
-#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier"
-#endif
-
-#if (CONFIG_SCLK_HZ >= CONFIG_CCLK_HZ)
-#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ)
-#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ)
-#error "Please select sclk less than cclk"
-#endif
-#endif
-#endif
-
-#if (CONFIG_CCLK_DIV == 1)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV1
-#endif
-#if (CONFIG_CCLK_DIV == 2)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV2
-#endif
-#if (CONFIG_CCLK_DIV == 4)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV4
-#endif
-#if (CONFIG_CCLK_DIV == 8)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV8
-#endif
-#ifndef CONFIG_CCLK_ACT_DIV
-#define CONFIG_CCLK_ACT_DIV   CONFIG_CCLK_DIV_not_defined_properly
-#endif
-
-#if defined(ANOMALY_05000273) && (CONFIG_CCLK_DIV == 1)
-#error ANOMALY 05000273, please make sure CCLK is at least 2x SCLK
-#endif
-
-#endif                         /* CONFIG_BFIN_KERNEL_CLOCK */
-
 #ifdef CONFIG_BF537
 #define CPU "BF537"
 #define CPUID 0x027c8000
 #define CPUID 0x0
 #endif
 
-#if (CONFIG_MEM_SIZE % 4)
-#error "SDRAM mem size must be multible of 4MB"
-#endif
-
-#define SDRAM_IGENERIC    (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
-#define SDRAM_IKERNEL     (SDRAM_IGENERIC | CPLB_LOCK)
-#define L1_IMEMORY        (               CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
-#define SDRAM_INON_CHBL   (               CPLB_USER_RD | CPLB_VALID)
-
-/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/
-
-#define ANOMALY_05000158_WORKAROUND            0x200
-#ifdef CONFIG_BLKFIN_WB                /*Write Back Policy */
-#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_DIRTY \
-                       | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
-#else                          /*Write Through */
-#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW \
-                       | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
-#endif
-
-
-#define L1_DMEMORY       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )
-#define SDRAM_DNON_CHBL  (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
-#define SDRAM_EBIU       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
-#define SDRAM_OOPS      (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )
-
-#define SIZE_1K 0x00000400     /* 1K */
-#define SIZE_4K 0x00001000     /* 4K */
-#define SIZE_1M 0x00100000     /* 1M */
-#define SIZE_4M 0x00400000     /* 4M */
-
-#define MAX_CPLBS (16 * 2)
-
-/*
-* Number of required data CPLB switchtable entries
-* MEMSIZE / 4 (we mostly install 4M page size CPLBs
-* approx 16 for smaller 1MB page size CPLBs for allignment purposes
-* 1 for L1 Data Memory
-* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
-* 1 for ASYNC Memory
-*/
-
-
-#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1) * 2)
-
-/*
-* Number of required instruction CPLB switchtable entries
-* MEMSIZE / 4 (we mostly install 4M page size CPLBs
-* approx 12 for smaller 1MB page size CPLBs for allignment purposes
-* 1 for L1 Instruction Memory
-* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
-*/
-
-#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1) * 2)
-
 #endif                         /* __MACH_BF537_H__  */
index bbd97051ec9ccb5e310a15aa389f436909a23099..53fcfa3408d0eb019157b5c5928226e75abd0dc5 100644 (file)
@@ -43,7 +43,7 @@
 #include "defBF537.h"
 #endif
 
-#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY))
+#if !defined(__ASSEMBLY__)
 #include "cdefBF534.h"
 
 /* UART 0*/
 #define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
 #define STOPCK_OFF STOPCK
 
-/* FIO USE PORT F*/
-#ifdef CONFIG_BF537_PORT_F
-#define bfin_read_PORT_FER() bfin_read_PORTF_FER()
-#define bfin_write_PORT_FER(val) bfin_write_PORTF_FER(val)
-#define bfin_read_FIO_FLAG_D() bfin_read_PORTFIO()
-#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTFIO(val)
-#define bfin_read_FIO_FLAG_C() bfin_read_PORTFIO_CLEAR()
-#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTFIO_CLEAR(val)
-#define bfin_read_FIO_FLAG_S() bfin_read_PORTFIO_SET()
-#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTFIO_SET(val)
-#define bfin_read_FIO_FLAG_T() bfin_read_PORTFIO_TOGGLE()
-#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTFIO_TOGGLE(val)
-#define bfin_read_FIO_MASKA_D() bfin_read_PORTFIO_MASKA()
-#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTFIO_MASKA(val)
-#define bfin_read_FIO_MASKA_C() bfin_read_PORTFIO_MASKA_CLEAR()
-#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTFIO_MASKA_CLEAR(val)
-#define bfin_read_FIO_MASKA_S() bfin_read_PORTFIO_MASKA_SET()
-#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTFIO_MASKA_SET(val)
-#define bfin_read_FIO_MASKA_T() bfin_read_PORTFIO_MASKA_TOGGLE()
-#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTFIO_MASKA_TOGGLE(val)
-#define bfin_read_FIO_MASKB_D() bfin_read_PORTFIO_MASKB()
-#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTFIO_MASKB(val)
-#define bfin_read_FIO_MASKB_C() bfin_read_PORTFIO_MASKB_CLEAR()
-#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTFIO_MASKB_CLEAR(val)
-#define bfin_read_FIO_MASKB_S() bfin_read_PORTFIO_MASKB_SET()
-#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTFIO_MASKB_SET(val)
-#define bfin_read_FIO_MASKB_T() bfin_read_PORTFIO_MASKB_TOGGLE()
-#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTFIO_MASKB_TOGGLE(val)
-#define bfin_read_FIO_DIR() bfin_read_PORTFIO_DIR()
-#define bfin_write_FIO_DIR(val) bfin_write_PORTFIO_DIR(val)
-#define bfin_read_FIO_POLAR() bfin_read_PORTFIO_POLAR()
-#define bfin_write_FIO_POLAR(val) bfin_write_PORTFIO_POLAR(val)
-#define bfin_read_FIO_EDGE() bfin_read_PORTFIO_EDGE()
-#define bfin_write_FIO_EDGE(val) bfin_write_PORTFIO_EDGE(val)
-#define bfin_read_FIO_BOTH() bfin_read_PORTFIO_BOTH()
-#define bfin_write_FIO_BOTH(val) bfin_write_PORTFIO_BOTH(val)
-#define bfin_read_FIO_INEN() bfin_read_PORTFIO_INEN()
-#define bfin_write_FIO_INEN(val) bfin_write_PORTFIO_INEN(val)
-
-#define bfin_read_FIO_FLAG_D() bfin_read_PORTFIO()
-#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTFIO(val)
-#define FIO_FLAG_D             PORTFIO
-#define bfin_read_FIO_FLAG_C() bfin_read_PORTFIO_CLEAR()
-#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTFIO_CLEAR(val)
-#define FIO_FLAG_C             PORTFIO_CLEAR
-#define bfin_read_FIO_FLAG_S() bfin_read_PORTFIO_SET()
-#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTFIO_SET(val)
-#define FIO_FLAG_S             PORTFIO_SET
-#define bfin_read_FIO_FLAG_T() bfin_read_PORTFIO_TOGGLE()
-#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTFIO_TOGGLE(val)
-#define FIO_FLAG_T             PORTFIO_TOGGLE
-#define bfin_read_FIO_MASKA_D() bfin_read_PORTFIO_MASKA()
-#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTFIO_MASKA(val)
-#define FIO_MASKA_D        PORTFIO_MASKA
-#define bfin_read_FIO_MASKA_C() bfin_read_PORTFIO_MASKA_CLEAR()
-#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTFIO_MASKA_CLEAR(val)
-#define FIO_MASKA_C     PORTFIO_MASKA_CLEAR
-#define bfin_read_FIO_MASKA_S() bfin_read_PORTFIO_MASKA_SET()
-#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTFIO_MASKA_SET(val)
-#define FIO_MASKA_S     PORTFIO_MASKA_SET
-#define bfin_read_FIO_MASKA_T() bfin_read_PORTFIO_MASKA_TOGGLE()
-#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTFIO_MASKA_TOGGLE(val)
-#define FIO_MASKA_T     PORTFIO_MASKA_TOGGLE
-#define bfin_read_FIO_MASKB_D() bfin_read_PORTFIO_MASKB()
-#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTFIO_MASKB(val)
-#define FIO_MASKB_D     PORTFIO_MASKB
-#define bfin_read_FIO_MASKB_C() bfin_read_PORTFIO_MASKB_CLEAR()
-#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTFIO_MASKB_CLEAR(val)
-#define FIO_MASKB_C     PORTFIO_MASKB_CLEAR
-#define bfin_read_FIO_MASKB_S() bfin_read_PORTFIO_MASKB_SET()
-#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTFIO_MASKB_SET(val)
-#define FIO_MASKB_S     PORTFIO_MASKB_SET
-#define bfin_read_FIO_MASKB_T() bfin_read_PORTFIO_MASKB_TOGGLE()
-#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTFIO_MASKB_TOGGLE(val)
-#define FIO_MASKB_T     PORTFIO_MASKB_TOGGLE
-#define bfin_read_FIO_DIR() bfin_read_PORTFIO_DIR()
-#define bfin_write_FIO_DIR(val) bfin_write_PORTFIO_DIR(val)
-#define FIO_DIR                    PORTFIO_DIR
-#define bfin_read_FIO_POLAR() bfin_read_PORTFIO_POLAR()
-#define bfin_write_FIO_POLAR(val) bfin_write_PORTFIO_POLAR(val)
-#define FIO_POLAR              PORTFIO_POLAR
-#define bfin_read_FIO_EDGE() bfin_read_PORTFIO_EDGE()
-#define bfin_write_FIO_EDGE(val) bfin_write_PORTFIO_EDGE(val)
-#define FIO_EDGE               PORTFIO_EDGE
-#define bfin_read_FIO_BOTH() bfin_read_PORTFIO_BOTH()
-#define bfin_write_FIO_BOTH(val) bfin_write_PORTFIO_BOTH(val)
-#define FIO_BOTH               PORTFIO_BOTH
-#define bfin_read_FIO_INEN() bfin_read_PORTFIO_INEN()
-#define bfin_write_FIO_INEN(val) bfin_write_PORTFIO_INEN(val)
-#define FIO_INEN               PORTFIO_INEN
-#endif
-
-/* FIO USE PORT G*/
-#ifdef CONFIG_BF537_PORT_G
-#define bfin_read_PORT_FER() bfin_read_PORTG_FER()
-#define bfin_write_PORT_FER(val) bfin_write_PORTG_FER(val)
-#define bfin_read_FIO_FLAG_D() bfin_read_PORTGIO()
-#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTGIO(val)
-#define bfin_read_FIO_FLAG_C() bfin_read_PORTGIO_CLEAR()
-#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTGIO_CLEAR(val)
-#define bfin_read_FIO_FLAG_S() bfin_read_PORTGIO_SET()
-#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTGIO_SET(val)
-#define bfin_read_FIO_FLAG_T() bfin_read_PORTGIO_TOGGLE()
-#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTGIO_TOGGLE(val)
-#define bfin_read_FIO_MASKA_D() bfin_read_PORTGIO_MASKA()
-#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTGIO_MASKA(val)
-#define bfin_read_FIO_MASKA_C() bfin_read_PORTGIO_MASKA_CLEAR()
-#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTGIO_MASKA_CLEAR(val)
-#define bfin_read_FIO_MASKA_S() bfin_read_PORTGIO_MASKA_SET()
-#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTGIO_MASKA_SET(val)
-#define bfin_read_FIO_MASKA_T() bfin_read_PORTGIO_MASKA_TOGGLE()
-#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTGIO_MASKA_TOGGLE(val)
-#define bfin_read_FIO_MASKB_D() bfin_read_PORTGIO_MASKB()
-#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTGIO_MASKB(val)
-#define bfin_read_FIO_MASKB_C() bfin_read_PORTGIO_MASKB_CLEAR()
-#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTGIO_MASKB_CLEAR(val)
-#define bfin_read_FIO_MASKB_S() bfin_read_PORTGIO_MASKB_SET()
-#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTGIO_MASKB_SET(val)
-#define bfin_read_FIO_MASKB_T() bfin_read_PORTGIO_MASKB_TOGGLE()
-#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTGIO_MASKB_TOGGLE(val)
-#define bfin_read_FIO_DIR() bfin_read_PORTGIO_DIR()
-#define bfin_write_FIO_DIR(val) bfin_write_PORTGIO_DIR(val)
-#define bfin_read_FIO_POLAR() bfin_read_PORTGIO_POLAR()
-#define bfin_write_FIO_POLAR(val) bfin_write_PORTGIO_POLAR(val)
-#define bfin_read_FIO_EDGE() bfin_read_PORTGIO_EDGE()
-#define bfin_write_FIO_EDGE(val) bfin_write_PORTGIO_EDGE(val)
-#define bfin_read_FIO_BOTH() bfin_read_PORTGIO_BOTH()
-#define bfin_write_FIO_BOTH(val) bfin_write_PORTGIO_BOTH(val)
-#define bfin_read_FIO_INEN() bfin_read_PORTGIO_INEN()
-#define bfin_write_FIO_INEN(val) bfin_write_PORTGIO_INEN(val)
-
-#define bfin_read_FIO_FLAG_D() bfin_read_PORTGIO()
-#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTGIO(val)
-#define FIO_FLAG_D             PORTGIO
-#define bfin_read_FIO_FLAG_C() bfin_read_PORTGIO_CLEAR()
-#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTGIO_CLEAR(val)
-#define FIO_FLAG_C             PORTGIO_CLEAR
-#define bfin_read_FIO_FLAG_S() bfin_read_PORTGIO_SET()
-#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTGIO_SET(val)
-#define FIO_FLAG_S             PORTGIO_SET
-#define bfin_read_FIO_FLAG_T() bfin_read_PORTGIO_TOGGLE()
-#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTGIO_TOGGLE(val)
-#define FIO_FLAG_T             PORTGIO_TOGGLE
-#define bfin_read_FIO_MASKA_D() bfin_read_PORTGIO_MASKA()
-#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTGIO_MASKA(val)
-#define FIO_MASKA_D        PORTGIO_MASKA
-#define bfin_read_FIO_MASKA_C() bfin_read_PORTGIO_MASKA_CLEAR()
-#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTGIO_MASKA_CLEAR(val)
-#define FIO_MASKA_C        PORTGIO_MASKA_CLEAR
-#define bfin_read_FIO_MASKA_S() bfin_read_PORTGIO_MASKA_SET()
-#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTGIO_MASKA_SET(val)
-#define FIO_MASKA_S        PORTGIO_MASKA_SET
-#define bfin_read_FIO_MASKA_T() bfin_read_PORTGIO_MASKA_TOGGLE()
-#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTGIO_MASKA_TOGGLE(val)
-#define FIO_MASKA_T        PORTGIO_MASKA_TOGGLE
-#define bfin_read_FIO_MASKB_D() bfin_read_PORTGIO_MASKB()
-#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTGIO_MASKB(val)
-#define FIO_MASKB_D        PORTGIO_MASKB
-#define bfin_read_FIO_MASKB_C() bfin_read_PORTGIO_MASKB_CLEAR()
-#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTGIO_MASKB_CLEAR(val)
-#define FIO_MASKB_C        PORTGIO_MASKB_CLEAR
-#define bfin_read_FIO_MASKB_S() bfin_read_PORTGIO_MASKB_SET()
-#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTGIO_MASKB_SET(val)
-#define FIO_MASKB_S        PORTGIO_MASKB_SET
-#define bfin_read_FIO_MASKB_T() bfin_read_PORTGIO_MASKB_TOGGLE()
-#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTGIO_MASKB_TOGGLE(val)
-#define FIO_MASKB_T        PORTGIO_MASKB_TOGGLE
-#define bfin_read_FIO_DIR() bfin_read_PORTGIO_DIR()
-#define bfin_write_FIO_DIR(val) bfin_write_PORTGIO_DIR(val)
-#define FIO_DIR                    PORTGIO_DIR
-#define bfin_read_FIO_POLAR() bfin_read_PORTGIO_POLAR()
-#define bfin_write_FIO_POLAR(val) bfin_write_PORTGIO_POLAR(val)
-#define FIO_POLAR              PORTGIO_POLAR
-#define bfin_read_FIO_EDGE() bfin_read_PORTGIO_EDGE()
-#define bfin_write_FIO_EDGE(val) bfin_write_PORTGIO_EDGE(val)
-#define FIO_EDGE               PORTGIO_EDGE
-#define bfin_read_FIO_BOTH() bfin_read_PORTGIO_BOTH()
-#define bfin_write_FIO_BOTH(val) bfin_write_PORTGIO_BOTH(val)
-#define FIO_BOTH               PORTGIO_BOTH
-#define bfin_read_FIO_INEN() bfin_read_PORTGIO_INEN()
-#define bfin_write_FIO_INEN(val) bfin_write_PORTGIO_INEN(val)
-#define FIO_INEN               PORTGIO_INEN
-
-#endif
-
-/* FIO USE PORT H*/
-#ifdef CONFIG_BF537_PORT_H
-#define bfin_read_PORT_FER() bfin_read_PORTH_FER()
-#define bfin_write_PORT_FER(val) bfin_write_PORTH_FER(val)
-#define bfin_read_FIO_FLAG_D() bfin_read_PORTHIO()
-#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTHIO(val)
-#define bfin_read_FIO_FLAG_C() bfin_read_PORTHIO_CLEAR()
-#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTHIO_CLEAR(val)
-#define bfin_read_FIO_FLAG_S() bfin_read_PORTHIO_SET()
-#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTHIO_SET(val)
-#define bfin_read_FIO_FLAG_T() bfin_read_PORTHIO_TOGGLE()
-#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTHIO_TOGGLE(val)
-#define bfin_read_FIO_MASKA_D() bfin_read_PORTHIO_MASKA()
-#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTHIO_MASKA(val)
-#define bfin_read_FIO_MASKA_C() bfin_read_PORTHIO_MASKA_CLEAR()
-#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTHIO_MASKA_CLEAR(val)
-#define bfin_read_FIO_MASKA_S() bfin_read_PORTHIO_MASKA_SET()
-#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTHIO_MASKA_SET(val)
-#define bfin_read_FIO_MASKA_T() bfin_read_PORTHIO_MASKA_TOGGLE()
-#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTHIO_MASKA_TOGGLE(val)
-#define bfin_read_FIO_MASKB_D() bfin_read_PORTHIO_MASKB()
-#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTHIO_MASKB(val)
-#define bfin_read_FIO_MASKB_C() bfin_read_PORTHIO_MASKB_CLEAR()
-#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTHIO_MASKB_CLEAR(val)
-#define bfin_read_FIO_MASKB_S() bfin_read_PORTHIO_MASKB_SET()
-#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTHIO_MASKB_SET(val)
-#define bfin_read_FIO_MASKB_T() bfin_read_PORTHIO_MASKB_TOGGLE()
-#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTHIO_MASKB_TOGGLE(val)
-#define bfin_read_FIO_DIR() bfin_read_PORTHIO_DIR()
-#define bfin_write_FIO_DIR(val) bfin_write_PORTHIO_DIR(val)
-#define bfin_read_FIO_POLAR() bfin_read_PORTHIO_POLAR()
-#define bfin_write_FIO_POLAR(val) bfin_write_PORTHIO_POLAR(val)
-#define bfin_read_FIO_EDGE() bfin_read_PORTHIO_EDGE()
-#define bfin_write_FIO_EDGE(val) bfin_write_PORTHIO_EDGE(val)
-#define bfin_read_FIO_BOTH() bfin_read_PORTHIO_BOTH()
-#define bfin_write_FIO_BOTH(val) bfin_write_PORTHIO_BOTH(val)
-#define bfin_read_FIO_INEN() bfin_read_PORTHIO_INEN()
-#define bfin_write_FIO_INEN(val) bfin_write_PORTHIO_INEN(val)
-
-#define bfin_read_FIO_FLAG_D() bfin_read_PORTHIO()
-#define bfin_write_FIO_FLAG_D(val) bfin_write_PORTHIO(val)
-#define FIO_FLAG_D             PORTHIO
-#define bfin_read_FIO_FLAG_C() bfin_read_PORTHIO_CLEAR()
-#define bfin_write_FIO_FLAG_C(val) bfin_write_PORTHIO_CLEAR(val)
-#define FIO_FLAG_C             PORTHIO_CLEAR
-#define bfin_read_FIO_FLAG_S() bfin_read_PORTHIO_SET()
-#define bfin_write_FIO_FLAG_S(val) bfin_write_PORTHIO_SET(val)
-#define FIO_FLAG_S             PORTHIO_SET
-#define bfin_read_FIO_FLAG_T() bfin_read_PORTHIO_TOGGLE()
-#define bfin_write_FIO_FLAG_T(val) bfin_write_PORTHIO_TOGGLE(val)
-#define FIO_FLAG_T             PORTHIO_TOGGLE
-#define bfin_read_FIO_MASKA_D() bfin_read_PORTHIO_MASKA()
-#define bfin_write_FIO_MASKA_D(val) bfin_write_PORTHIO_MASKA(val)
-#define FIO_MASKA_D        PORTHIO_MASKA
-#define bfin_read_FIO_MASKA_C() bfin_read_PORTHIO_MASKA_CLEAR()
-#define bfin_write_FIO_MASKA_C(val) bfin_write_PORTHIO_MASKA_CLEAR(val)
-#define FIO_MASKA_C        PORTHIO_MASKA_CLEAR
-#define bfin_read_FIO_MASKA_S() bfin_read_PORTHIO_MASKA_SET()
-#define bfin_write_FIO_MASKA_S(val) bfin_write_PORTHIO_MASKA_SET(val)
-#define FIO_MASKA_S        PORTHIO_MASKA_SET
-#define bfin_read_FIO_MASKA_T() bfin_read_PORTHIO_MASKA_TOGGLE()
-#define bfin_write_FIO_MASKA_T(val) bfin_write_PORTHIO_MASKA_TOGGLE(val)
-#define FIO_MASKA_T        PORTHIO_MASKA_TOGGLE
-#define bfin_read_FIO_MASKB_D() bfin_read_PORTHIO_MASKB()
-#define bfin_write_FIO_MASKB_D(val) bfin_write_PORTHIO_MASKB(val)
-#define FIO_MASKB_D        PORTHIO_MASKB
-#define bfin_read_FIO_MASKB_C() bfin_read_PORTHIO_MASKB_CLEAR()
-#define bfin_write_FIO_MASKB_C(val) bfin_write_PORTHIO_MASKB_CLEAR(val)
-#define FIO_MASKB_C        PORTHIO_MASKB_CLEAR
-#define bfin_read_FIO_MASKB_S() bfin_read_PORTHIO_MASKB_SET()
-#define bfin_write_FIO_MASKB_S(val) bfin_write_PORTHIO_MASKB_SET(val)
-#define FIO_MASKB_S        PORTHIO_MASKB_SET
-#define bfin_read_FIO_MASKB_T() bfin_read_PORTHIO_MASKB_TOGGLE()
-#define bfin_write_FIO_MASKB_T(val) bfin_write_PORTHIO_MASKB_TOGGLE(val)
-#define FIO_MASKB_T        PORTHIO_MASKB_TOGGLE
-#define bfin_read_FIO_DIR() bfin_read_PORTHIO_DIR()
-#define bfin_write_FIO_DIR(val) bfin_write_PORTHIO_DIR(val)
-#define FIO_DIR                    PORTHIO_DIR
-#define bfin_read_FIO_POLAR() bfin_read_PORTHIO_POLAR()
-#define bfin_write_FIO_POLAR(val) bfin_write_PORTHIO_POLAR(val)
-#define FIO_POLAR              PORTHIO_POLAR
-#define bfin_read_FIO_EDGE() bfin_read_PORTHIO_EDGE()
-#define bfin_write_FIO_EDGE(val) bfin_write_PORTHIO_EDGE(val)
-#define FIO_EDGE               PORTHIO_EDGE
-#define bfin_read_FIO_BOTH() bfin_read_PORTHIO_BOTH()
-#define bfin_write_FIO_BOTH(val) bfin_write_PORTHIO_BOTH(val)
-#define FIO_BOTH               PORTHIO_BOTH
-#define bfin_read_FIO_INEN() bfin_read_PORTHIO_INEN()
-#define bfin_write_FIO_INEN(val) bfin_write_PORTHIO_INEN(val)
-#define FIO_INEN               PORTHIO_INEN
-
-#endif
-
 /* PLL_DIV Masks                                                                                                       */
 #define CCLK_DIV1 CSEL_DIV1    /*          CCLK = VCO / 1                                  */
 #define CCLK_DIV2 CSEL_DIV2    /*          CCLK = VCO / 2                                  */
index 84e58fa73dce846aee6c24af20d09e5197a90a5a..78227bc855df54bca56220dc55d777fec0e6a04a 100644 (file)
@@ -32,6 +32,8 @@
 #ifndef _CDEF_BF534_H
 #define _CDEF_BF534_H
 
+#include <asm/blackfin.h>
+
 /* Include all Core registers and bit definitions                                                                      */
 #include "defBF534.h"
 
@@ -57,7 +59,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        bfin_write32(SIC_IWR, IWR_ENABLE(0));
 
        bfin_write16(VR_CTL, val);
-       __builtin_bfin_ssync();
+       SSYNC();
 
        local_irq_save(flags);
        asm("IDLE;");
index 1859f2fee5a732778161fc39b5d887dcb5353bd6..d0d80d3152bab06f800b88c09632adb67d2d72bd 100644 (file)
@@ -86,6 +86,7 @@
 #define UART0_GCTL                     0xFFC00424      /* Global Control Register                                      */
 
 /* SPI Controller                      (0xFFC00500 - 0xFFC005FF)                                                               */
+#define SPI0_REGBASE                   0xFFC00500
 #define SPI_CTL                                0xFFC00500      /* SPI Control Register                                         */
 #define SPI_FLG                                0xFFC00504      /* SPI Flag register                                            */
 #define SPI_STAT                       0xFFC00508      /* SPI Status register                                          */
 #define PPI_FRAME                      0xFFC01010      /* PPI Frame Length Register    */
 
 /* Two-Wire Interface          (0xFFC01400 - 0xFFC014FF)                                                               */
+#define TWI0_REGBASE                   0xFFC01400
 #define TWI_CLKDIV                     0xFFC01400      /* Serial Clock Divider Register                        */
 #define TWI_CONTROL                    0xFFC01404      /* TWI Control Register                                         */
 #define TWI_SLAVE_CTL          0xFFC01408      /* Slave Mode Control Register                          */
 #define GM                     0x0008  /* Get More (When RDBR Full, Overwrite/Discard*)        */
 #define PSSE           0x0010  /* Slave-Select Input Enable                                            */
 #define EMISO          0x0020  /* Enable MISO As Output                                                        */
-#define SPI_SIZE       0x0100  /* Size of Words (16/8* Bits)                                           */
+#define SIZE           0x0100  /* Size of Words (16/8* Bits)                                           */
 #define LSBF           0x0200  /* LSB First                                                                            */
 #define CPHA           0x0400  /* Clock Phase                                                                          */
 #define CPOL           0x0800  /* Clock Polarity                                                                       */
index 8af2a832ef6b832d4290fdea815af7ce3921922e..36c44bc1a917d8acd6a6da642f0dc033234d2e05 100644 (file)
@@ -160,6 +160,8 @@ Core        Emulation               **
 #define IRQ_PH14        96
 #define IRQ_PH15        97
 
+#define GPIO_IRQ_BASE  IRQ_PF0
+
 #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
 #define NR_IRQS     (IRQ_PH15+1)
 #else
index 2a808c1202bf54842b4a2142e3c3202af1fbf4c1..18759e38eaae3dce208f13066ced2ca3ba239a42 100644 (file)
 
 /* Memory Map for ADSP-BF537 processors */
 
-#ifdef CONFIG_BLKFIN_CACHE
-#define BLKFIN_ICACHESIZE      (16*1024)
+#ifdef CONFIG_BFIN_ICACHE
+#define BFIN_ICACHESIZE        (16*1024)
 #else
-#define BLKFIN_ICACHESIZE      (0*1024)
+#define BFIN_ICACHESIZE        (0*1024)
 #endif
 
 
 
 #define L1_CODE_LENGTH      0xC000
 
-#ifdef CONFIG_BLKFIN_DCACHE
+#ifdef CONFIG_BFIN_DCACHE
 
-#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#ifdef CONFIG_BFIN_DCACHE_BANKA
 #define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
 #define L1_DATA_B_LENGTH      0x8000
-#define BLKFIN_DCACHESIZE      (16*1024)
-#define BLKFIN_DSUPBANKS       1
+#define BFIN_DCACHESIZE        (16*1024)
+#define BFIN_DSUPBANKS 1
 #else
 #define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
 #define L1_DATA_B_LENGTH      (0x8000 - 0x4000)
-#define BLKFIN_DCACHESIZE      (32*1024)
-#define BLKFIN_DSUPBANKS       2
+#define BFIN_DCACHESIZE        (32*1024)
+#define BFIN_DSUPBANKS 2
 #endif
 
 #else
 #define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      0x8000
 #define L1_DATA_B_LENGTH      0x8000
-#define BLKFIN_DCACHESIZE      (0*1024)
-#define BLKFIN_DSUPBANKS       0
-#endif /*CONFIG_BLKFIN_DCACHE*/
+#define BFIN_DCACHESIZE        (0*1024)
+#define BFIN_DSUPBANKS 0
+#endif /*CONFIG_BFIN_DCACHE*/
 
 #endif /*CONFIG_BF537*/
 
 #define L1_CODE_LENGTH      0xC000
 
 
-#ifdef CONFIG_BLKFIN_DCACHE
+#ifdef CONFIG_BFIN_DCACHE
 
-#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#ifdef CONFIG_BFIN_DCACHE_BANKA
 #define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x4000 - 0x4000)
 #define L1_DATA_B_LENGTH      0x4000
-#define BLKFIN_DCACHESIZE      (16*1024)
-#define BLKFIN_DSUPBANKS       1
+#define BFIN_DCACHESIZE        (16*1024)
+#define BFIN_DSUPBANKS 1
 
 #else
 #define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x4000 - 0x4000)
 #define L1_DATA_B_LENGTH      (0x4000 - 0x4000)
-#define BLKFIN_DCACHESIZE      (32*1024)
-#define BLKFIN_DSUPBANKS       2
+#define BFIN_DCACHESIZE        (32*1024)
+#define BFIN_DSUPBANKS 2
 #endif
 
 #else
 #define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      0x4000
 #define L1_DATA_B_LENGTH      0x4000
-#define BLKFIN_DCACHESIZE      (0*1024)
-#define BLKFIN_DSUPBANKS       0
-#endif /*CONFIG_BLKFIN_DCACHE*/
+#define BFIN_DCACHESIZE        (0*1024)
+#define BFIN_DSUPBANKS 0
+#endif /*CONFIG_BFIN_DCACHE*/
 
 #endif
 
 
 #define L1_CODE_LENGTH      0xC000
 
-#ifdef CONFIG_BLKFIN_DCACHE
+#ifdef CONFIG_BFIN_DCACHE
 
-#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#ifdef CONFIG_BFIN_DCACHE_BANKA
 #define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
 #define L1_DATA_B_LENGTH      0x8000
-#define BLKFIN_DCACHESIZE      (16*1024)
-#define BLKFIN_DSUPBANKS       1
+#define BFIN_DCACHESIZE        (16*1024)
+#define BFIN_DSUPBANKS 1
 
 #else
 #define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
 #define L1_DATA_B_LENGTH      (0x8000 - 0x4000)
-#define BLKFIN_DCACHESIZE      (32*1024)
-#define BLKFIN_DSUPBANKS       2
+#define BFIN_DCACHESIZE        (32*1024)
+#define BFIN_DSUPBANKS 2
 #endif
 
 #else
 #define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      0x8000
 #define L1_DATA_B_LENGTH      0x8000
-#define BLKFIN_DCACHESIZE      (0*1024)
-#define BLKFIN_DSUPBANKS       0
-#endif /*CONFIG_BLKFIN_DCACHE*/
+#define BFIN_DCACHESIZE        (0*1024)
+#define BFIN_DSUPBANKS 0
+#endif /*CONFIG_BFIN_DCACHE*/
 
 #endif
 
index ae6c53b28452520919decaa007c3979a2dd2896a..5a3f7d3bf73d0b7696585383dacd46b23ca8658c 100644 (file)
@@ -99,7 +99,7 @@
 #define P_SPORT0_DRPRI (P_DEFINED | P_IDENT(PORT_PJ8) | P_FUNCT(0))
 #define P_SPORT0_TSCLK (P_DEFINED | P_IDENT(PORT_PJ9) | P_FUNCT(0))
 #define P_SPORT0_TFS   (P_DEFINED | P_IDENT(PORT_PJ10) | P_FUNCT(0))
-#define P_SPORT0_DTPRI (P_DEFINED | P_IDENT(PORT_PJ11) | P_FUNCT(1))
+#define P_SPORT0_DTPRI (P_DEFINED | P_IDENT(PORT_PJ11) | P_FUNCT(0))
 #define P_CAN0_RX      (P_DEFINED | P_IDENT(PORT_PJ4) | P_FUNCT(1))
 #define P_CAN0_TX      (P_DEFINED | P_IDENT(PORT_PJ5) | P_FUNCT(1))
 #define P_SPI0_SSEL3   (P_DEFINED | P_IDENT(PORT_PJ10) | P_FUNCT(1))
index aca1d4ba145c4a036a37b1f0db0d3e139cff5ac2..c5b63759cdee02598c0567f0f37ef3c8a6231421 100644 (file)
@@ -1,74 +1,85 @@
-
 /*
- * File:         include/asm-blackfin/mach-bf548/anomaly.h
- * Based on:
- * Author:
- *
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ * File: include/asm-blackfin/mach-bf548/anomaly.h
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Copyright (C) 2004-2007 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
+ */
+
+/* This file shoule be up to date with:
+ *  - Revision C, July 16, 2007; ADSP-BF549 Silicon Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
 #define _MACH_ANOMALY_H_
-#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in
-                           slot1 and store of a P register in slot 2 is not
-                           supported */
-#define ANOMALY_05000119 /* DMA_RUN bit is not valid after a Peripheral Receive
-                           Channel DMA stops */
-#define ANOMALY_05000122 /* Rx.H can not be used to access 16-bit System MMR
-                           registers. */
-#define ANOMALY_05000245 /* Spurious Hardware Error from an Access in the
-                           Shadow of a Conditional Branch */
-#define ANOMALY_05000255 /* Entering Hibernate Mode with RTC Seconds event
-                           interrupt not functional */
-#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on
-                           SPORT external receive and transmit clocks. */
-#define ANOMALY_05000272 /* Certain data cache write through modes fail for
-                           VDDint <=0.9V */
-#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is
-                           not restored */
-#define ANOMALY_05000310 /* False Hardware Errors Caused by Fetches at the
-                           Boundary of Reserved Memory */
-#define ANOMALY_05000312 /* Errors When SSYNC, CSYNC, or Loads to LT, LB and
-                           LC Registers Are Interrupted */
-#define ANOMALY_05000324 /* TWI Slave Boot Mode Is Not Functional */
-#define ANOMALY_05000325 /* External FIFO Boot Mode Is Not Functional */
-#define ANOMALY_05000327 /* Data Lost When Core and DMA Accesses Are Made to
-                           the USB FIFO Simultaneously */
-#define ANOMALY_05000328 /* Incorrect Access of OTP_STATUS During otp_write()
-                           function */
-#define ANOMALY_05000329 /* Synchronous Burst Flash Boot Mode Is Not Functional
-                           */
-#define ANOMALY_05000330 /* Host DMA Boot Mode Is Not Functional */
-#define ANOMALY_05000334 /* Inadequate Timing Margins on DDR DQS to DQ and DQM
-                           Skew */
-#define ANOMALY_05000335 /* Inadequate Rotary Debounce Logic Duration */
-#define ANOMALY_05000336 /* Phantom Interrupt Occurs After First Configuration
-                           of Host DMA Port */
-#define ANOMALY_05000337 /* Disallowed Configuration Prevents Subsequent
-                           Allowed Configuration on Host DMA Port */
-#define ANOMALY_05000338 /* Slave-Mode SPI0 MISO Failure With CPHA = 0 */
 
-#endif /* _MACH_ANOMALY_H_ */
+/* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot 2 Not Supported */
+#define ANOMALY_05000074 (1)
+/* DMA_RUN Bit Is Not Valid after a Peripheral Receive Channel DMA Stops */
+#define ANOMALY_05000119 (1)
+/* Rx.H Cannot Be Used to Access 16-bit System MMR Registers */
+#define ANOMALY_05000122 (1)
+/* Spurious Hardware Error from an Access in the Shadow of a Conditional Branch */
+#define ANOMALY_05000245 (1)
+/* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */
+#define ANOMALY_05000265 (1)
+/* Certain Data Cache Writethrough Modes Fail for Vddint <= 0.9V */
+#define ANOMALY_05000272 (1)
+/* False Hardware Error Exception when ISR context is not restored */
+#define ANOMALY_05000281 (1)
+/* SSYNCs After Writes To CAN/DMA MMR Registers Are Not Always Handled Correctly */
+#define ANOMALY_05000304 (1)
+/* False Hardware Errors Caused by Fetches at the Boundary of Reserved Memory */
+#define ANOMALY_05000310 (1)
+/* Errors When SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted */
+#define ANOMALY_05000312 (1)
+/* TWI Slave Boot Mode Is Not Functional */
+#define ANOMALY_05000324 (1)
+/* External FIFO Boot Mode Is Not Functional */
+#define ANOMALY_05000325 (1)
+/* Data Lost When Core and DMA Accesses Are Made to the USB FIFO Simultaneously */
+#define ANOMALY_05000327 (1)
+/* Incorrect Access of OTP_STATUS During otp_write() Function */
+#define ANOMALY_05000328 (1)
+/* Synchronous Burst Flash Boot Mode Is Not Functional */
+#define ANOMALY_05000329 (1)
+/* Host DMA Boot Mode Is Not Functional */
+#define ANOMALY_05000330 (1)
+/* Inadequate Timing Margins on DDR DQS to DQ and DQM Skew */
+#define ANOMALY_05000334 (1)
+/* Inadequate Rotary Debounce Logic Duration */
+#define ANOMALY_05000335 (1)
+/* Phantom Interrupt Occurs After First Configuration of Host DMA Port */
+#define ANOMALY_05000336 (1)
+/* Disallowed Configuration Prevents Subsequent Allowed Configuration on Host DMA Port */
+#define ANOMALY_05000337 (1)
+/* Slave-Mode SPI0 MISO Failure With CPHA = 0 */
+#define ANOMALY_05000338 (1)
+/* If Memory Reads Are Enabled on SDH or HOSTDP, Other DMAC1 Peripherals Cannot Read */
+#define ANOMALY_05000340 (1)
+/* Boot Host Wait (HWAIT) and Boot Host Wait Alternate (HWAITA) Signals Are Swapped */
+#define ANOMALY_05000344 (1)
+/* USB Calibration Value Is Not Intialized */
+#define ANOMALY_05000346 (1)
+/* Boot ROM Kernel Incorrectly Alters Reset Value of USB Register */
+#define ANOMALY_05000347 (1)
+/* Data Lost when Core Reads SDH Data FIFO */
+#define ANOMALY_05000349 (1)
+/* PLL Status Register Is Inaccurate */
+#define ANOMALY_05000351 (1)
+
+/* Anomalies that don't exist on this proc */
+#define ANOMALY_05000125 (0)
+#define ANOMALY_05000158 (0)
+#define ANOMALY_05000183 (0)
+#define ANOMALY_05000198 (0)
+#define ANOMALY_05000230 (0)
+#define ANOMALY_05000244 (0)
+#define ANOMALY_05000261 (0)
+#define ANOMALY_05000263 (0)
+#define ANOMALY_05000266 (0)
+#define ANOMALY_05000273 (0)
+#define ANOMALY_05000311 (0)
+#define ANOMALY_05000323 (0)
+
+#endif
index 9498313a2cb7286852842f32e0e06edaf2ed7ed9..7e6d349beb088680b41cec91cabd591c3348f1f6 100644 (file)
 /***************************/
 
 
-#define BLKFIN_DSUBBANKS       4
-#define BLKFIN_DWAYS           2
-#define BLKFIN_DLINES          64
-#define BLKFIN_ISUBBANKS       4
-#define BLKFIN_IWAYS           4
-#define BLKFIN_ILINES          32
+#define BFIN_DSUBBANKS 4
+#define BFIN_DWAYS             2
+#define BFIN_DLINES            64
+#define BFIN_ISUBBANKS 4
+#define BFIN_IWAYS             4
+#define BFIN_ILINES            32
 
 #define WAY0_L                 0x1
 #define WAY1_L                 0x2
 
 #define AMGCTLVAL      (V_AMBEN | V_AMCKEN)
 
-#define MAX_VC 650000000
-#define MIN_VC 50000000
-
-/********************************PLL Settings **************************************/
-#ifdef CONFIG_BFIN_KERNEL_CLOCK
-#if (CONFIG_VCO_MULT < 0)
-#error "VCO Multiplier is less than 0. Please select a different value"
-#endif
-
-#if (CONFIG_VCO_MULT == 0)
-#error "VCO Multiplier should be greater than 0. Please select a different value"
-#endif
-
-#if (CONFIG_VCO_MULT > 64)
-#error "VCO Multiplier is more than 64. Please select a different value"
-#endif
-
-#ifndef CONFIG_CLKIN_HALF
-#define CONFIG_VCO_HZ  (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)
-#else
-#define CONFIG_VCO_HZ  ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2)
-#endif
-
-#ifndef CONFIG_PLL_BYPASS
-#define CONFIG_CCLK_HZ (CONFIG_VCO_HZ/CONFIG_CCLK_DIV)
-#define CONFIG_SCLK_HZ (CONFIG_VCO_HZ/CONFIG_SCLK_DIV)
-#else
-#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ
-#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ
-#endif
-
-#if (CONFIG_SCLK_DIV < 1)
-#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
-#endif
-
-#if (CONFIG_SCLK_DIV > 15)
-#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
-#endif
-
-#if (CONFIG_CCLK_DIV != 1)
-#if (CONFIG_CCLK_DIV != 2)
-#if (CONFIG_CCLK_DIV != 4)
-#if (CONFIG_CCLK_DIV != 8)
-#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value"
-#endif
-#endif
-#endif
-#endif
-
-#if (CONFIG_VCO_HZ > MAX_VC)
-#error "VCO selected is more than maximum value. Please change the VCO multipler"
-#endif
-
-#if (CONFIG_SCLK_HZ > 133000000)
-#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier"
-#endif
-
-#if (CONFIG_SCLK_HZ < 27000000)
-#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier"
-#endif
-
-#if (CONFIG_SCLK_HZ >= CONFIG_CCLK_HZ)
-#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ)
-#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ)
-#error "Please select sclk less than cclk"
-#endif
-#endif
-#endif
-
-#if (CONFIG_CCLK_DIV == 1)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV1
-#endif
-#if (CONFIG_CCLK_DIV == 2)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV2
-#endif
-#if (CONFIG_CCLK_DIV == 4)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV4
-#endif
-#if (CONFIG_CCLK_DIV == 8)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV8
-#endif
-#ifndef CONFIG_CCLK_ACT_DIV
-#define CONFIG_CCLK_ACT_DIV   CONFIG_CCLK_DIV_not_defined_properly
-#endif
-
-#endif /* CONFIG_BFIN_KERNEL_CLOCK */
-
 #ifdef CONFIG_BF542
 #define CPU "BF542"
 #define CPUID 0x027c8000
 #define CPUID 0x0
 #endif
 
-#if (CONFIG_MEM_SIZE % 4)
-#error "SDRAM mem size must be multible of 4MB"
-#endif
-
-#define SDRAM_IGENERIC    (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
-#define SDRAM_IKERNEL     (SDRAM_IGENERIC | CPLB_LOCK)
-#define L1_IMEMORY        (               CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
-#define SDRAM_INON_CHBL   (               CPLB_USER_RD | CPLB_VALID)
-
-/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/
-
-#define ANOMALY_05000158_WORKAROUND            0x200
-#ifdef CONFIG_BLKFIN_WB                /*Write Back Policy */
-#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_DIRTY \
-                       | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
-#else                          /*Write Through */
-#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW \
-                       | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
-#endif
-
-
-#define L1_DMEMORY       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )
-#define SDRAM_DNON_CHBL  (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
-#define SDRAM_EBIU       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )
-#define SDRAM_OOPS      (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )
-
-#define SIZE_1K 0x00000400     /* 1K */
-#define SIZE_4K 0x00001000     /* 4K */
-#define SIZE_1M 0x00100000     /* 1M */
-#define SIZE_4M 0x00400000     /* 4M */
-
-#define MAX_CPLBS (16 * 2)
-
-/*
-* Number of required data CPLB switchtable entries
-* MEMSIZE / 4 (we mostly install 4M page size CPLBs
-* approx 16 for smaller 1MB page size CPLBs for allignment purposes
-* 1 for L1 Data Memory
-* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
-* 1 for ASYNC Memory
-*/
-
-
-#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1) * 2)
-
-/*
-* Number of required instruction CPLB switchtable entries
-* MEMSIZE / 4 (we mostly install 4M page size CPLBs
-* approx 12 for smaller 1MB page size CPLBs for allignment purposes
-* 1 for L1 Instruction Memory
-* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
-*/
-
-#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1) * 2)
-
 #endif /* __MACH_BF48_H__  */
index 2f4afc90db11f375536c2171d05a7ea1fcd0b7af..f21a1620e6bd931f57bc4ed08e48e02fcb2f0755 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/serial.h>
 #include <asm/dma.h>
+#include <asm/portmux.h>
 
 #define NR_PORTS               4
 
@@ -143,50 +144,48 @@ struct bfin_serial_res bfin_serial_resource[] = {
 
 int nr_ports = ARRAY_SIZE(bfin_serial_resource);
 
+#define DRIVER_NAME "bfin-uart"
+
 static void bfin_serial_hw_init(struct bfin_serial_port *uart)
 {
 #ifdef CONFIG_SERIAL_BFIN_UART0
-       /* Enable UART0 RX and TX on pin 7 & 8 of PORT E */
-       bfin_write_PORTE_FER(0x180 | bfin_read_PORTE_FER());
-       bfin_write_PORTE_MUX(0x3C000 | bfin_read_PORTE_MUX());
+       peripheral_request(P_UART0_TX, DRIVER_NAME);
+       peripheral_request(P_UART0_RX, DRIVER_NAME);
 #endif
 
 #ifdef CONFIG_SERIAL_BFIN_UART1
-       /* Enable UART1 RX and TX on pin 0 & 1 of PORT H */
-       bfin_write_PORTH_FER(0x3 | bfin_read_PORTH_FER());
-       bfin_write_PORTH_MUX(~0xF & bfin_read_PORTH_MUX());
+       peripheral_request(P_UART1_TX, DRIVER_NAME);
+       peripheral_request(P_UART1_RX, DRIVER_NAME);
+
 #ifdef CONFIG_BFIN_UART1_CTSRTS
-       /* Enable UART1 RTS and CTS on pin 9 & 10 of PORT E */
-       bfin_write_PORTE_FER(0x600 | bfin_read_PORTE_FER());
-       bfin_write_PORTE_MUX(~0x3C0000 & bfin_read_PORTE_MUX());
+       peripheral_request(P_UART1_RTS, DRIVER_NAME);
+       peripheral_request(P_UART1_CTS DRIVER_NAME);
 #endif
 #endif
 
 #ifdef CONFIG_SERIAL_BFIN_UART2
-       /* Enable UART2 RX and TX on pin 4 & 5 of PORT B */
-       bfin_write_PORTB_FER(0x30 | bfin_read_PORTB_FER());
-       bfin_write_PORTB_MUX(~0xF00 & bfin_read_PORTB_MUX());
+       peripheral_request(P_UART2_TX, DRIVER_NAME);
+       peripheral_request(P_UART2_RX, DRIVER_NAME);
 #endif
 
 #ifdef CONFIG_SERIAL_BFIN_UART3
-       /* Enable UART3 RX and TX on pin 6 & 7 of PORT B */
-       bfin_write_PORTB_FER(0xC0 | bfin_read_PORTB_FER());
-       bfin_write_PORTB_MUX(~0xF000 | bfin_read_PORTB_MUX());
+       peripheral_request(P_UART3_TX, DRIVER_NAME);
+       peripheral_request(P_UART3_RX, DRIVER_NAME);
+
 #ifdef CONFIG_BFIN_UART3_CTSRTS
-       /* Enable UART3 RTS and CTS on pin 2 & 3 of PORT B */
-       bfin_write_PORTB_FER(0xC | bfin_read_PORTB_FER());
-       bfin_write_PORTB_MUX(~0xF0 | bfin_read_PORTB_MUX());
+       peripheral_request(P_UART3_RTS, DRIVER_NAME);
+       peripheral_request(P_UART3_CTS DRIVER_NAME);
 #endif
 #endif
        SSYNC();
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
        if (uart->cts_pin >= 0) {
-               gpio_request(uart->cts_pin, NULL);
+               gpio_request(uart->cts_pin, DRIVER_NAME);
                gpio_direction_input(uart->cts_pin);
        }
 
        if (uart->rts_pin >= 0) {
-               gpio_request(uart->rts_pin, NULL);
+               gpio_request(uart->rts_pin, DRIVER_NAME);
                gpio_direction_output(uart->rts_pin);
        }
 #endif
index 791218fe7d946a315a8768ec0a1b9a482d807c73..19e84dd4c99c760128222c1f68983f7681dffc75 100644 (file)
@@ -54,7 +54,7 @@
 #include "defBF549.h"
 #endif
 
-#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY))
+#if !defined(__ASSEMBLY__)
 #ifdef CONFIG_BF542
 #include "cdefBF542.h"
 #endif
index cdf29e75ea598922b3091c6e7c526dffd92e31cb..aefab3f618c1ef31834c05ae386200ee35fd1af0 100644 (file)
@@ -31,6 +31,8 @@
 #ifndef _CDEF_BF54X_H
 #define _CDEF_BF54X_H
 
+#include <asm/blackfin.h>
+
 #include "defBF54x_base.h"
 #include <asm/system.h>
 
@@ -60,7 +62,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        bfin_write32(SIC_IWR2, 0);
 
        bfin_write16(VR_CTL, val);
-       __builtin_bfin_ssync();
+       SSYNC();
 
        local_irq_save(flags);
        asm("IDLE;");
index dd955dcd39b8949cb4aafd20e52b333c80386b32..760307e34b9e751f25a55c64c26f6d47c768eedc 100644 (file)
@@ -81,6 +81,7 @@
 
 /* Two Wire Interface Registers (TWI1) */
 
+#define                     TWI1_REGBASE  0xffc02200
 #define                      TWI1_CLKDIV  0xffc02200   /* Clock Divider Register */
 #define                     TWI1_CONTROL  0xffc02204   /* TWI Control Register */
 #define                  TWI1_SLAVE_CTRL  0xffc02208   /* TWI Slave Mode Control Register */
index 8d4214e0807ccac3d58b90b5ae277f5b21569d9a..70af33c963b068c89455905378ba95b171a7cf44 100644 (file)
 
 /* Two Wire Interface Registers (TWI1) */
 
+#define                     TWI1_REGBASE  0xffc02200
 #define                      TWI1_CLKDIV  0xffc02200   /* Clock Divider Register */
 #define                     TWI1_CONTROL  0xffc02204   /* TWI Control Register */
 #define                  TWI1_SLAVE_CTRL  0xffc02208   /* TWI Slave Mode Control Register */
 
 /* SPI2  Registers */
 
+#define                     SPI2_REGBASE  0xffc02400
 #define                         SPI2_CTL  0xffc02400   /* SPI2 Control Register */
 #define                         SPI2_FLG  0xffc02404   /* SPI2 Flag Register */
 #define                        SPI2_STAT  0xffc02408   /* SPI2 Status Register */
index c2f4734da48df9ca9d96a02d868c2af734e6a9a9..50b3fe55ef0c182137ea6abd11c5c3a2ee5d3d26 100644 (file)
 
 /* Two Wire Interface Registers (TWI1) */
 
+#define                     TWI1_REGBASE  0xffc02200
 #define                      TWI1_CLKDIV  0xffc02200   /* Clock Divider Register */
 #define                     TWI1_CONTROL  0xffc02204   /* TWI Control Register */
 #define                  TWI1_SLAVE_CTRL  0xffc02208   /* TWI Slave Mode Control Register */
 
 /* SPI2  Registers */
 
+#define                     SPI2_REGBASE  0xffc02400
 #define                         SPI2_CTL  0xffc02400   /* SPI2 Control Register */
 #define                         SPI2_FLG  0xffc02404   /* SPI2 Flag Register */
 #define                        SPI2_STAT  0xffc02408   /* SPI2 Status Register */
index 895ddd40a838cce33bc295a79e68aea339aa6ab9..e2632db74baa4605c2594872f4047a37ae32a543 100644 (file)
 
 /* SPI0 Registers */
 
+#define                     SPI0_REGBASE  0xffc00500
 #define                         SPI0_CTL  0xffc00500   /* SPI0 Control Register */
 #define                         SPI0_FLG  0xffc00504   /* SPI0 Flag Register */
 #define                        SPI0_STAT  0xffc00508   /* SPI0 Status Register */
 
 /* Two Wire Interface Registers (TWI0) */
 
+#define                     TWI0_REGBASE  0xffc00700
 #define                      TWI0_CLKDIV  0xffc00700   /* Clock Divider Register */
 #define                     TWI0_CONTROL  0xffc00704   /* TWI Control Register */
 #define                  TWI0_SLAVE_CTRL  0xffc00708   /* TWI Slave Mode Control Register */
 
 /* SPI1 Registers */
 
+#define                     SPI1_REGBASE  0xffc02300
 #define                         SPI1_CTL  0xffc02300   /* SPI1 Control Register */
 #define                         SPI1_FLG  0xffc02304   /* SPI1 Flag Register */
 #define                        SPI1_STAT  0xffc02308   /* SPI1 Status Register */
index dbf66bcabe35e9a7669b6ec6c092037bfe4c9f80..cb8b0f15c9a6b2439b3ea120e0c7c53ef8c66aee 100644 (file)
@@ -209,8 +209,3 @@ struct gpio_port_t {
        unsigned short dummy7;
        unsigned int port_mux;
 };
-
-int gpio_request(unsigned short gpio, const char *label);
-void peripheral_free(unsigned short per);
-int peripheral_request_list(unsigned short per[], const char *label);
-void peripheral_free_list(unsigned short per[]);
index e548d3cd81e31b3b0099f4d25536b763b5ea35a3..3b08cf9bd6f36ec4bf2068a90df9648c1f2c2248 100644 (file)
@@ -55,287 +55,288 @@ Events         (highest priority)  EMU         0
 
 /* The ABSTRACT IRQ definitions */
 /** the first seven of the following are fixed, the rest you change if you need to **/
-#define IRQ_EMU                0       /* Emulation */
-#define IRQ_RST                1       /* reset */
-#define IRQ_NMI                2       /* Non Maskable */
-#define IRQ_EVX                3       /* Exception */
-#define IRQ_UNUSED     4       /* - unused interrupt*/
-#define IRQ_HWERR      5       /* Hardware Error */
-#define IRQ_CORETMR    6       /* Core timer */
-
-#define BFIN_IRQ(x)    ((x) + 7)
-
-#define IRQ_PLL_WAKEUP BFIN_IRQ(0)     /* PLL Wakeup Interrupt */
-#define IRQ_DMAC0_ERR  BFIN_IRQ(1)     /* DMAC0 Status Interrupt */
-#define IRQ_EPPI0_ERR  BFIN_IRQ(2)     /* EPPI0 Error Interrupt */
-#define IRQ_SPORT0_ERR BFIN_IRQ(3)     /* SPORT0 Error Interrupt */
-#define IRQ_SPORT1_ERR BFIN_IRQ(4)     /* SPORT1 Error Interrupt */
-#define IRQ_SPI0_ERR   BFIN_IRQ(5)     /* SPI0 Status(Error) Interrupt */
-#define IRQ_UART0_ERR  BFIN_IRQ(6)     /* UART0 Status(Error) Interrupt */
-#define IRQ_RTC                BFIN_IRQ(7)     /* RTC Interrupt */
-#define IRQ_EPPI0      BFIN_IRQ(8)     /* EPPI0 Interrupt (DMA12) */
-#define IRQ_SPORT0_RX  BFIN_IRQ(9)     /* SPORT0 RX Interrupt (DMA0) */
-#define IRQ_SPORT0_TX  BFIN_IRQ(10)    /* SPORT0 TX Interrupt (DMA1) */
-#define IRQ_SPORT1_RX  BFIN_IRQ(11)    /* SPORT1 RX Interrupt (DMA2) */
-#define IRQ_SPORT1_TX  BFIN_IRQ(12)    /* SPORT1 TX Interrupt (DMA3) */
-#define IRQ_SPI0       BFIN_IRQ(13)    /* SPI0 Interrupt (DMA4) */
-#define IRQ_UART0_RX   BFIN_IRQ(14)    /* UART0 RX Interrupt (DMA6) */
-#define IRQ_UART0_TX   BFIN_IRQ(15)    /* UART0 TX Interrupt (DMA7) */
-#define IRQ_TIMER8     BFIN_IRQ(16)    /* TIMER 8 Interrupt */
-#define IRQ_TIMER9     BFIN_IRQ(17)    /* TIMER 9 Interrupt */
-#define IRQ_TIMER10    BFIN_IRQ(18)    /* TIMER 10 Interrupt */
-#define IRQ_PINT0      BFIN_IRQ(19)    /* PINT0 Interrupt */
-#define IRQ_PINT1      BFIN_IRQ(20)    /* PINT1 Interrupt */
-#define IRQ_MDMAS0     BFIN_IRQ(21)    /* MDMA Stream 0 Interrupt */
-#define IRQ_MDMAS1     BFIN_IRQ(22)    /* MDMA Stream 1 Interrupt */
-#define IRQ_WATCHDOG   BFIN_IRQ(23)    /* Watchdog Interrupt */
-#define IRQ_DMAC1_ERR  BFIN_IRQ(24)    /* DMAC1 Status (Error) Interrupt */
-#define IRQ_SPORT2_ERR BFIN_IRQ(25)    /* SPORT2 Error Interrupt */
-#define IRQ_SPORT3_ERR BFIN_IRQ(26)    /* SPORT3 Error Interrupt */
-#define IRQ_MXVR_DATA  BFIN_IRQ(27)    /* MXVR Data Interrupt */
-#define IRQ_SPI1_ERR   BFIN_IRQ(28)    /* SPI1 Status (Error) Interrupt */
-#define IRQ_SPI2_ERR   BFIN_IRQ(29)    /* SPI2 Status (Error) Interrupt */
-#define IRQ_UART1_ERR  BFIN_IRQ(30)    /* UART1 Status (Error) Interrupt */
-#define IRQ_UART2_ERR  BFIN_IRQ(31)    /* UART2 Status (Error) Interrupt */
-#define IRQ_CAN0_ERR   BFIN_IRQ(32)    /* CAN0 Status (Error) Interrupt */
-#define IRQ_SPORT2_RX  BFIN_IRQ(33)    /* SPORT2 RX (DMA18) Interrupt */
-#define IRQ_SPORT2_TX  BFIN_IRQ(34)    /* SPORT2 TX (DMA19) Interrupt */
-#define IRQ_SPORT3_RX  BFIN_IRQ(35)    /* SPORT3 RX (DMA20) Interrupt */
-#define IRQ_SPORT3_TX  BFIN_IRQ(36)    /* SPORT3 TX (DMA21) Interrupt */
-#define IRQ_EPPI1      BFIN_IRQ(37)    /* EPP1 (DMA13) Interrupt */
-#define IRQ_EPPI2      BFIN_IRQ(38)    /* EPP2 (DMA14) Interrupt */
-#define IRQ_SPI1       BFIN_IRQ(39)    /* SPI1 (DMA5) Interrupt */
-#define IRQ_SPI2       BFIN_IRQ(40)    /* SPI2 (DMA23) Interrupt */
-#define IRQ_UART1_RX   BFIN_IRQ(41)    /* UART1 RX (DMA8) Interrupt */
-#define IRQ_UART1_TX   BFIN_IRQ(42)    /* UART1 TX (DMA9) Interrupt */
-#define IRQ_ATAPI_RX   BFIN_IRQ(43)    /* ATAPI RX (DMA10) Interrupt */
-#define IRQ_ATAPI_TX   BFIN_IRQ(44)    /* ATAPI TX (DMA11) Interrupt */
-#define IRQ_TWI0       BFIN_IRQ(45)    /* TWI0 Interrupt */
-#define IRQ_TWI1       BFIN_IRQ(46)    /* TWI1 Interrupt */
-#define IRQ_TWI                IRQ_TWI0        /* TWI Interrupt */
-#define IRQ_CAN0_RX    BFIN_IRQ(47)    /* CAN0 Receive Interrupt */
-#define IRQ_CAN0_TX    BFIN_IRQ(48)    /* CAN0 Transmit Interrupt */
-#define IRQ_MDMAS2     BFIN_IRQ(49)    /* MDMA Stream 2 Interrupt */
-#define IRQ_MDMAS3     BFIN_IRQ(50)    /* MDMA Stream 3 Interrupt */
-#define IRQ_MXVR_ERR   BFIN_IRQ(51)    /* MXVR Status (Error) Interrupt */
-#define IRQ_MXVR_MSG   BFIN_IRQ(52)    /* MXVR Message Interrupt */
-#define IRQ_MXVR_PKT   BFIN_IRQ(53)    /* MXVR Packet Interrupt */
-#define IRQ_EPP1_ERR   BFIN_IRQ(54)    /* EPPI1 Error Interrupt */
-#define IRQ_EPP2_ERR   BFIN_IRQ(55)    /* EPPI2 Error Interrupt */
-#define IRQ_UART3_ERR  BFIN_IRQ(56)    /* UART3 Status (Error) Interrupt */
-#define IRQ_HOST_ERR   BFIN_IRQ(57)    /* HOST Status (Error) Interrupt */
-#define IRQ_PIXC_ERR   BFIN_IRQ(59)    /* PIXC Status (Error) Interrupt */
-#define IRQ_NFC_ERR    BFIN_IRQ(60)    /* NFC Error Interrupt */
-#define IRQ_ATAPI_ERR  BFIN_IRQ(61)    /* ATAPI Error Interrupt */
-#define IRQ_CAN1_ERR   BFIN_IRQ(62)    /* CAN1 Status (Error) Interrupt */
-#define IRQ_HS_DMA_ERR BFIN_IRQ(63)    /* Handshake DMA Status Interrupt */
-#define IRQ_PIXC_IN0   BFIN_IRQ(64)    /* PIXC IN0 (DMA15) Interrupt */
-#define IRQ_PIXC_IN1   BFIN_IRQ(65)    /* PIXC IN1 (DMA16) Interrupt */
-#define IRQ_PIXC_OUT   BFIN_IRQ(66)    /* PIXC OUT (DMA17) Interrupt */
-#define IRQ_SDH                BFIN_IRQ(67)    /* SDH/NFC (DMA22) Interrupt */
-#define IRQ_CNT                BFIN_IRQ(68)    /* CNT Interrupt */
-#define IRQ_KEY                BFIN_IRQ(69)    /* KEY Interrupt */
-#define IRQ_CAN1_RX    BFIN_IRQ(70)    /* CAN1 RX Interrupt */
-#define IRQ_CAN1_TX    BFIN_IRQ(71)    /* CAN1 TX Interrupt */
-#define IRQ_SDH_MASK0  BFIN_IRQ(72)    /* SDH Mask 0 Interrupt */
-#define IRQ_SDH_MASK1  BFIN_IRQ(73)    /* SDH Mask 1 Interrupt */
-#define IRQ_USB_INT0   BFIN_IRQ(75)    /* USB INT0 Interrupt */
-#define IRQ_USB_INT1   BFIN_IRQ(76)    /* USB INT1 Interrupt */
-#define IRQ_USB_INT2   BFIN_IRQ(77)    /* USB INT2 Interrupt */
-#define IRQ_USB_DMA    BFIN_IRQ(78)    /* USB DMA Interrupt */
-#define IRQ_OPTSEC     BFIN_IRQ(79)    /* OTPSEC Interrupt */
-#define IRQ_TIMER0     BFIN_IRQ(86)    /* Timer 0 Interrupt */
-#define IRQ_TIMER1     BFIN_IRQ(87)    /* Timer 1 Interrupt */
-#define IRQ_TIMER2     BFIN_IRQ(88)    /* Timer 2 Interrupt */
-#define IRQ_TIMER3     BFIN_IRQ(89)    /* Timer 3 Interrupt */
-#define IRQ_TIMER4     BFIN_IRQ(90)    /* Timer 4 Interrupt */
-#define IRQ_TIMER5     BFIN_IRQ(91)    /* Timer 5 Interrupt */
-#define IRQ_TIMER6     BFIN_IRQ(92)    /* Timer 6 Interrupt */
-#define IRQ_TIMER7     BFIN_IRQ(93)    /* Timer 7 Interrupt */
-#define IRQ_PINT2      BFIN_IRQ(94)    /* PINT2 Interrupt */
-#define IRQ_PINT3      BFIN_IRQ(95)    /* PINT3 Interrupt */
-
-#define SYS_IRQS        IRQ_PINT3
-
-#define BFIN_PA_IRQ(x) ((x) + SYS_IRQS + 1)
-#define IRQ_PA0                BFIN_PA_IRQ(0)
-#define IRQ_PA1                BFIN_PA_IRQ(1)
-#define IRQ_PA2                BFIN_PA_IRQ(2)
-#define IRQ_PA3                BFIN_PA_IRQ(3)
-#define IRQ_PA4                BFIN_PA_IRQ(4)
-#define IRQ_PA5                BFIN_PA_IRQ(5)
-#define IRQ_PA6                BFIN_PA_IRQ(6)
-#define IRQ_PA7                BFIN_PA_IRQ(7)
-#define IRQ_PA8                BFIN_PA_IRQ(8)
-#define IRQ_PA9                BFIN_PA_IRQ(9)
-#define IRQ_PA10       BFIN_PA_IRQ(10)
-#define IRQ_PA11       BFIN_PA_IRQ(11)
-#define IRQ_PA12       BFIN_PA_IRQ(12)
-#define IRQ_PA13       BFIN_PA_IRQ(13)
-#define IRQ_PA14       BFIN_PA_IRQ(14)
-#define IRQ_PA15       BFIN_PA_IRQ(15)
-
-#define BFIN_PB_IRQ(x) ((x) + IRQ_PA15 + 1)
-#define IRQ_PB0                BFIN_PB_IRQ(0)
-#define IRQ_PB1                BFIN_PB_IRQ(1)
-#define IRQ_PB2                BFIN_PB_IRQ(2)
-#define IRQ_PB3                BFIN_PB_IRQ(3)
-#define IRQ_PB4                BFIN_PB_IRQ(4)
-#define IRQ_PB5                BFIN_PB_IRQ(5)
-#define IRQ_PB6                BFIN_PB_IRQ(6)
-#define IRQ_PB7                BFIN_PB_IRQ(7)
-#define IRQ_PB8                BFIN_PB_IRQ(8)
-#define IRQ_PB9                BFIN_PB_IRQ(9)
-#define IRQ_PB10       BFIN_PB_IRQ(10)
-#define IRQ_PB11       BFIN_PB_IRQ(11)
-#define IRQ_PB12       BFIN_PB_IRQ(12)
-#define IRQ_PB13       BFIN_PB_IRQ(13)
-#define IRQ_PB14       BFIN_PB_IRQ(14)
-#define IRQ_PB15       BFIN_PB_IRQ(15)         /* N/A */
-
-#define BFIN_PC_IRQ(x) ((x) + IRQ_PB15 + 1)
-#define IRQ_PC0                BFIN_PC_IRQ(0)
-#define IRQ_PC1                BFIN_PC_IRQ(1)
-#define IRQ_PC2                BFIN_PC_IRQ(2)
-#define IRQ_PC3                BFIN_PC_IRQ(3)
-#define IRQ_PC4                BFIN_PC_IRQ(4)
-#define IRQ_PC5                BFIN_PC_IRQ(5)
-#define IRQ_PC6                BFIN_PC_IRQ(6)
-#define IRQ_PC7                BFIN_PC_IRQ(7)
-#define IRQ_PC8                BFIN_PC_IRQ(8)
-#define IRQ_PC9                BFIN_PC_IRQ(9)
-#define IRQ_PC10       BFIN_PC_IRQ(10)
-#define IRQ_PC11       BFIN_PC_IRQ(11)
-#define IRQ_PC12       BFIN_PC_IRQ(12)
-#define IRQ_PC13       BFIN_PC_IRQ(13)
-#define IRQ_PC14       BFIN_PC_IRQ(14)         /* N/A */
-#define IRQ_PC15       BFIN_PC_IRQ(15)         /* N/A */
-
-#define BFIN_PD_IRQ(x) ((x) + IRQ_PC15 + 1)
-#define IRQ_PD0                BFIN_PD_IRQ(0)
-#define IRQ_PD1                BFIN_PD_IRQ(1)
-#define IRQ_PD2                BFIN_PD_IRQ(2)
-#define IRQ_PD3                BFIN_PD_IRQ(3)
-#define IRQ_PD4                BFIN_PD_IRQ(4)
-#define IRQ_PD5                BFIN_PD_IRQ(5)
-#define IRQ_PD6                BFIN_PD_IRQ(6)
-#define IRQ_PD7                BFIN_PD_IRQ(7)
-#define IRQ_PD8                BFIN_PD_IRQ(8)
-#define IRQ_PD9                BFIN_PD_IRQ(9)
-#define IRQ_PD10       BFIN_PD_IRQ(10)
-#define IRQ_PD11       BFIN_PD_IRQ(11)
-#define IRQ_PD12       BFIN_PD_IRQ(12)
-#define IRQ_PD13       BFIN_PD_IRQ(13)
-#define IRQ_PD14       BFIN_PD_IRQ(14)
-#define IRQ_PD15       BFIN_PD_IRQ(15)
-
-#define BFIN_PE_IRQ(x) ((x) + IRQ_PD15 + 1)
-#define IRQ_PE0                BFIN_PE_IRQ(0)
-#define IRQ_PE1                BFIN_PE_IRQ(1)
-#define IRQ_PE2                BFIN_PE_IRQ(2)
-#define IRQ_PE3                BFIN_PE_IRQ(3)
-#define IRQ_PE4                BFIN_PE_IRQ(4)
-#define IRQ_PE5                BFIN_PE_IRQ(5)
-#define IRQ_PE6                BFIN_PE_IRQ(6)
-#define IRQ_PE7                BFIN_PE_IRQ(7)
-#define IRQ_PE8                BFIN_PE_IRQ(8)
-#define IRQ_PE9                BFIN_PE_IRQ(9)
-#define IRQ_PE10       BFIN_PE_IRQ(10)
-#define IRQ_PE11       BFIN_PE_IRQ(11)
-#define IRQ_PE12       BFIN_PE_IRQ(12)
-#define IRQ_PE13       BFIN_PE_IRQ(13)
-#define IRQ_PE14       BFIN_PE_IRQ(14)
-#define IRQ_PE15       BFIN_PE_IRQ(15)
-
-#define BFIN_PF_IRQ(x) ((x) + IRQ_PE15 + 1)
-#define IRQ_PF0                BFIN_PF_IRQ(0)
-#define IRQ_PF1                BFIN_PF_IRQ(1)
-#define IRQ_PF2                BFIN_PF_IRQ(2)
-#define IRQ_PF3                BFIN_PF_IRQ(3)
-#define IRQ_PF4                BFIN_PF_IRQ(4)
-#define IRQ_PF5                BFIN_PF_IRQ(5)
-#define IRQ_PF6                BFIN_PF_IRQ(6)
-#define IRQ_PF7                BFIN_PF_IRQ(7)
-#define IRQ_PF8                BFIN_PF_IRQ(8)
-#define IRQ_PF9                BFIN_PF_IRQ(9)
-#define IRQ_PF10       BFIN_PF_IRQ(10)
-#define IRQ_PF11       BFIN_PF_IRQ(11)
-#define IRQ_PF12       BFIN_PF_IRQ(12)
-#define IRQ_PF13       BFIN_PF_IRQ(13)
-#define IRQ_PF14       BFIN_PF_IRQ(14)
-#define IRQ_PF15       BFIN_PF_IRQ(15)
-
-#define BFIN_PG_IRQ(x) ((x) + IRQ_PF15 + 1)
-#define IRQ_PG0                BFIN_PG_IRQ(0)
-#define IRQ_PG1                BFIN_PG_IRQ(1)
-#define IRQ_PG2                BFIN_PG_IRQ(2)
-#define IRQ_PG3                BFIN_PG_IRQ(3)
-#define IRQ_PG4                BFIN_PG_IRQ(4)
-#define IRQ_PG5                BFIN_PG_IRQ(5)
-#define IRQ_PG6                BFIN_PG_IRQ(6)
-#define IRQ_PG7                BFIN_PG_IRQ(7)
-#define IRQ_PG8                BFIN_PG_IRQ(8)
-#define IRQ_PG9                BFIN_PG_IRQ(9)
-#define IRQ_PG10       BFIN_PG_IRQ(10)
-#define IRQ_PG11       BFIN_PG_IRQ(11)
-#define IRQ_PG12       BFIN_PG_IRQ(12)
-#define IRQ_PG13       BFIN_PG_IRQ(13)
-#define IRQ_PG14       BFIN_PG_IRQ(14)
-#define IRQ_PG15       BFIN_PG_IRQ(15)
-
-#define BFIN_PH_IRQ(x) ((x) + IRQ_PG15 + 1)
-#define IRQ_PH0                BFIN_PH_IRQ(0)
-#define IRQ_PH1                BFIN_PH_IRQ(1)
-#define IRQ_PH2                BFIN_PH_IRQ(2)
-#define IRQ_PH3                BFIN_PH_IRQ(3)
-#define IRQ_PH4                BFIN_PH_IRQ(4)
-#define IRQ_PH5                BFIN_PH_IRQ(5)
-#define IRQ_PH6                BFIN_PH_IRQ(6)
-#define IRQ_PH7                BFIN_PH_IRQ(7)
-#define IRQ_PH8                BFIN_PH_IRQ(8)
-#define IRQ_PH9                BFIN_PH_IRQ(9)
-#define IRQ_PH10       BFIN_PH_IRQ(10)
-#define IRQ_PH11       BFIN_PH_IRQ(11)
-#define IRQ_PH12       BFIN_PH_IRQ(12)
-#define IRQ_PH13       BFIN_PH_IRQ(13)
-#define IRQ_PH14       BFIN_PH_IRQ(14)         /* N/A */
-#define IRQ_PH15       BFIN_PH_IRQ(15)         /* N/A */
-
-#define BFIN_PI_IRQ(x) ((x) + IRQ_PH15 + 1)
-#define IRQ_PI0                BFIN_PI_IRQ(0)
-#define IRQ_PI1                BFIN_PI_IRQ(1)
-#define IRQ_PI2                BFIN_PI_IRQ(2)
-#define IRQ_PI3                BFIN_PI_IRQ(3)
-#define IRQ_PI4                BFIN_PI_IRQ(4)
-#define IRQ_PI5                BFIN_PI_IRQ(5)
-#define IRQ_PI6                BFIN_PI_IRQ(6)
-#define IRQ_PI7                BFIN_PI_IRQ(7)
-#define IRQ_PI8                BFIN_PI_IRQ(8)
-#define IRQ_PI9                BFIN_PI_IRQ(9)
-#define IRQ_PI10       BFIN_PI_IRQ(10)
-#define IRQ_PI11       BFIN_PI_IRQ(11)
-#define IRQ_PI12       BFIN_PI_IRQ(12)
-#define IRQ_PI13       BFIN_PI_IRQ(13)
-#define IRQ_PI14       BFIN_PI_IRQ(14)
-#define IRQ_PI15       BFIN_PI_IRQ(15)
-
-#define BFIN_PJ_IRQ(x) ((x) + IRQ_PI15 + 1)
-#define IRQ_PJ0                BFIN_PJ_IRQ(0)
-#define IRQ_PJ1                BFIN_PJ_IRQ(1)
-#define IRQ_PJ2                BFIN_PJ_IRQ(2)
-#define IRQ_PJ3                BFIN_PJ_IRQ(3)
-#define IRQ_PJ4                BFIN_PJ_IRQ(4)
-#define IRQ_PJ5                BFIN_PJ_IRQ(5)
-#define IRQ_PJ6                BFIN_PJ_IRQ(6)
-#define IRQ_PJ7                BFIN_PJ_IRQ(7)
-#define IRQ_PJ8                BFIN_PJ_IRQ(8)
-#define IRQ_PJ9                BFIN_PJ_IRQ(9)
-#define IRQ_PJ10       BFIN_PJ_IRQ(10)
-#define IRQ_PJ11       BFIN_PJ_IRQ(11)
-#define IRQ_PJ12       BFIN_PJ_IRQ(12)
-#define IRQ_PJ13       BFIN_PJ_IRQ(13)
-#define IRQ_PJ14       BFIN_PJ_IRQ(14)         /* N/A */
-#define IRQ_PJ15       BFIN_PJ_IRQ(15)         /* N/A */
+#define IRQ_EMU                        0       /* Emulation */
+#define IRQ_RST                        1       /* reset */
+#define IRQ_NMI                        2       /* Non Maskable */
+#define IRQ_EVX                        3       /* Exception */
+#define IRQ_UNUSED             4       /* - unused interrupt*/
+#define IRQ_HWERR              5       /* Hardware Error */
+#define IRQ_CORETMR            6       /* Core timer */
+
+#define BFIN_IRQ(x)            ((x) + 7)
+
+#define IRQ_PLL_WAKEUP         BFIN_IRQ(0)     /* PLL Wakeup Interrupt */
+#define IRQ_DMAC0_ERROR                BFIN_IRQ(1)     /* DMAC0 Status Interrupt */
+#define IRQ_EPPI0_ERROR                BFIN_IRQ(2)     /* EPPI0 Error Interrupt */
+#define IRQ_SPORT0_ERROR       BFIN_IRQ(3)     /* SPORT0 Error Interrupt */
+#define IRQ_SPORT1_ERROR       BFIN_IRQ(4)     /* SPORT1 Error Interrupt */
+#define IRQ_SPI0_ERROR         BFIN_IRQ(5)     /* SPI0 Status(Error) Interrupt */
+#define IRQ_UART0_ERROR                BFIN_IRQ(6)     /* UART0 Status(Error) Interrupt */
+#define IRQ_RTC                        BFIN_IRQ(7)     /* RTC Interrupt */
+#define IRQ_EPPI0              BFIN_IRQ(8)     /* EPPI0 Interrupt (DMA12) */
+#define IRQ_SPORT0_RX          BFIN_IRQ(9)     /* SPORT0 RX Interrupt (DMA0) */
+#define IRQ_SPORT0_TX          BFIN_IRQ(10)    /* SPORT0 TX Interrupt (DMA1) */
+#define IRQ_SPORT1_RX          BFIN_IRQ(11)    /* SPORT1 RX Interrupt (DMA2) */
+#define IRQ_SPORT1_TX          BFIN_IRQ(12)    /* SPORT1 TX Interrupt (DMA3) */
+#define IRQ_SPI0               BFIN_IRQ(13)    /* SPI0 Interrupt (DMA4) */
+#define IRQ_UART0_RX           BFIN_IRQ(14)    /* UART0 RX Interrupt (DMA6) */
+#define IRQ_UART0_TX           BFIN_IRQ(15)    /* UART0 TX Interrupt (DMA7) */
+#define IRQ_TIMER8             BFIN_IRQ(16)    /* TIMER 8 Interrupt */
+#define IRQ_TIMER9             BFIN_IRQ(17)    /* TIMER 9 Interrupt */
+#define IRQ_TIMER10            BFIN_IRQ(18)    /* TIMER 10 Interrupt */
+#define IRQ_PINT0              BFIN_IRQ(19)    /* PINT0 Interrupt */
+#define IRQ_PINT1              BFIN_IRQ(20)    /* PINT1 Interrupt */
+#define IRQ_MDMAS0             BFIN_IRQ(21)    /* MDMA Stream 0 Interrupt */
+#define IRQ_MDMAS1             BFIN_IRQ(22)    /* MDMA Stream 1 Interrupt */
+#define IRQ_WATCHDOG           BFIN_IRQ(23)    /* Watchdog Interrupt */
+#define IRQ_DMAC1_ERROR                BFIN_IRQ(24)    /* DMAC1 Status (Error) Interrupt */
+#define IRQ_SPORT2_ERROR       BFIN_IRQ(25)    /* SPORT2 Error Interrupt */
+#define IRQ_SPORT3_ERROR       BFIN_IRQ(26)    /* SPORT3 Error Interrupt */
+#define IRQ_MXVR_DATA          BFIN_IRQ(27)    /* MXVR Data Interrupt */
+#define IRQ_SPI1_ERROR         BFIN_IRQ(28)    /* SPI1 Status (Error) Interrupt */
+#define IRQ_SPI2_ERROR         BFIN_IRQ(29)    /* SPI2 Status (Error) Interrupt */
+#define IRQ_UART1_ERROR                BFIN_IRQ(30)    /* UART1 Status (Error) Interrupt */
+#define IRQ_UART2_ERROR                BFIN_IRQ(31)    /* UART2 Status (Error) Interrupt */
+#define IRQ_CAN0_ERROR         BFIN_IRQ(32)    /* CAN0 Status (Error) Interrupt */
+#define IRQ_SPORT2_RX          BFIN_IRQ(33)    /* SPORT2 RX (DMA18) Interrupt */
+#define IRQ_SPORT2_TX          BFIN_IRQ(34)    /* SPORT2 TX (DMA19) Interrupt */
+#define IRQ_SPORT3_RX          BFIN_IRQ(35)    /* SPORT3 RX (DMA20) Interrupt */
+#define IRQ_SPORT3_TX          BFIN_IRQ(36)    /* SPORT3 TX (DMA21) Interrupt */
+#define IRQ_EPPI1              BFIN_IRQ(37)    /* EPP1 (DMA13) Interrupt */
+#define IRQ_EPPI2              BFIN_IRQ(38)    /* EPP2 (DMA14) Interrupt */
+#define IRQ_SPI1               BFIN_IRQ(39)    /* SPI1 (DMA5) Interrupt */
+#define IRQ_SPI2               BFIN_IRQ(40)    /* SPI2 (DMA23) Interrupt */
+#define IRQ_UART1_RX           BFIN_IRQ(41)    /* UART1 RX (DMA8) Interrupt */
+#define IRQ_UART1_TX           BFIN_IRQ(42)    /* UART1 TX (DMA9) Interrupt */
+#define IRQ_ATAPI_RX           BFIN_IRQ(43)    /* ATAPI RX (DMA10) Interrupt */
+#define IRQ_ATAPI_TX           BFIN_IRQ(44)    /* ATAPI TX (DMA11) Interrupt */
+#define IRQ_TWI0               BFIN_IRQ(45)    /* TWI0 Interrupt */
+#define IRQ_TWI1               BFIN_IRQ(46)    /* TWI1 Interrupt */
+#define IRQ_CAN0_RX            BFIN_IRQ(47)    /* CAN0 Receive Interrupt */
+#define IRQ_CAN0_TX            BFIN_IRQ(48)    /* CAN0 Transmit Interrupt */
+#define IRQ_MDMAS2             BFIN_IRQ(49)    /* MDMA Stream 2 Interrupt */
+#define IRQ_MDMAS3             BFIN_IRQ(50)    /* MDMA Stream 3 Interrupt */
+#define IRQ_MXVR_ERROR         BFIN_IRQ(51)    /* MXVR Status (Error) Interrupt */
+#define IRQ_MXVR_MSG           BFIN_IRQ(52)    /* MXVR Message Interrupt */
+#define IRQ_MXVR_PKT           BFIN_IRQ(53)    /* MXVR Packet Interrupt */
+#define IRQ_EPP1_ERROR         BFIN_IRQ(54)    /* EPPI1 Error Interrupt */
+#define IRQ_EPP2_ERROR         BFIN_IRQ(55)    /* EPPI2 Error Interrupt */
+#define IRQ_UART3_ERROR                BFIN_IRQ(56)    /* UART3 Status (Error) Interrupt */
+#define IRQ_HOST_ERROR         BFIN_IRQ(57)    /* HOST Status (Error) Interrupt */
+#define IRQ_PIXC_ERROR         BFIN_IRQ(59)    /* PIXC Status (Error) Interrupt */
+#define IRQ_NFC_ERROR          BFIN_IRQ(60)    /* NFC Error Interrupt */
+#define IRQ_ATAPI_ERROR                BFIN_IRQ(61)    /* ATAPI Error Interrupt */
+#define IRQ_CAN1_ERROR         BFIN_IRQ(62)    /* CAN1 Status (Error) Interrupt */
+#define IRQ_HS_DMA_ERROR       BFIN_IRQ(63)    /* Handshake DMA Status Interrupt */
+#define IRQ_PIXC_IN0           BFIN_IRQ(64)    /* PIXC IN0 (DMA15) Interrupt */
+#define IRQ_PIXC_IN1           BFIN_IRQ(65)    /* PIXC IN1 (DMA16) Interrupt */
+#define IRQ_PIXC_OUT           BFIN_IRQ(66)    /* PIXC OUT (DMA17) Interrupt */
+#define IRQ_SDH                        BFIN_IRQ(67)    /* SDH/NFC (DMA22) Interrupt */
+#define IRQ_CNT                        BFIN_IRQ(68)    /* CNT Interrupt */
+#define IRQ_KEY                        BFIN_IRQ(69)    /* KEY Interrupt */
+#define IRQ_CAN1_RX            BFIN_IRQ(70)    /* CAN1 RX Interrupt */
+#define IRQ_CAN1_TX            BFIN_IRQ(71)    /* CAN1 TX Interrupt */
+#define IRQ_SDH_MASK0          BFIN_IRQ(72)    /* SDH Mask 0 Interrupt */
+#define IRQ_SDH_MASK1          BFIN_IRQ(73)    /* SDH Mask 1 Interrupt */
+#define IRQ_USB_INT0           BFIN_IRQ(75)    /* USB INT0 Interrupt */
+#define IRQ_USB_INT1           BFIN_IRQ(76)    /* USB INT1 Interrupt */
+#define IRQ_USB_INT2           BFIN_IRQ(77)    /* USB INT2 Interrupt */
+#define IRQ_USB_DMA            BFIN_IRQ(78)    /* USB DMA Interrupt */
+#define IRQ_OPTSEC             BFIN_IRQ(79)    /* OTPSEC Interrupt */
+#define IRQ_TIMER0             BFIN_IRQ(86)    /* Timer 0 Interrupt */
+#define IRQ_TIMER1             BFIN_IRQ(87)    /* Timer 1 Interrupt */
+#define IRQ_TIMER2             BFIN_IRQ(88)    /* Timer 2 Interrupt */
+#define IRQ_TIMER3             BFIN_IRQ(89)    /* Timer 3 Interrupt */
+#define IRQ_TIMER4             BFIN_IRQ(90)    /* Timer 4 Interrupt */
+#define IRQ_TIMER5             BFIN_IRQ(91)    /* Timer 5 Interrupt */
+#define IRQ_TIMER6             BFIN_IRQ(92)    /* Timer 6 Interrupt */
+#define IRQ_TIMER7             BFIN_IRQ(93)    /* Timer 7 Interrupt */
+#define IRQ_PINT2              BFIN_IRQ(94)    /* PINT2 Interrupt */
+#define IRQ_PINT3              BFIN_IRQ(95)    /* PINT3 Interrupt */
+
+#define SYS_IRQS               IRQ_PINT3
+
+#define BFIN_PA_IRQ(x)         ((x) + SYS_IRQS + 1)
+#define IRQ_PA0                        BFIN_PA_IRQ(0)
+#define IRQ_PA1                        BFIN_PA_IRQ(1)
+#define IRQ_PA2                        BFIN_PA_IRQ(2)
+#define IRQ_PA3                        BFIN_PA_IRQ(3)
+#define IRQ_PA4                        BFIN_PA_IRQ(4)
+#define IRQ_PA5                        BFIN_PA_IRQ(5)
+#define IRQ_PA6                        BFIN_PA_IRQ(6)
+#define IRQ_PA7                        BFIN_PA_IRQ(7)
+#define IRQ_PA8                        BFIN_PA_IRQ(8)
+#define IRQ_PA9                        BFIN_PA_IRQ(9)
+#define IRQ_PA10               BFIN_PA_IRQ(10)
+#define IRQ_PA11               BFIN_PA_IRQ(11)
+#define IRQ_PA12               BFIN_PA_IRQ(12)
+#define IRQ_PA13               BFIN_PA_IRQ(13)
+#define IRQ_PA14               BFIN_PA_IRQ(14)
+#define IRQ_PA15               BFIN_PA_IRQ(15)
+
+#define BFIN_PB_IRQ(x)         ((x) + IRQ_PA15 + 1)
+#define IRQ_PB0                        BFIN_PB_IRQ(0)
+#define IRQ_PB1                        BFIN_PB_IRQ(1)
+#define IRQ_PB2                        BFIN_PB_IRQ(2)
+#define IRQ_PB3                        BFIN_PB_IRQ(3)
+#define IRQ_PB4                        BFIN_PB_IRQ(4)
+#define IRQ_PB5                        BFIN_PB_IRQ(5)
+#define IRQ_PB6                        BFIN_PB_IRQ(6)
+#define IRQ_PB7                        BFIN_PB_IRQ(7)
+#define IRQ_PB8                        BFIN_PB_IRQ(8)
+#define IRQ_PB9                        BFIN_PB_IRQ(9)
+#define IRQ_PB10               BFIN_PB_IRQ(10)
+#define IRQ_PB11               BFIN_PB_IRQ(11)
+#define IRQ_PB12               BFIN_PB_IRQ(12)
+#define IRQ_PB13               BFIN_PB_IRQ(13)
+#define IRQ_PB14               BFIN_PB_IRQ(14)
+#define IRQ_PB15               BFIN_PB_IRQ(15)         /* N/A */
+
+#define BFIN_PC_IRQ(x)         ((x) + IRQ_PB15 + 1)
+#define IRQ_PC0                        BFIN_PC_IRQ(0)
+#define IRQ_PC1                        BFIN_PC_IRQ(1)
+#define IRQ_PC2                        BFIN_PC_IRQ(2)
+#define IRQ_PC3                        BFIN_PC_IRQ(3)
+#define IRQ_PC4                        BFIN_PC_IRQ(4)
+#define IRQ_PC5                        BFIN_PC_IRQ(5)
+#define IRQ_PC6                        BFIN_PC_IRQ(6)
+#define IRQ_PC7                        BFIN_PC_IRQ(7)
+#define IRQ_PC8                        BFIN_PC_IRQ(8)
+#define IRQ_PC9                        BFIN_PC_IRQ(9)
+#define IRQ_PC10               BFIN_PC_IRQ(10)
+#define IRQ_PC11               BFIN_PC_IRQ(11)
+#define IRQ_PC12               BFIN_PC_IRQ(12)
+#define IRQ_PC13               BFIN_PC_IRQ(13)
+#define IRQ_PC14               BFIN_PC_IRQ(14)         /* N/A */
+#define IRQ_PC15               BFIN_PC_IRQ(15)         /* N/A */
+
+#define BFIN_PD_IRQ(x)         ((x) + IRQ_PC15 + 1)
+#define IRQ_PD0                        BFIN_PD_IRQ(0)
+#define IRQ_PD1                        BFIN_PD_IRQ(1)
+#define IRQ_PD2                        BFIN_PD_IRQ(2)
+#define IRQ_PD3                        BFIN_PD_IRQ(3)
+#define IRQ_PD4                        BFIN_PD_IRQ(4)
+#define IRQ_PD5                        BFIN_PD_IRQ(5)
+#define IRQ_PD6                        BFIN_PD_IRQ(6)
+#define IRQ_PD7                        BFIN_PD_IRQ(7)
+#define IRQ_PD8                        BFIN_PD_IRQ(8)
+#define IRQ_PD9                        BFIN_PD_IRQ(9)
+#define IRQ_PD10               BFIN_PD_IRQ(10)
+#define IRQ_PD11               BFIN_PD_IRQ(11)
+#define IRQ_PD12               BFIN_PD_IRQ(12)
+#define IRQ_PD13               BFIN_PD_IRQ(13)
+#define IRQ_PD14               BFIN_PD_IRQ(14)
+#define IRQ_PD15               BFIN_PD_IRQ(15)
+
+#define BFIN_PE_IRQ(x)         ((x) + IRQ_PD15 + 1)
+#define IRQ_PE0                        BFIN_PE_IRQ(0)
+#define IRQ_PE1                        BFIN_PE_IRQ(1)
+#define IRQ_PE2                        BFIN_PE_IRQ(2)
+#define IRQ_PE3                        BFIN_PE_IRQ(3)
+#define IRQ_PE4                        BFIN_PE_IRQ(4)
+#define IRQ_PE5                        BFIN_PE_IRQ(5)
+#define IRQ_PE6                        BFIN_PE_IRQ(6)
+#define IRQ_PE7                        BFIN_PE_IRQ(7)
+#define IRQ_PE8                        BFIN_PE_IRQ(8)
+#define IRQ_PE9                        BFIN_PE_IRQ(9)
+#define IRQ_PE10               BFIN_PE_IRQ(10)
+#define IRQ_PE11               BFIN_PE_IRQ(11)
+#define IRQ_PE12               BFIN_PE_IRQ(12)
+#define IRQ_PE13               BFIN_PE_IRQ(13)
+#define IRQ_PE14               BFIN_PE_IRQ(14)
+#define IRQ_PE15               BFIN_PE_IRQ(15)
+
+#define BFIN_PF_IRQ(x)         ((x) + IRQ_PE15 + 1)
+#define IRQ_PF0                        BFIN_PF_IRQ(0)
+#define IRQ_PF1                        BFIN_PF_IRQ(1)
+#define IRQ_PF2                        BFIN_PF_IRQ(2)
+#define IRQ_PF3                        BFIN_PF_IRQ(3)
+#define IRQ_PF4                        BFIN_PF_IRQ(4)
+#define IRQ_PF5                        BFIN_PF_IRQ(5)
+#define IRQ_PF6                        BFIN_PF_IRQ(6)
+#define IRQ_PF7                        BFIN_PF_IRQ(7)
+#define IRQ_PF8                        BFIN_PF_IRQ(8)
+#define IRQ_PF9                        BFIN_PF_IRQ(9)
+#define IRQ_PF10               BFIN_PF_IRQ(10)
+#define IRQ_PF11               BFIN_PF_IRQ(11)
+#define IRQ_PF12               BFIN_PF_IRQ(12)
+#define IRQ_PF13               BFIN_PF_IRQ(13)
+#define IRQ_PF14               BFIN_PF_IRQ(14)
+#define IRQ_PF15               BFIN_PF_IRQ(15)
+
+#define BFIN_PG_IRQ(x)         ((x) + IRQ_PF15 + 1)
+#define IRQ_PG0                        BFIN_PG_IRQ(0)
+#define IRQ_PG1                        BFIN_PG_IRQ(1)
+#define IRQ_PG2                        BFIN_PG_IRQ(2)
+#define IRQ_PG3                        BFIN_PG_IRQ(3)
+#define IRQ_PG4                        BFIN_PG_IRQ(4)
+#define IRQ_PG5                        BFIN_PG_IRQ(5)
+#define IRQ_PG6                        BFIN_PG_IRQ(6)
+#define IRQ_PG7                        BFIN_PG_IRQ(7)
+#define IRQ_PG8                        BFIN_PG_IRQ(8)
+#define IRQ_PG9                        BFIN_PG_IRQ(9)
+#define IRQ_PG10               BFIN_PG_IRQ(10)
+#define IRQ_PG11               BFIN_PG_IRQ(11)
+#define IRQ_PG12               BFIN_PG_IRQ(12)
+#define IRQ_PG13               BFIN_PG_IRQ(13)
+#define IRQ_PG14               BFIN_PG_IRQ(14)
+#define IRQ_PG15               BFIN_PG_IRQ(15)
+
+#define BFIN_PH_IRQ(x)         ((x) + IRQ_PG15 + 1)
+#define IRQ_PH0                        BFIN_PH_IRQ(0)
+#define IRQ_PH1                        BFIN_PH_IRQ(1)
+#define IRQ_PH2                        BFIN_PH_IRQ(2)
+#define IRQ_PH3                        BFIN_PH_IRQ(3)
+#define IRQ_PH4                        BFIN_PH_IRQ(4)
+#define IRQ_PH5                        BFIN_PH_IRQ(5)
+#define IRQ_PH6                        BFIN_PH_IRQ(6)
+#define IRQ_PH7                        BFIN_PH_IRQ(7)
+#define IRQ_PH8                        BFIN_PH_IRQ(8)
+#define IRQ_PH9                        BFIN_PH_IRQ(9)
+#define IRQ_PH10               BFIN_PH_IRQ(10)
+#define IRQ_PH11               BFIN_PH_IRQ(11)
+#define IRQ_PH12               BFIN_PH_IRQ(12)
+#define IRQ_PH13               BFIN_PH_IRQ(13)
+#define IRQ_PH14               BFIN_PH_IRQ(14)         /* N/A */
+#define IRQ_PH15               BFIN_PH_IRQ(15)         /* N/A */
+
+#define BFIN_PI_IRQ(x)         ((x) + IRQ_PH15 + 1)
+#define IRQ_PI0                        BFIN_PI_IRQ(0)
+#define IRQ_PI1                        BFIN_PI_IRQ(1)
+#define IRQ_PI2                        BFIN_PI_IRQ(2)
+#define IRQ_PI3                        BFIN_PI_IRQ(3)
+#define IRQ_PI4                        BFIN_PI_IRQ(4)
+#define IRQ_PI5                        BFIN_PI_IRQ(5)
+#define IRQ_PI6                        BFIN_PI_IRQ(6)
+#define IRQ_PI7                        BFIN_PI_IRQ(7)
+#define IRQ_PI8                        BFIN_PI_IRQ(8)
+#define IRQ_PI9                        BFIN_PI_IRQ(9)
+#define IRQ_PI10               BFIN_PI_IRQ(10)
+#define IRQ_PI11               BFIN_PI_IRQ(11)
+#define IRQ_PI12               BFIN_PI_IRQ(12)
+#define IRQ_PI13               BFIN_PI_IRQ(13)
+#define IRQ_PI14               BFIN_PI_IRQ(14)
+#define IRQ_PI15               BFIN_PI_IRQ(15)
+
+#define BFIN_PJ_IRQ(x)         ((x) + IRQ_PI15 + 1)
+#define IRQ_PJ0                        BFIN_PJ_IRQ(0)
+#define IRQ_PJ1                        BFIN_PJ_IRQ(1)
+#define IRQ_PJ2                        BFIN_PJ_IRQ(2)
+#define IRQ_PJ3                        BFIN_PJ_IRQ(3)
+#define IRQ_PJ4                        BFIN_PJ_IRQ(4)
+#define IRQ_PJ5                        BFIN_PJ_IRQ(5)
+#define IRQ_PJ6                        BFIN_PJ_IRQ(6)
+#define IRQ_PJ7                        BFIN_PJ_IRQ(7)
+#define IRQ_PJ8                        BFIN_PJ_IRQ(8)
+#define IRQ_PJ9                        BFIN_PJ_IRQ(9)
+#define IRQ_PJ10               BFIN_PJ_IRQ(10)
+#define IRQ_PJ11               BFIN_PJ_IRQ(11)
+#define IRQ_PJ12               BFIN_PJ_IRQ(12)
+#define IRQ_PJ13               BFIN_PJ_IRQ(13)
+#define IRQ_PJ14               BFIN_PJ_IRQ(14)         /* N/A */
+#define IRQ_PJ15               BFIN_PJ_IRQ(15)         /* N/A */
+
+#define GPIO_IRQ_BASE  IRQ_PA0
 
 #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
 #define NR_IRQS     (IRQ_PJ15+1)
@@ -343,6 +344,34 @@ Events         (highest priority)  EMU         0
 #define NR_IRQS     (SYS_IRQS+1)
 #endif
 
+/* For compatibility reasons with existing code */
+
+#define IRQ_DMAC0_ERR          IRQ_DMAC0_ERROR
+#define IRQ_EPPI0_ERR          IRQ_EPPI0_ERROR
+#define IRQ_SPORT0_ERR         IRQ_SPORT0_ERROR
+#define IRQ_SPORT1_ERR         IRQ_SPORT1_ERROR
+#define IRQ_SPI0_ERR           IRQ_SPI0_ERROR
+#define IRQ_UART0_ERR          IRQ_UART0_ERROR
+#define IRQ_DMAC1_ERR          IRQ_DMAC1_ERROR
+#define IRQ_SPORT2_ERR         IRQ_SPORT2_ERROR
+#define IRQ_SPORT3_ERR         IRQ_SPORT3_ERROR
+#define IRQ_SPI1_ERR           IRQ_SPI1_ERROR
+#define IRQ_SPI2_ERR           IRQ_SPI2_ERROR
+#define IRQ_UART1_ERR          IRQ_UART1_ERROR
+#define IRQ_UART2_ERR          IRQ_UART2_ERROR
+#define IRQ_CAN0_ERR           IRQ_CAN0_ERROR
+#define IRQ_MXVR_ERR           IRQ_MXVR_ERROR
+#define IRQ_EPP1_ERR           IRQ_EPP1_ERROR
+#define IRQ_EPP2_ERR           IRQ_EPP2_ERROR
+#define IRQ_UART3_ERR          IRQ_UART3_ERROR
+#define IRQ_HOST_ERR           IRQ_HOST_ERROR
+#define IRQ_PIXC_ERR           IRQ_PIXC_ERROR
+#define IRQ_NFC_ERR            IRQ_NFC_ERROR
+#define IRQ_ATAPI_ERR          IRQ_ATAPI_ERROR
+#define IRQ_CAN1_ERR           IRQ_CAN1_ERROR
+#define IRQ_HS_DMA_ERR         IRQ_HS_DMA_ERROR
+
+
 #define IVG7            7
 #define IVG8            8
 #define IVG9            9
index 72d80e8a6e811647fc03a3ceba007c0c89fe80a5..ec1597e318315ca40286ab3aed1f8ebc09ecc511 100644 (file)
 /* Level 1 Memory */
 
 /* Memory Map for ADSP-BF548 processors */
-#ifdef CONFIG_BLKFIN_ICACHE
-#define BLKFIN_ICACHESIZE      (16*1024)
+#ifdef CONFIG_BFIN_ICACHE
+#define BFIN_ICACHESIZE        (16*1024)
 #else
-#define BLKFIN_ICACHESIZE      (0*1024)
+#define BFIN_ICACHESIZE        (0*1024)
 #endif
 
 #define L1_CODE_START       0xFFA00000
 
 #define L1_CODE_LENGTH      0xC000
 
-#ifdef CONFIG_BLKFIN_DCACHE
+#ifdef CONFIG_BFIN_DCACHE
 
-#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#ifdef CONFIG_BFIN_DCACHE_BANKA
 #define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
 #define L1_DATA_B_LENGTH      0x8000
-#define BLKFIN_DCACHESIZE      (16*1024)
-#define BLKFIN_DSUPBANKS       1
+#define BFIN_DCACHESIZE        (16*1024)
+#define BFIN_DSUPBANKS 1
 #else
 #define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
 #define L1_DATA_B_LENGTH      (0x8000 - 0x4000)
-#define BLKFIN_DCACHESIZE      (32*1024)
-#define BLKFIN_DSUPBANKS       2
+#define BFIN_DCACHESIZE        (32*1024)
+#define BFIN_DSUPBANKS 2
 #endif
 
 #else
 #define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      0x8000
 #define L1_DATA_B_LENGTH      0x8000
-#define BLKFIN_DCACHESIZE      (0*1024)
-#define BLKFIN_DSUPBANKS       0
-#endif /*CONFIG_BLKFIN_DCACHE*/
+#define BFIN_DCACHESIZE        (0*1024)
+#define BFIN_DSUPBANKS 0
+#endif /*CONFIG_BFIN_DCACHE*/
 
 /* Scratch Pad Memory */
 
index f5b32d66517d248e180c707f85a3e0af4d0b8427..bed956456884b4c1c8bfdcea5216f69c59a45316 100644 (file)
-
 /*
- * File:         include/asm-blackfin/mach-bf561/anomaly.h
- * Based on:
- * Author:
- *
- * Created:
- * Description:
- *
- * Rev:
- *
- * Modified:
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ * File: include/asm-blackfin/mach-bf561/anomaly.h
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.
- * If not, write to the Free Software Foundation,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Copyright (C) 2004-2007 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
  */
 
 /* This file shoule be up to date with:
- *  - Revision L, 10Aug2006; ADSP-BF561 Silicon Anomaly List
+ *  - Revision N, March 28, 2007; ADSP-BF561 Silicon Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
 #define _MACH_ANOMALY_H_
 
-/* We do not support 0.1 or 0.4 silicon - sorry */
-#if (defined(CONFIG_BF_REV_0_1) || defined(CONFIG_BF_REV_0_2) || defined(CONFIG_BF_REV_0_4))
-#error Kernel will not work on BF561 Version 0.1, 0.2, or 0.4
+/* We do not support 0.1, 0.2, or 0.4 silicon - sorry */
+#if __SILICON_REVISION__ < 3 || __SILICON_REVISION__ == 4
+# error Kernel will not work on BF561 silicon version 0.0, 0.1, 0.2, or 0.4
 #endif
 
-/* Issues that are common to 0.5 and  0.3 silicon */
-#if  (defined(CONFIG_BF_REV_0_5) || defined(CONFIG_BF_REV_0_3))
-#define ANOMALY_05000074 /* A multi issue instruction with dsp32shiftimm in
-                            slot1 and store of a P register in slot 2 is not
-                            supported */
-#define ANOMALY_05000099 /* UART Line Status Register (UART_LSR) bits are not
-                            updated at the same time. */
-#define ANOMALY_05000120 /* Testset instructions restricted to 32-bit aligned
-                            memory locations */
-#define ANOMALY_05000122 /* Rx.H cannot be used to access 16-bit System MMR
-                            registers */
-#define ANOMALY_05000127 /* Signbits instruction not functional under certain
-                            conditions */
-#define ANOMALY_05000149 /* IMDMA S1/D1 channel may stall */
-#define ANOMALY_05000166 /* PPI Data Lengths Between 8 and 16 do not zero out
-                            upper bits */
-#define ANOMALY_05000167 /* Turning Serial Ports on With External Frame Syncs */
-#define ANOMALY_05000180 /* PPI_DELAY not functional in PPI modes with 0 frame
-                            syncs */
-#define ANOMALY_05000182 /* IMDMA does not operate to full speed for 600MHz
-                            and higher devices */
-#define ANOMALY_05000187 /* IMDMA Corrupted Data after a Halt */
-#define ANOMALY_05000190 /* PPI not functional at core voltage < 1Volt */
-#define ANOMALY_05000208 /* VSTAT status bit in PLL_STAT register is not
-                            functional */
-#define ANOMALY_05000245 /* Spurious Hardware Error from an access in the
-                            shadow of a conditional branch */
-#define ANOMALY_05000257 /* Interrupt/Exception during short hardware loop
-                            may cause bad instruction fetches */
-#define ANOMALY_05000265 /* Sensitivity to noise with slow input edge rates on
-                            external SPORT TX and RX clocks */
-#define ANOMALY_05000267 /* IMDMA may corrupt data under certain conditions */
-#define ANOMALY_05000269 /* High I/O activity causes output voltage of internal
-                            voltage regulator (VDDint) to increase */
-#define ANOMALY_05000270 /* High I/O activity causes output voltage of internal
-                            voltage regulator (VDDint) to decrease */
-#define ANOMALY_05000272 /* Certain data cache write through modes fail for
-                            VDDint <=0.9V */
-#define ANOMALY_05000274 /* Data cache write back to external synchronous memory
-                            may be lost */
-#define ANOMALY_05000275 /* PPI Timing and sampling informaton updates */
-#define ANOMALY_05000312 /* Errors when SSYNC, CSYNC, or loads to LT, LB and LC
-                           registers are interrupted */
+/* Multi-Issue Instruction with dsp32shiftimm in slot1 and P-reg Store in slot 2 Not Supported */
+#define ANOMALY_05000074 (1)
+/* UART Line Status Register (UART_LSR) Bits Are Not Updated at the Same Time */
+#define ANOMALY_05000099 (__SILICON_REVISION__ < 5)
+/* Trace Buffers may contain errors in emulation mode and/or exception, NMI, reset handlers */
+#define ANOMALY_05000116 (__SILICON_REVISION__ < 3)
+/* Testset instructions restricted to 32-bit aligned memory locations */
+#define ANOMALY_05000120 (1)
+/* Rx.H Cannot Be Used to Access 16-bit System MMR Registers */
+#define ANOMALY_05000122 (1)
+/* Erroneous exception when enabling cache */
+#define ANOMALY_05000125 (__SILICON_REVISION__ < 3)
+/* Signbits instruction not functional under certain conditions */
+#define ANOMALY_05000127 (1)
+/* Two bits in the Watchpoint Status Register (WPSTAT) are swapped */
+#define ANOMALY_05000134 (__SILICON_REVISION__ < 3)
+/* Enable wires from the Data Watchpoint Address Control Register (WPDACTL) are swapped */
+#define ANOMALY_05000135 (__SILICON_REVISION__ < 3)
+/* Stall in multi-unit DMA operations */
+#define ANOMALY_05000136 (__SILICON_REVISION__ < 3)
+/* Allowing the SPORT RX FIFO to fill will cause an overflow */
+#define ANOMALY_05000140 (__SILICON_REVISION__ < 3)
+/* Infinite Stall may occur with a particular sequence of consecutive dual dag events */
+#define ANOMALY_05000141 (__SILICON_REVISION__ < 3)
+/* Interrupts may be lost when a programmable input flag is configured to be edge sensitive */
+#define ANOMALY_05000142 (__SILICON_REVISION__ < 3)
+/* DMA and TESTSET conflict when both are accessing external memory */
+#define ANOMALY_05000144 (__SILICON_REVISION__ < 3)
+/* In PWM_OUT mode, you must enable the PPI block to generate a waveform from PPI_CLK */
+#define ANOMALY_05000145 (__SILICON_REVISION__ < 3)
+/* MDMA may lose the first few words of a descriptor chain */
+#define ANOMALY_05000146 (__SILICON_REVISION__ < 3)
+/* Source MDMA descriptor may stop with a DMA Error near beginning of descriptor fetch */
+#define ANOMALY_05000147 (__SILICON_REVISION__ < 3)
+/* IMDMA S1/D1 channel may stall */
+#define ANOMALY_05000149 (1)
+/* DMA engine may lose data due to incorrect handshaking */
+#define ANOMALY_05000150 (__SILICON_REVISION__ < 3)
+/* DMA stalls when all three controllers read data from the same source */
+#define ANOMALY_05000151 (__SILICON_REVISION__ < 3)
+/* Execution stall when executing in L2 and doing external accesses */
+#define ANOMALY_05000152 (__SILICON_REVISION__ < 3)
+/* Frame Delay in SPORT Multichannel Mode */
+#define ANOMALY_05000153 (__SILICON_REVISION__ < 3)
+/* SPORT TFS signal stays active in multichannel mode outside of valid channels */
+#define ANOMALY_05000154 (__SILICON_REVISION__ < 3)
+/* Timers in PWM-Out Mode with PPI GP Receive (Input) Mode with 0 Frame Syncs */
+#define ANOMALY_05000156 (__SILICON_REVISION__ < 4)
+/* Killed 32-bit MMR write leads to next system MMR access thinking it should be 32-bit */
+#define ANOMALY_05000157 (__SILICON_REVISION__ < 3)
+/* DMA Lock-up at CCLK to SCLK ratios of 4:1, 2:1, or 1:1 */
+#define ANOMALY_05000159 (__SILICON_REVISION__ < 3)
+/* A read from external memory may return a wrong value with data cache enabled */
+#define ANOMALY_05000160 (__SILICON_REVISION__ < 3)
+/* Data Cache Fill data can be corrupted after/during Instruction DMA if certain core stalls exist */
+#define ANOMALY_05000161 (__SILICON_REVISION__ < 3)
+/* DMEM_CONTROL<12> is not set on Reset */
+#define ANOMALY_05000162 (__SILICON_REVISION__ < 3)
+/* SPORT transmit data is not gated by external frame sync in certain conditions */
+#define ANOMALY_05000163 (__SILICON_REVISION__ < 3)
+/* PPI Data Lengths Between 8 and 16 Do Not Zero Out Upper Bits */
+#define ANOMALY_05000166 (1)
+/* Turning Serial Ports on with External Frame Syncs */
+#define ANOMALY_05000167 (1)
+/* SDRAM auto-refresh and subsequent Power Ups */
+#define ANOMALY_05000168 (__SILICON_REVISION__ < 5)
+/* DATA CPLB page miss can result in lost write-through cache data writes */
+#define ANOMALY_05000169 (__SILICON_REVISION__ < 5)
+/* Boot-ROM code modifies SICA_IWRx wakeup registers */
+#define ANOMALY_05000171 (__SILICON_REVISION__ < 5)
+/* DSPID register values incorrect */
+#define ANOMALY_05000172 (__SILICON_REVISION__ < 3)
+/* DMA vs Core accesses to external memory */
+#define ANOMALY_05000173 (__SILICON_REVISION__ < 3)
+/* Cache Fill Buffer Data lost */
+#define ANOMALY_05000174 (__SILICON_REVISION__ < 5)
+/* Overlapping Sequencer and Memory Stalls */
+#define ANOMALY_05000175 (__SILICON_REVISION__ < 5)
+/* Multiplication of (-1) by (-1) followed by an accumulator saturation */
+#define ANOMALY_05000176 (__SILICON_REVISION__ < 5)
+/* PPI_COUNT Cannot Be Programmed to 0 in General Purpose TX or RX Modes */
+#define ANOMALY_05000179 (__SILICON_REVISION__ < 5)
+/* PPI_DELAY Not Functional in PPI Modes with 0 Frame Syncs */
+#define ANOMALY_05000180 (1)
+/* Disabling the PPI resets the PPI configuration registers */
+#define ANOMALY_05000181 (__SILICON_REVISION__ < 5)
+/* IMDMA does not operate to full speed for 600MHz and higher devices */
+#define ANOMALY_05000182 (1)
+/* Timer Pin limitations for PPI TX Modes with External Frame Syncs */
+#define ANOMALY_05000184 (__SILICON_REVISION__ < 5)
+/* PPI TX Mode with 2 External Frame Syncs */
+#define ANOMALY_05000185 (__SILICON_REVISION__ < 5)
+/* PPI packing with Data Length greater than 8 bits (not a meaningful mode) */
+#define ANOMALY_05000186 (__SILICON_REVISION__ < 5)
+/* IMDMA Corrupted Data after a Halt */
+#define ANOMALY_05000187 (1)
+/* IMDMA Restrictions on Descriptor and Buffer Placement in Memory */
+#define ANOMALY_05000188 (__SILICON_REVISION__ < 5)
+/* False Protection Exceptions */
+#define ANOMALY_05000189 (__SILICON_REVISION__ < 5)
+/* PPI not functional at core voltage < 1Volt */
+#define ANOMALY_05000190 (1)
+/* PPI does not invert the Driving PPICLK edge in Transmit Modes */
+#define ANOMALY_05000191 (__SILICON_REVISION__ < 3)
+/* False I/O Pin Interrupts on Edge-Sensitive Inputs When Polarity Setting Is Changed */
+#define ANOMALY_05000193 (__SILICON_REVISION__ < 5)
+/* Restarting SPORT in Specific Modes May Cause Data Corruption */
+#define ANOMALY_05000194 (__SILICON_REVISION__ < 5)
+/* Failing MMR Accesses When Stalled by Preceding Memory Read */
+#define ANOMALY_05000198 (__SILICON_REVISION__ < 5)
+/* Current DMA Address Shows Wrong Value During Carry Fix */
+#define ANOMALY_05000199 (__SILICON_REVISION__ < 5)
+/* SPORT TFS and DT Are Incorrectly Driven During Inactive Channels in Certain Conditions */
+#define ANOMALY_05000200 (__SILICON_REVISION__ < 5)
+/* Possible Infinite Stall with Specific Dual-DAG Situation */
+#define ANOMALY_05000202 (__SILICON_REVISION__ < 5)
+/* Incorrect data read with write-through cache and allocate cache lines on reads only mode */
+#define ANOMALY_05000204 (__SILICON_REVISION__ < 5)
+/* Specific sequence that can cause DMA error or DMA stopping */
+#define ANOMALY_05000205 (__SILICON_REVISION__ < 5)
+/* Recovery from "Brown-Out" Condition */
+#define ANOMALY_05000207 (__SILICON_REVISION__ < 5)
+/* VSTAT Status Bit in PLL_STAT Register Is Not Functional */
+#define ANOMALY_05000208 (1)
+/* Speed Path in Computational Unit Affects Certain Instructions */
+#define ANOMALY_05000209 (__SILICON_REVISION__ < 5)
+/* UART TX Interrupt Masked Erroneously */
+#define ANOMALY_05000215 (__SILICON_REVISION__ < 5)
+/* NMI Event at Boot Time Results in Unpredictable State */
+#define ANOMALY_05000219 (__SILICON_REVISION__ < 5)
+/* Data Corruption with Cached External Memory and Non-Cached On-Chip L2 Memory */
+#define ANOMALY_05000220 (__SILICON_REVISION__ < 5)
+/* Incorrect Pulse-Width of UART Start Bit */
+#define ANOMALY_05000225 (__SILICON_REVISION__ < 5)
+/* Scratchpad Memory Bank Reads May Return Incorrect Data */
+#define ANOMALY_05000227 (__SILICON_REVISION__ < 5)
+/* UART Receiver is Less Robust Against Baudrate Differences in Certain Conditions */
+#define ANOMALY_05000230 (__SILICON_REVISION__ < 5)
+/* UART STB Bit Incorrectly Affects Receiver Setting */
+#define ANOMALY_05000231 (__SILICON_REVISION__ < 5)
+/* SPORT data transmit lines are incorrectly driven in multichannel mode */
+#define ANOMALY_05000232 (__SILICON_REVISION__ < 5)
+/* DF Bit in PLL_CTL Register Does Not Respond to Hardware Reset */
+#define ANOMALY_05000242 (__SILICON_REVISION__ < 5)
+/* If I-Cache Is On, CSYNC/SSYNC/IDLE Around Change of Control Causes Failures */
+#define ANOMALY_05000244 (__SILICON_REVISION__ < 5)
+/* Spurious Hardware Error from an Access in the Shadow of a Conditional Branch */
+#define ANOMALY_05000245 (__SILICON_REVISION__ < 5)
+/* TESTSET operation forces stall on the other core */
+#define ANOMALY_05000248 (__SILICON_REVISION__ < 5)
+/* Incorrect Bit Shift of Data Word in Multichannel (TDM) Mode in Certain Conditions */
+#define ANOMALY_05000250 (__SILICON_REVISION__ > 2 && __SILICON_REVISION__ < 5)
+/* Exception Not Generated for MMR Accesses in Reserved Region */
+#define ANOMALY_05000251 (__SILICON_REVISION__ < 5)
+/* Maximum External Clock Speed for Timers */
+#define ANOMALY_05000253 (__SILICON_REVISION__ < 5)
+/* Incorrect Timer Pulse Width in Single-Shot PWM_OUT Mode with External Clock */
+#define ANOMALY_05000254 (__SILICON_REVISION__ > 3)
+/* Interrupt/Exception During Short Hardware Loop May Cause Bad Instruction Fetches */
+#define ANOMALY_05000257 (__SILICON_REVISION__ < 5)
+/* Instruction Cache Is Corrupted When Bits 9 and 12 of the ICPLB Data Registers Differ */
+#define ANOMALY_05000258 (__SILICON_REVISION__ < 5)
+/* ICPLB_STATUS MMR Register May Be Corrupted */
+#define ANOMALY_05000260 (__SILICON_REVISION__ < 5)
+/* DCPLB_FAULT_ADDR MMR Register May Be Corrupted */
+#define ANOMALY_05000261 (__SILICON_REVISION__ < 5)
+/* Stores To Data Cache May Be Lost */
+#define ANOMALY_05000262 (__SILICON_REVISION__ < 5)
+/* Hardware Loop Corrupted When Taking an ICPLB Exception */
+#define ANOMALY_05000263 (__SILICON_REVISION__ < 5)
+/* CSYNC/SSYNC/IDLE Causes Infinite Stall in Penultimate Instruction in Hardware Loop */
+#define ANOMALY_05000264 (__SILICON_REVISION__ < 5)
+/* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */
+#define ANOMALY_05000265 (__SILICON_REVISION__ < 5)
+/* IMDMA destination IRQ status must be read prior to using IMDMA */
+#define ANOMALY_05000266 (__SILICON_REVISION__ > 3)
+/* IMDMA may corrupt data under certain conditions */
+#define ANOMALY_05000267 (1)
+/* High I/O Activity Causes Output Voltage of Internal Voltage Regulator (Vddint) to Increase */
+#define ANOMALY_05000269 (1)
+/* High I/O Activity Causes Output Voltage of Internal Voltage Regulator (Vddint) to Decrease */
+#define ANOMALY_05000270 (1)
+/* Certain Data Cache Writethrough Modes Fail for Vddint <= 0.9V */
+#define ANOMALY_05000272 (1)
+/* Data cache write back to external synchronous memory may be lost */
+#define ANOMALY_05000274 (1)
+/* PPI Timing and Sampling Information Updates */
+#define ANOMALY_05000275 (__SILICON_REVISION__ > 2)
+/* Timing Requirements Change for External Frame Sync PPI Modes with Non-Zero PPI_DELAY */
+#define ANOMALY_05000276 (__SILICON_REVISION__ < 5)
+/* Disabling Peripherals with DMA Running May Cause DMA System Instability */
+#define ANOMALY_05000278 (__SILICON_REVISION__ < 5)
+/* False Hardware Error Exception When ISR Context Is Not Restored */
+#define ANOMALY_05000281 (__SILICON_REVISION__ < 5)
+/* System MMR Write Is Stalled Indefinitely When Killed in a Particular Stage */
+#define ANOMALY_05000283 (1)
+/* A read will receive incorrect data under certain conditions */
+#define ANOMALY_05000287 (__SILICON_REVISION__ < 5)
+/* SPORTs May Receive Bad Data If FIFOs Fill Up */
+#define ANOMALY_05000288 (__SILICON_REVISION__ < 5)
+/* Memory-To-Memory DMA Source/Destination Descriptors Must Be in Same Memory Space */
+#define ANOMALY_05000301 (1)
+/* SSYNCs After Writes To DMA MMR Registers May Not Be Handled Correctly */
+#define ANOMALY_05000302 (1)
+/* New Feature: Additional Hysteresis on SPORT Input Pins (Not Available On Older Silicon) */
+#define ANOMALY_05000305 (__SILICON_REVISION__ < 5)
+/* SCKELOW Bit Does Not Maintain State Through Hibernate */
+#define ANOMALY_05000307 (__SILICON_REVISION__ < 5)
+/* False Hardware Errors Caused by Fetches at the Boundary of Reserved Memory */
+#define ANOMALY_05000310 (1)
+/* Errors When SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted */
+#define ANOMALY_05000312 (1)
+/* PPI Is Level-Sensitive on First Transfer */
+#define ANOMALY_05000313 (1)
+/* Killed System MMR Write Completes Erroneously On Next System MMR Access */
+#define ANOMALY_05000315 (1)
+/* PF2 Output Remains Asserted After SPI Master Boot */
+#define ANOMALY_05000320 (__SILICON_REVISION__ > 3)
+/* Erroneous GPIO Flag Pin Operations Under Specific Sequences */
+#define ANOMALY_05000323 (1)
+/* SPORT Secondary Receive Channel Not Functional When Word Length Exceeds 16 Bits */
+#define ANOMALY_05000326 (__SILICON_REVISION__ > 3)
+/* New Feature: 24-Bit SPI Boot Mode Support (Not Available On Older Silicon) */
+#define ANOMALY_05000331 (__SILICON_REVISION__ < 5)
+/* New Feature: Slave SPI Boot Mode Supported (Not Available On Older Silicon) */
+#define ANOMALY_05000332 (__SILICON_REVISION__ < 5)
+/* Flag Data Register Writes One SCLK Cycle After Edge Is Detected May Clear Interrupt Status */
+#define ANOMALY_05000333 (__SILICON_REVISION__ < 5)
 
-#endif /*  (defined(CONFIG_BF_REV_0_5) || defined(CONFIG_BF_REV_0_3)) */
+/* Anomalies that don't exist on this proc */
+#define ANOMALY_05000158 (0)
+#define ANOMALY_05000183 (0)
+#define ANOMALY_05000273 (0)
+#define ANOMALY_05000311 (0)
 
-#if  (defined(CONFIG_BF_REV_0_5))
-#define ANOMALY_05000254 /* Incorrect Timer Pulse Width in Single-Shot PWM_OUT
-                            mode with external clock */
-#define ANOMALY_05000266 /* IMDMA destination IRQ status must be read prior to
-                            using IMDMA */
 #endif
-
-#if  (defined(CONFIG_BF_REV_0_3))
-#define ANOMALY_05000156 /* Timers in PWM-Out Mode with PPI GP Receive (Input)
-                            Mode with 0 Frame Syncs */
-#define ANOMALY_05000168 /* SDRAM auto-refresh and subsequent Power Ups */
-#define ANOMALY_05000169 /* DATA CPLB page miss can result in lost write-through
-                            cache data writes */
-#define ANOMALY_05000171 /* Boot-ROM code modifies SICA_IWRx wakeup registers */
-#define ANOMALY_05000174 /* Cache Fill Buffer Data lost */
-#define ANOMALY_05000175 /* Overlapping Sequencer and Memory Stalls */
-#define ANOMALY_05000176 /* Multiplication of (-1) by (-1) followed by an
-                            accumulator saturation */
-#define ANOMALY_05000179 /* PPI_COUNT cannot be programmed to 0 in General
-                            Purpose TX or RX modes */
-#define ANOMALY_05000181 /* Disabling the PPI resets the PPI configuration
-                            registers */
-#define ANOMALY_05000184 /* Timer Pin limitations for PPI TX Modes with
-                            External Frame Syncs */
-#define ANOMALY_05000185 /* PPI TX Mode with 2 External Frame Syncs */
-#define ANOMALY_05000186 /* PPI packing with Data Length greater than 8 bits
-                            (not a meaningful mode) */
-#define ANOMALY_05000188 /* IMDMA Restrictions on Descriptor and Buffer
-                            Placement in Memory */
-#define ANOMALY_05000189 /* False Protection Exception */
-#define ANOMALY_05000193 /* False Flag Pin Interrupts on Edge Sensitive Inputs
-                            when polarity setting is changed */
-#define ANOMALY_05000194 /* Restarting SPORT in specific modes may cause data
-                            corruption */
-#define ANOMALY_05000198 /* Failing MMR accesses when stalled by preceding
-                            memory read */
-#define ANOMALY_05000199 /* DMA current address shows wrong value during carry
-                            fix */
-#define ANOMALY_05000200 /* SPORT TFS and DT are incorrectly driven during
-                            inactive channels in certain conditions */
-#define ANOMALY_05000202 /* Possible infinite stall with specific dual-DAG
-                            situation */
-#define ANOMALY_05000204 /* Incorrect data read with write-through cache and
-                            allocate cache lines on reads only mode */
-#define ANOMALY_05000205 /* Specific sequence that can cause DMA error or DMA
-                            stopping */
-#define ANOMALY_05000207 /* Recovery from "brown-out" condition */
-#define ANOMALY_05000209 /* Speed-Path in computational unit affects certain
-                            instructions */
-#define ANOMALY_05000215 /* UART TX Interrupt masked erroneously */
-#define ANOMALY_05000219 /* NMI event at boot time results in unpredictable
-                            state */
-#define ANOMALY_05000220 /* Data Corruption with Cached External Memory and
-                            Non-Cached On-Chip L2 Memory */
-#define ANOMALY_05000225 /* Incorrect pulse-width of UART start-bit */
-#define ANOMALY_05000227 /* Scratchpad memory bank reads may return incorrect
-                            data */
-#define ANOMALY_05000230 /* UART Receiver is less robust against Baudrate
-                            Differences in certain Conditions */
-#define ANOMALY_05000231 /* UART STB bit incorrectly affects receiver setting */
-#define ANOMALY_05000232 /* SPORT data transmit lines are incorrectly driven in
-                            multichannel mode */
-#define ANOMALY_05000242 /* DF bit in PLL_CTL register does not respond to
-                            hardware reset */
-#define ANOMALY_05000244 /* If i-cache is on, CSYNC/SSYNC/IDLE around Change of
-                            Control causes failures */
-#define ANOMALY_05000248 /* TESTSET operation forces stall on the other core */
-#define ANOMALY_05000250 /* Incorrect Bit-Shift of Data Word in Multichannel
-                            (TDM) mode in certain conditions */
-#define ANOMALY_05000251 /* Exception not generated for MMR accesses in
-                            reserved region */
-#define ANOMALY_05000253 /* Maximum external clock speed for Timers */
-#define ANOMALY_05000258 /* Instruction Cache is corrupted when bits 9 and 12
-                            of the ICPLB Data registers differ */
-#define ANOMALY_05000260 /* ICPLB_STATUS MMR register may be corrupted */
-#define ANOMALY_05000261 /* DCPLB_FAULT_ADDR MMR register may be corrupted */
-#define ANOMALY_05000262 /* Stores to data cache may be lost */
-#define ANOMALY_05000263 /* Hardware loop corrupted when taking an ICPLB
-                            exception */
-#define ANOMALY_05000264 /* CSYNC/SSYNC/IDLE causes infinite stall in second
-                            to last instruction in hardware loop */
-#define ANOMALY_05000276 /* Timing requirements change for External Frame
-                            Sync PPI Modes with non-zero PPI_DELAY */
-#define ANOMALY_05000278 /* Disabling Peripherals with DMA running may cause
-                            DMA system instability */
-#define ANOMALY_05000281 /* False Hardware Error Exception when ISR context is
-                            not restored */
-#define ANOMALY_05000283 /* An MMR write is stalled indefinitely when killed
-                            in a particular stage */
-#define ANOMALY_05000287 /* A read will receive incorrect data under certain
-                            conditions */
-#define ANOMALY_05000288 /* SPORTs may receive bad data if FIFOs fill up */
-#endif
-
-#endif /* _MACH_ANOMALY_H_ */
index 96a5d3a47e4525084108a042dfb1ebd6e157a4f1..17e1d5dcef028ba85662e000a1c0a79ff65398d8 100644 (file)
  */
 
 
-#define BLKFIN_ISUBBANKS       4
-#define BLKFIN_IWAYS           4
-#define BLKFIN_ILINES          32
+#define BFIN_ISUBBANKS 4
+#define BFIN_IWAYS             4
+#define BFIN_ILINES            32
 
-#define BLKFIN_DSUBBANKS       4
-#define BLKFIN_DWAYS           2
-#define BLKFIN_DLINES          64
+#define BFIN_DSUBBANKS 4
+#define BFIN_DWAYS             2
+#define BFIN_DLINES            64
 
 #define WAY0_L                 0x1
 #define WAY1_L                 0x2
 
 #define AMGCTLVAL      (V_AMBEN | V_AMCKEN | V_CDPRIO | V_B0PEN | V_B1PEN | V_B2PEN | V_B3PEN | 0x0002)
 
-#define MAX_VC 600000000
-#define MIN_VC 50000000
-
-/******************************* PLL Settings ********************************/
-#ifdef CONFIG_BFIN_KERNEL_CLOCK
-#if (CONFIG_VCO_MULT < 0)
-#error "VCO Multiplier is less than 0. Please select a different value"
-#endif
-
-#if (CONFIG_VCO_MULT == 0)
-#error "VCO Multiplier should be greater than 0. Please select a different value"
-#endif
-
-#ifndef CONFIG_CLKIN_HALF
-#define CONFIG_VCO_HZ  (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)
-#else
-#define CONFIG_VCO_HZ  ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2)
-#endif
-
-#ifndef CONFIG_PLL_BYPASS
-#define CONFIG_CCLK_HZ (CONFIG_VCO_HZ/CONFIG_CCLK_DIV)
-#define CONFIG_SCLK_HZ (CONFIG_VCO_HZ/CONFIG_SCLK_DIV)
-#else
-#define CONFIG_CCLK_HZ CONFIG_CLKIN_HZ
-#define CONFIG_SCLK_HZ CONFIG_CLKIN_HZ
-#endif
-
-#if (CONFIG_SCLK_DIV < 1)
-#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
-#endif
-
-#if (CONFIG_SCLK_DIV > 15)
-#error "SCLK DIV cannot be less than 1 or more than 15. Please select a proper value"
-#endif
-
-#if (CONFIG_CCLK_DIV != 1)
-#if (CONFIG_CCLK_DIV != 2)
-#if (CONFIG_CCLK_DIV != 4)
-#if (CONFIG_CCLK_DIV != 8)
-#error "CCLK DIV can be 1,2,4 or 8 only. Please select a proper value"
-#endif
-#endif
-#endif
-#endif
-
-#if (CONFIG_VCO_HZ > MAX_VC)
-#error "VCO selected is more than maximum value. Please change the VCO multipler"
-#endif
-
-#if (CONFIG_SCLK_HZ > 133000000)
-#error "Sclk value selected is more than maximum. Please select a proper value for SCLK multiplier"
-#endif
-
-#if (CONFIG_SCLK_HZ < 27000000)
-#error "Sclk value selected is less than minimum. Please select a proper value for SCLK multiplier"
-#endif
-
-#if (CONFIG_SCLK_HZ >= CONFIG_CCLK_HZ)
-#if (CONFIG_SCLK_HZ != CONFIG_CLKIN_HZ)
-#if (CONFIG_CCLK_HZ != CONFIG_CLKIN_HZ)
-#error "Please select sclk less than cclk"
-#endif
-#endif
-#endif
-
-#if (CONFIG_CCLK_DIV == 1)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV1
-#endif
-#if (CONFIG_CCLK_DIV == 2)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV2
-#endif
-#if (CONFIG_CCLK_DIV == 4)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV4
-#endif
-#if (CONFIG_CCLK_DIV == 8)
-#define CONFIG_CCLK_ACT_DIV   CCLK_DIV8
-#endif
-#ifndef CONFIG_CCLK_ACT_DIV
-#define CONFIG_CCLK_ACT_DIV   CONFIG_CCLK_DIV_not_defined_properly
-#endif
-
-#if defined(ANOMALY_05000273) && (CONFIG_CCLK_DIV == 1)
-#error ANOMALY 05000273, please make sure CCLK is at least 2x SCLK
-#endif
-
-#endif                         /* CONFIG_BFIN_KERNEL_CLOCK */
-
 #ifdef CONFIG_BF561
 #define CPU "BF561"
 #define CPUID 0x027bb000
 #define CPUID 0x0
 #endif
 
-#if (CONFIG_MEM_SIZE % 4)
-#error "SDRAM memory size must be a multiple of 4MB!"
-#endif
-#define SDRAM_IGENERIC    (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
-#define SDRAM_IKERNEL     (SDRAM_IGENERIC | CPLB_LOCK)
-#define L1_IMEMORY        (               CPLB_USER_RD | CPLB_VALID | CPLB_LOCK)
-#define SDRAM_INON_CHBL   (               CPLB_USER_RD | CPLB_VALID)
-
-/*Use the menuconfig cache policy here - CONFIG_BLKFIN_WT/CONFIG_BLKFIN_WB*/
-
-#define ANOMALY_05000158_WORKAROUND            0x200
-#ifdef CONFIG_BLKFIN_WB                /*Write Back Policy */
-#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_DIRTY \
-                       | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
-#else                          /*Write Through */
-#define SDRAM_DGENERIC   (CPLB_L1_CHBL | CPLB_WT | CPLB_L1_AOW | CPLB_DIRTY \
-                       | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)
-#endif
-
-
-#define L1_DMEMORY       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
-#define SDRAM_DNON_CHBL  (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)
-#define SDRAM_EBIU       (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)
-#define SDRAM_OOPS      (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
-
-#define L2_MEMORY      (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)
-
-#define SIZE_1K 0x00000400     /* 1K */
-#define SIZE_4K 0x00001000     /* 4K */
-#define SIZE_1M 0x00100000     /* 1M */
-#define SIZE_4M 0x00400000     /* 4M */
-
-#define MAX_CPLBS (16 * 2)
-
-/*
-* Number of required data CPLB switchtable entries
-* MEMSIZE / 4 (we mostly install 4M page size CPLBs
-* approx 16 for smaller 1MB page size CPLBs for allignment purposes
-* 1 for L1 Data Memory
-* 1 for L2 Data Memory
-* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
-* 64 for ASYNC Memory
-*/
-
-
-#define MAX_SWITCH_D_CPLBS (((CONFIG_MEM_SIZE / 4) + 16 + 1 + 1 + 1 + 64) * 2)
-
-/*
-* Number of required instruction CPLB switchtable entries
-* MEMSIZE / 4 (we mostly install 4M page size CPLBs
-* approx 12 for smaller 1MB page size CPLBs for allignment purposes
-* 1 for L1 Instruction Memory
-* 1 for L2 Instruction Memory
-* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
-*/
-
-#define MAX_SWITCH_I_CPLBS (((CONFIG_MEM_SIZE / 4) + 12 + 1 + 1 + 1) * 2)
-
-#if 0                          /* comment by mhfan */
-/* Event Vector Table Address */
-#define EVT_EMULATION_ADDR      0xffe02000
-#define EVT_RESET_ADDR          0xffe02004
-#define EVT_NMI_ADDR            0xffe02008
-#define EVT_EXCEPTION_ADDR      0xffe0200c
-#define EVT_GLOBAL_INT_ENB_ADDR 0xffe02010
-#define EVT_HARDWARE_ERROR_ADDR 0xffe02014
-#define EVT_TIMER_ADDR          0xffe02018
-#define EVT_IVG7_ADDR           0xffe0201c
-#define EVT_IVG8_ADDR           0xffe02020
-#define EVT_IVG9_ADDR           0xffe02024
-#define EVT_IVG10_ADDR          0xffe02028
-#define EVT_IVG11_ADDR          0xffe0202c
-#define EVT_IVG12_ADDR          0xffe02030
-#define EVT_IVG13_ADDR          0xffe02034
-#define EVT_IVG14_ADDR          0xffe02038
-#define EVT_IVG15_ADDR          0xffe0203c
-#define EVT_OVERRIDE_ADDR       0xffe02100
-#endif                         /* comment by mhfan */
-
 #endif                         /* __MACH_BF561_H__  */
index 2537c845e8b089691e77da6f9bf245f51a7d0506..562aee39895cdca6437490083c3ab6b9efbd9136 100644 (file)
@@ -38,7 +38,7 @@
 #include "defBF561.h"
 #include "anomaly.h"
 
-#if !(defined(__ASSEMBLY__) || defined(ASSEMBLY))
+#if !defined(__ASSEMBLY__)
 #include "cdefBF561.h"
 #endif
 
index 73d4d65249cdc41c23eee21c9a500d52c7a3feee..d667816486c095cfe162b143e4c7ff68449a5a21 100644 (file)
 #ifndef _CDEF_BF561_H
 #define _CDEF_BF561_H
 
-/*
-#if !defined(__ADSPBF561__)
-#warning cdefBF561.h should only be included for BF561 chip.
-#endif
-*/
+#include <asm/blackfin.h>
+
 /* include all Core registers and bit definitions */
 #include "defBF561.h"
 
@@ -67,7 +64,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        bfin_write32(SICA_IWR1, 0);
 
        bfin_write16(VR_CTL, val);
-       __builtin_bfin_ssync();
+       SSYNC();
 
        local_irq_save(flags);
        asm("IDLE;");
index 0f2dc6e6335b60b108eedbeeed11b8c6a7d495b7..bf7dc4e00065d2023c2133c8f018c1a3f960e02c 100644 (file)
 #define UART_GCTL                      0xFFC00424      /* Global Control Register */
 
 /* SPI Controller (0xFFC00500 - 0xFFC005FF) */
+#define SPI0_REGBASE                   0xFFC00500
 #define SPI_CTL                        0xFFC00500      /* SPI Control Register */
 #define SPI_FLG                        0xFFC00504      /* SPI Flag register */
 #define SPI_STAT                       0xFFC00508      /* SPI Status register */
index a753ce720d74a935ee135228e863f099b04d984c..12789927db3d976ec7e807a6416d23d477841244 100644 (file)
 #define IRQ_PF46               119
 #define IRQ_PF47               120
 
+#define GPIO_IRQ_BASE          IRQ_PF0
+
 #ifdef CONFIG_IRQCHIP_DEMUX_GPIO
 #define NR_IRQS                        (IRQ_PF47 + 1)
 #else
index ebac9a8d838d6b55ab78f884f535998d11f42893..f7ac09cf2c3d3be80a8d532f6face2d2ac64e171 100644 (file)
 
 /* Level 1 Memory */
 
-#ifdef CONFIG_BLKFIN_CACHE
-#define BLKFIN_ICACHESIZE      (16*1024)
+#ifdef CONFIG_BFIN_ICACHE
+#define BFIN_ICACHESIZE        (16*1024)
 #else
-#define BLKFIN_ICACHESIZE      (0*1024)
+#define BFIN_ICACHESIZE        (0*1024)
 #endif
 
 /* Memory Map for ADSP-BF561 processors */
 
 #define L1_CODE_LENGTH      0x4000
 
-#ifdef CONFIG_BLKFIN_DCACHE
+#ifdef CONFIG_BFIN_DCACHE
 
-#ifdef CONFIG_BLKFIN_DCACHE_BANKA
+#ifdef CONFIG_BFIN_DCACHE_BANKA
 #define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
 #define L1_DATA_B_LENGTH      0x8000
-#define BLKFIN_DCACHESIZE      (16*1024)
-#define BLKFIN_DSUPBANKS       1
+#define BFIN_DCACHESIZE        (16*1024)
+#define BFIN_DSUPBANKS 1
 #else
 #define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      (0x8000 - 0x4000)
 #define L1_DATA_B_LENGTH      (0x8000 - 0x4000)
-#define BLKFIN_DCACHESIZE      (32*1024)
-#define BLKFIN_DSUPBANKS       2
+#define BFIN_DCACHESIZE        (32*1024)
+#define BFIN_DSUPBANKS 2
 #endif
 
 #else
 #define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
 #define L1_DATA_A_LENGTH      0x8000
 #define L1_DATA_B_LENGTH      0x8000
-#define BLKFIN_DCACHESIZE      (0*1024)
-#define BLKFIN_DSUPBANKS       0
-#endif /*CONFIG_BLKFIN_DCACHE*/
+#define BFIN_DCACHESIZE        (0*1024)
+#define BFIN_DSUPBANKS 0
+#endif /*CONFIG_BFIN_DCACHE*/
 #endif
 
 /* Level 2 Memory */
index 10d11d5ffe23c51d0a749fafcfa6d3b38cd5db00..132ad31665e3337af2612a7746f47fd21abfe349 100644 (file)
@@ -81,7 +81,7 @@
 #define P_TMR1         (P_DEFINED | P_IDENT(GPIO_PF1))
 #define P_TMR0         (P_DEFINED | P_IDENT(GPIO_PF0))
 #define P_SPI0_MOSI    (P_DONTCARE)
-#define P_SPI0_MIS0    (P_DONTCARE)
+#define P_SPI0_MISO    (P_DONTCARE)
 #define P_SPI0_SCK     (P_DONTCARE)
 
 #endif /* _MACH_PORTMUX_H_ */
index 94ed381e560671b74374584b5d6459b4f8d0c426..ede210eca4ec1f6c202601dd77a94abfa52b432f 100644 (file)
@@ -39,7 +39,7 @@
 #define bfin_read_SRAM_BASE_ADDRESS()        bfin_read32(SRAM_BASE_ADDRESS)
 #define bfin_write_SRAM_BASE_ADDRESS(val)    bfin_write32(SRAM_BASE_ADDRESS,val)
 #define bfin_read_DMEM_CONTROL()             bfin_read32(DMEM_CONTROL)
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
 extern void bfin_write_DMEM_CONTROL(unsigned int val);
 #else
 #define bfin_write_DMEM_CONTROL(val)         bfin_write32(DMEM_CONTROL,val)
@@ -129,7 +129,7 @@ extern void bfin_write_DMEM_CONTROL(unsigned int val);
 #define DTEST_DATA3            0xFFE0040C
 */
 #define bfin_read_IMEM_CONTROL()             bfin_read32(IMEM_CONTROL)
-#ifdef ANOMALY_05000125
+#if ANOMALY_05000125
 extern void bfin_write_IMEM_CONTROL(unsigned int val);
 #else
 #define bfin_write_IMEM_CONTROL(val)         bfin_write32(IMEM_CONTROL,val)
diff --git a/include/asm-blackfin/mach-common/clocks.h b/include/asm-blackfin/mach-common/clocks.h
new file mode 100644 (file)
index 0000000..033bba9
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * File:         include/asm-blackfin/mach-common/clocks.h
+ * Based on:     include/asm-blackfin/mach-bf537/bf537.h
+ * Author:      Robin Getz <rgetz@blackfin.uclinux.org>
+ *
+ * Created:      25Jul07
+ * Description:  Common Clock definitions for various kernel files
+ *
+ * Modified:
+ *               Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _BFIN_CLOCKS_H
+#define _BFIN_CLOCKS_H
+
+#ifdef CONFIG_CCLK_DIV_1
+# define CONFIG_CCLK_ACT_DIV   CCLK_DIV1
+# define CONFIG_CCLK_DIV 1
+#endif
+
+#ifdef CONFIG_CCLK_DIV_2
+# define CONFIG_CCLK_ACT_DIV   CCLK_DIV2
+# define CONFIG_CCLK_DIV 2
+#endif
+
+#ifdef CONFIG_CCLK_DIV_4
+# define CONFIG_CCLK_ACT_DIV   CCLK_DIV4
+# define CONFIG_CCLK_DIV 4
+#endif
+
+#ifdef CONFIG_CCLK_DIV_8
+# define CONFIG_CCLK_ACT_DIV   CCLK_DIV8
+# define CONFIG_CCLK_DIV 8
+#endif
+
+#ifndef CONFIG_PLL_BYPASS
+# ifndef CONFIG_CLKIN_HALF
+#  define CONFIG_VCO_HZ   (CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)
+# else
+#  define CONFIG_VCO_HZ   ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT)/2)
+# endif
+
+# define CONFIG_CCLK_HZ  (CONFIG_VCO_HZ/CONFIG_CCLK_DIV)
+# define CONFIG_SCLK_HZ  (CONFIG_VCO_HZ/CONFIG_SCLK_DIV)
+
+#else
+# define CONFIG_VCO_HZ   (CONFIG_CLKIN_HZ)
+# define CONFIG_CCLK_HZ  (CONFIG_CLKIN_HZ)
+# define CONFIG_SCLK_HZ  (CONFIG_CLKIN_HZ)
+# define CONFIG_VCO_MULT 0
+#endif
+
+#endif
index be1ece8c0c2775c277023ad74c88067054ee830e..c1d8c4a78fcfc7a4a7e8e7b840ce30e856d139bd 100644 (file)
 
 #include <asm/mach/anomaly.h>
 
-/*#if !defined(__ADSPLPBLACKFIN__)
-#warning def_LPBlackfin.h should only be included for 532 compatible chips.
-#endif
-*/
-
 #define MK_BMSK_(x) (1<<x)
 
-#if defined(ANOMALY_05000198)
-
-#define bfin_read8(addr) ({ unsigned char __v; \
-               __asm__ __volatile__ ("NOP;\n\t" \
-                       "%0 = b[%1] (z);\n\t" \
-                       : "=d"(__v) : "a"(addr)); \
-               __v; })
-
-#define bfin_read16(addr) ({ unsigned __v; \
-                       __asm__ __volatile__ ("NOP;\n\t"\
-                                                               "%0 = w[%1] (z);\n\t"\
-  : "=d"(__v) : "a"(addr)); (unsigned short)__v; })
-
-#define bfin_read32(addr) ({ unsigned __v; \
-                      __asm__ __volatile__ ("NOP;\n\t"\
-                                            "%0 = [%1];\n\t"\
-  : "=d"(__v) : "a"(addr)); __v; })
-
-#define bfin_write8(addr, val) ({ \
-               __asm__ __volatile__ ("NOP;\n\t" \
-                       "b[%0] = %1;\n\t" \
-                       : : "a"(addr), "d"(val) : "memory");})
+#ifndef __ASSEMBLY__
 
-#define bfin_write16(addr,val) ({\
-                      __asm__ __volatile__ ("NOP;\n\t"\
-                                            "w[%0] = %1;\n\t"\
-  : : "a"(addr) , "d"(val) : "memory");})
-
-#define bfin_write32(addr,val) ({\
-                      __asm__ __volatile__ ("NOP;\n\t"\
-                                            "[%0] = %1;\n\t"\
-  : : "a"(addr) , "d"(val) : "memory");})
+#include <linux/types.h>
 
+#if ANOMALY_05000198
+# define NOP_PAD_ANOMALY_05000198 "nop;"
 #else
-
-#define bfin_read8(addr) ({ unsigned char __v; \
-               __asm__ __volatile__ ( \
-                       "%0 = b[%1] (z);\n\t" \
-                       :"=d"(__v) : "a"(addr)); \
-               __v; })
-
-#define bfin_read16(addr) ({ unsigned __v; \
-                       __asm__ __volatile__ (\
-                                                               "%0 = w[%1] (z);\n\t"\
-  : "=d"(__v) : "a"(addr)); (unsigned short)__v; })
-
-#define bfin_read32(addr) ({ unsigned __v; \
-                      __asm__ __volatile__ (\
-                                            "%0 = [%1];\n\t"\
-  : "=d"(__v) : "a"(addr)); __v; })
-
-#define bfin_write8(addr, val) ({ \
-               __asm__ __volatile__ ( \
-                       "b[%0] = %1; \n\t" \
-                       ::"a"(addr), "d"(val) : "memory");})
-
-#define bfin_write16(addr,val) ({\
-                      __asm__ __volatile__ (\
-                                            "w[%0] = %1;\n\t"\
-  : : "a"(addr) , "d"(val) : "memory");})
-
-#define bfin_write32(addr,val) ({\
-                      __asm__ __volatile__ (\
-                                            "[%0] = %1;\n\t"\
-  : : "a"(addr) , "d"(val) : "memory");})
-
+# define NOP_PAD_ANOMALY_05000198
 #endif
 
+#define bfin_read8(addr) ({ \
+       uint8_t __v; \
+       __asm__ __volatile__( \
+               NOP_PAD_ANOMALY_05000198 \
+               "%0 = b[%1] (z);" \
+               : "=d" (__v) \
+               : "a" (addr) \
+       ); \
+       __v; })
+
+#define bfin_read16(addr) ({ \
+       uint16_t __v; \
+       __asm__ __volatile__( \
+               NOP_PAD_ANOMALY_05000198 \
+               "%0 = w[%1] (z);" \
+               : "=d" (__v) \
+               : "a" (addr) \
+       ); \
+       __v; })
+
+#define bfin_read32(addr) ({ \
+       uint32_t __v; \
+       __asm__ __volatile__( \
+               NOP_PAD_ANOMALY_05000198 \
+               "%0 = [%1];" \
+               : "=d" (__v) \
+               : "a" (addr) \
+       ); \
+       __v; })
+
+#define bfin_write8(addr, val) \
+       __asm__ __volatile__( \
+               NOP_PAD_ANOMALY_05000198 \
+               "b[%0] = %1;" \
+               : \
+               : "a" (addr), "d" (val) \
+               : "memory" \
+       )
+
+#define bfin_write16(addr, val) \
+       __asm__ __volatile__( \
+               NOP_PAD_ANOMALY_05000198 \
+               "w[%0] = %1;" \
+               : \
+               : "a" (addr), "d" (val) \
+               : "memory" \
+       )
+
+#define bfin_write32(addr, val) \
+       __asm__ __volatile__( \
+               NOP_PAD_ANOMALY_05000198 \
+               "[%0] = %1;" \
+               : \
+               : "a" (addr), "d" (val) \
+               : "memory" \
+       )
+
+#endif /* __ASSEMBLY__ */
+
 /**************************************************
  * System Register Bits
  **************************************************/
 #define CPLB_USER_RD       0x00000004  /* 0=no read access, 1=read access
                                         * allowed (user mode)
                                         */
+
 #define PAGE_SIZE_1KB      0x00000000  /* 1 KB page size */
 #define PAGE_SIZE_4KB      0x00010000  /* 4 KB page size */
 #define PAGE_SIZE_1MB      0x00020000  /* 1 MB page size */
                                         */
 #define CPLB_WT            0x00004000  /* 0=write-back, 1=write-through */
 
+#define CPLB_ALL_ACCESS CPLB_SUPV_WR | CPLB_USER_RD | CPLB_USER_WR
+
 /* TBUFCTL Masks */
 #define TBUFPWR            0x0001
 #define TBUFEN             0x0002
index 5a8f9e431c40c2154bca75e837d5c896bd761541..b11b114689c06be7f260ae9d1489a7c1c3d26da6 100644 (file)
@@ -4,7 +4,7 @@
 #include <asm-generic/4level-fixup.h>
 
 #include <asm/page.h>
-#include <asm/cplb.h>
+#include <asm/mach-common/def_LPBlackfin.h>
 
 typedef pte_t *pte_addr_t;
 /*
diff --git a/include/asm-blackfin/reboot.h b/include/asm-blackfin/reboot.h
new file mode 100644 (file)
index 0000000..6d448b5
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * include/asm-blackfin/reboot.h - shutdown/reboot header
+ *
+ * Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __ASM_REBOOT_H__
+#define __ASM_REBOOT_H__
+
+/* optional board specific hooks */
+extern void native_machine_restart(char *cmd);
+extern void native_machine_halt(void);
+extern void native_machine_power_off(void);
+
+/* common reboot workarounds */
+extern void bfin_gpio_reset_spi0_ssel1(void);
+
+#endif
index 5e5f1a0566c0fe6b1c90d9d0d0b039ed23c289e8..2b3d47d0bbb692f62d9242adba7adec523cc0723 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <linux/linkage.h>
 #include <linux/compiler.h>
+#include <asm/mach/anomaly.h>
 
 /*
  * Interrupt configuring macros.
 
 extern unsigned long irq_flags;
 
-#define local_irq_enable() do {                \
-       __asm__ __volatile__ (          \
-               "sti %0;"               \
-               ::"d"(irq_flags));      \
-} while (0)
+#define local_irq_enable() \
+       __asm__ __volatile__( \
+               "sti %0;" \
+               : \
+               : "d" (irq_flags) \
+       )
 
-#define local_irq_disable() do {       \
-       int _tmp_dummy;                 \
-       __asm__ __volatile__ (          \
-               "cli %0;"               \
-               :"=d" (_tmp_dummy):);   \
-} while (0)
+#define local_irq_disable() \
+       do { \
+               int __tmp_dummy; \
+               __asm__ __volatile__( \
+                       "cli %0;" \
+                       : "=d" (__tmp_dummy) \
+               ); \
+       } while (0)
 
-#if defined(ANOMALY_05000244) && defined (CONFIG_BLKFIN_CACHE)
-#define idle_with_irq_disabled() do {   \
-        __asm__ __volatile__ (          \
-                "nop; nop;\n"           \
-                ".align 8;\n"           \
-                "sti %0; idle;\n"       \
-                ::"d" (irq_flags));     \
-} while (0)
+#if ANOMALY_05000244 && defined(CONFIG_BFIN_ICACHE)
+# define NOP_PAD_ANOMALY_05000244 "nop; nop;"
 #else
-#define idle_with_irq_disabled() do {   \
-       __asm__ __volatile__ (          \
-               ".align 8;\n"           \
-               "sti %0; idle;\n"       \
-               ::"d" (irq_flags));     \
-} while (0)
+# define NOP_PAD_ANOMALY_05000244
 #endif
 
+#define idle_with_irq_disabled() \
+       __asm__ __volatile__( \
+               NOP_PAD_ANOMALY_05000244 \
+               ".align 8;" \
+               "sti %0;" \
+               "idle;" \
+               : \
+               : "d" (irq_flags) \
+       )
+
 #ifdef CONFIG_DEBUG_HWERR
-#define __save_and_cli(x) do {                 \
-       __asm__ __volatile__ (                  \
-               "cli %0;\n\tsti %1;"            \
-               :"=&d"(x): "d" (0x3F));         \
-} while (0)
+# define __save_and_cli(x) \
+       __asm__ __volatile__( \
+               "cli %0;" \
+               "sti %1;" \
+               : "=&d" (x) \
+               : "d" (0x3F) \
+       )
 #else
-#define __save_and_cli(x) do {         \
-       __asm__ __volatile__ (          \
-               "cli %0;"               \
-               :"=&d"(x):);            \
-} while (0)
+# define __save_and_cli(x) \
+       __asm__ __volatile__( \
+               "cli %0;" \
+               : "=&d" (x) \
+       )
 #endif
 
-#define local_save_flags(x) asm volatile ("cli %0;"     \
-                                         "sti %0;"     \
-                                         :"=d"(x):);
+#define local_save_flags(x) \
+       __asm__ __volatile__( \
+               "cli %0;" \
+               "sti %0;" \
+               : "=d" (x) \
+       )
 
 #ifdef CONFIG_DEBUG_HWERR
 #define irqs_enabled_from_flags(x) (((x) & ~0x3f) != 0)
@@ -97,10 +105,11 @@ extern unsigned long irq_flags;
 #define irqs_enabled_from_flags(x) ((x) != 0x1f)
 #endif
 
-#define local_irq_restore(x) do {                      \
-       if (irqs_enabled_from_flags(x))                 \
-               local_irq_enable ();                    \
-} while (0)
+#define local_irq_restore(x) \
+       do { \
+               if (irqs_enabled_from_flags(x)) \
+                       local_irq_enable(); \
+       } while (0)
 
 /* For spinlocks etc */
 #define local_irq_save(x) __save_and_cli(x)
index 4eac38de8ce173f94c94a1215c95727f17017c1d..f37feb7cf89520f7c75ad5facc26c20184a7b60f 100644 (file)
@@ -140,6 +140,7 @@ struct ktermios {
 #define HUPCL  0002000
 #define CLOCAL 0004000
 #define CBAUDEX 0010000
+#define BOTHER 0010000
 #define    B57600 0010001
 #define   B115200 0010002
 #define   B230400 0010003
@@ -155,10 +156,12 @@ struct ktermios {
 #define  B3000000 0010015
 #define  B3500000 0010016
 #define  B4000000 0010017
-#define CIBAUD   002003600000  /* input baud rate (not used) */
+#define CIBAUD   002003600000  /* input baud rate */
 #define CMSPAR   010000000000  /* mark or space (stick) parity */
 #define CRTSCTS          020000000000  /* flow control */
 
+#define IBSHIFT        16      /* Shift from CBAUD to CIBAUD */
+
 /* c_lflag bits */
 #define ISIG   0000001
 #define ICANON 0000002
index 5c41478a51c6c31c7de86c7111ec5df5fbb99aea..e31fe859650b64c0261de13366cfc329dcdf05c3 100644 (file)
@@ -98,8 +98,14 @@ struct termio {
        copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
 })
 
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+#define user_termios_to_kernel_termios(k, u) \
+       copy_from_user(k, u, sizeof(struct termios2))
+#define kernel_termios_to_user_termios(u, k) \
+       copy_to_user(u, k, sizeof(struct termios2))
+#define user_termios_to_kernel_termios_1(k, u) \
+       copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios_1(u, k) \
+       copy_to_user(u, k, sizeof(struct termios))
 
 #endif                         /* __KERNEL__ */
 
index 9c2474c9a589694adb54a9b5726fc92f4bf6497d..6313aace9d5915991aa55c438fa45914a561e809 100644 (file)
@@ -6,23 +6,46 @@
 #ifndef _BLACKFIN_TRACE_
 #define _BLACKFIN_TRACE_
 
+/* Normally, we use ON, but you can't turn on software expansion until
+ * interrupts subsystem is ready
+ */
+
+#define BFIN_TRACE_INIT ((CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION << 4) | 0x03)
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
+#define BFIN_TRACE_ON   (BFIN_TRACE_INIT | (CONFIG_DEBUG_BFIN_HWTRACE_EXPAND << 2))
+#else
+#define BFIN_TRACE_ON   (BFIN_TRACE_INIT)
+#endif
+
 #ifndef __ASSEMBLY__
+extern unsigned long trace_buff_offset;
+extern unsigned long software_trace_buff[];
+
 /* Trace Macros for C files */
 
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
+
 #define trace_buffer_save(x) \
-        do { \
-                (x) = bfin_read_TBUFCTL(); \
-                bfin_write_TBUFCTL((x) & ~TBUFEN); \
-        } while (0)
+       do { \
+               (x) = bfin_read_TBUFCTL(); \
+               bfin_write_TBUFCTL((x) & ~TBUFEN); \
+       } while (0)
 
 #define trace_buffer_restore(x) \
-        do { \
-                bfin_write_TBUFCTL((x));        \
-        } while (0)
+       do { \
+               bfin_write_TBUFCTL((x));        \
+       } while (0)
+#else /* DEBUG_BFIN_HWTRACE_ON */
+
+#define trace_buffer_save(x)
+#define trace_buffer_restore(x)
+#endif /* CONFIG_DEBUG_BFIN_HWTRACE_ON */
 
 #else
 /* Trace Macros for Assembly files */
 
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
+
 #define TRACE_BUFFER_START(preg, dreg) trace_buffer_start(preg, dreg)
 #define TRACE_BUFFER_STOP(preg, dreg)  trace_buffer_stop(preg, dreg)
 
        dreg = 0x1;                     \
        [preg] = dreg;
 
-#define trace_buffer_start(preg, dreg) \
+#define trace_buffer_start(preg, dreg) \
        preg.L = LO(TBUFCTL);           \
        preg.H = HI(TBUFCTL);           \
-       dreg = 0x13;                    \
+       dreg = BFIN_TRACE_ON;           \
+       [preg] = dreg;
+
+#define trace_buffer_init(preg, dreg) \
+       preg.L = LO(TBUFCTL);         \
+       preg.H = HI(TBUFCTL);         \
+       dreg = BFIN_TRACE_INIT;       \
        [preg] = dreg;
 
+#else /* CONFIG_DEBUG_BFIN_HWTRACE_ON */
+
+#define trace_buffer_stop(preg, dreg)
+#define trace_buffer_start(preg, dreg)
+#define trace_buffer_init(preg, dreg)
+
+#endif /* CONFIG_DEBUG_BFIN_HWTRACE_ON */
+
 #ifdef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE
 # define DEBUG_START_HWTRACE(preg, dreg) trace_buffer_start(preg, dreg)
 # define DEBUG_STOP_HWTRACE(preg, dreg) trace_buffer_stop(preg, dreg)
diff --git a/include/asm-i386/Kbuild b/include/asm-i386/Kbuild
deleted file mode 100644 (file)
index cbf6e8f..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-include include/asm-generic/Kbuild.asm
-
-header-y += boot.h
-header-y += debugreg.h
-header-y += ldt.h
-header-y += msr-index.h
-header-y += ptrace-abi.h
-header-y += ucontext.h
-
-unifdef-y += msr.h
-unifdef-y += mtrr.h
-unifdef-y += vm86.h
diff --git a/include/asm-i386/k8.h b/include/asm-i386/k8.h
deleted file mode 100644 (file)
index dfd88a6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-x86_64/k8.h>
diff --git a/include/asm-i386/pci-direct.h b/include/asm-i386/pci-direct.h
deleted file mode 100644 (file)
index 4f6738b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "asm-x86_64/pci-direct.h"
diff --git a/include/asm-i386/stacktrace.h b/include/asm-i386/stacktrace.h
deleted file mode 100644 (file)
index 7d1f6a5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-x86_64/stacktrace.h>
index 0ec78f66cea409c2e256a3be1172aa5f18312970..e245f2a3cd78ed86c51f9061aa9c881da6049182 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * MPC1211 uses PC/AT style RTC definitions.
  */
-#include <asm-i386/mc146818rtc.h>
+#include <asm-x86/mc146818rtc_32.h>
 
 
diff --git a/include/asm-x86/8253pit.h b/include/asm-x86/8253pit.h
new file mode 100644 (file)
index 0000000..d3c2b38
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "8253pit_32.h"
+#else
+# include "8253pit_64.h"
+#endif
diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild
new file mode 100644 (file)
index 0000000..c5e43cb
--- /dev/null
@@ -0,0 +1,88 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += boot.h
+header-y += bootsetup.h
+header-y += debugreg_32.h
+header-y += debugreg_64.h
+header-y += debugreg.h
+header-y += ldt_32.h
+header-y += ldt_64.h
+header-y += ldt.h
+header-y += msr-index.h
+header-y += prctl.h
+header-y += ptrace-abi_32.h
+header-y += ptrace-abi_64.h
+header-y += ptrace-abi.h
+header-y += sigcontext32.h
+header-y += ucontext_32.h
+header-y += ucontext_64.h
+header-y += ucontext.h
+header-y += vsyscall32.h
+
+unifdef-y += a.out_32.h
+unifdef-y += a.out_64.h
+unifdef-y += auxvec_32.h
+unifdef-y += auxvec_64.h
+unifdef-y += byteorder_32.h
+unifdef-y += byteorder_64.h
+unifdef-y += elf_32.h
+unifdef-y += elf_64.h
+unifdef-y += errno_32.h
+unifdef-y += errno_64.h
+unifdef-y += ioctls_32.h
+unifdef-y += ioctls_64.h
+unifdef-y += ipcbuf_32.h
+unifdef-y += ipcbuf_64.h
+unifdef-y += mce.h
+unifdef-y += mman_32.h
+unifdef-y += mman_64.h
+unifdef-y += msgbuf_32.h
+unifdef-y += msgbuf_64.h
+unifdef-y += msr_32.h
+unifdef-y += msr_64.h
+unifdef-y += msr.h
+unifdef-y += mtrr_32.h
+unifdef-y += mtrr_64.h
+unifdef-y += mtrr.h
+unifdef-y += page_32.h
+unifdef-y += page_64.h
+unifdef-y += param_32.h
+unifdef-y += param_64.h
+unifdef-y += posix_types_32.h
+unifdef-y += posix_types_64.h
+unifdef-y += ptrace_32.h
+unifdef-y += ptrace_64.h
+unifdef-y += resource_32.h
+unifdef-y += resource_64.h
+unifdef-y += sembuf_32.h
+unifdef-y += sembuf_64.h
+unifdef-y += setup_32.h
+unifdef-y += setup_64.h
+unifdef-y += shmbuf_32.h
+unifdef-y += shmbuf_64.h
+unifdef-y += shmparam_32.h
+unifdef-y += shmparam_64.h
+unifdef-y += sigcontext_32.h
+unifdef-y += sigcontext_64.h
+unifdef-y += siginfo_32.h
+unifdef-y += siginfo_64.h
+unifdef-y += signal_32.h
+unifdef-y += signal_64.h
+unifdef-y += sockios_32.h
+unifdef-y += sockios_64.h
+unifdef-y += stat_32.h
+unifdef-y += stat_64.h
+unifdef-y += statfs_32.h
+unifdef-y += statfs_64.h
+unifdef-y += termbits_32.h
+unifdef-y += termbits_64.h
+unifdef-y += termios_32.h
+unifdef-y += termios_64.h
+unifdef-y += types_32.h
+unifdef-y += types_64.h
+unifdef-y += unistd_32.h
+unifdef-y += unistd_64.h
+unifdef-y += user_32.h
+unifdef-y += user_64.h
+unifdef-y += vm86.h
+unifdef-y += vsyscall.h
diff --git a/include/asm-x86/a.out.h b/include/asm-x86/a.out.h
new file mode 100644 (file)
index 0000000..5bc9b1d
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "a.out_32.h"
+# else
+#  include "a.out_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "a.out_32.h"
+# else
+#  include "a.out_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/acpi.h b/include/asm-x86/acpi.h
new file mode 100644 (file)
index 0000000..0693689
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "acpi_32.h"
+#else
+# include "acpi_64.h"
+#endif
diff --git a/include/asm-x86/agp.h b/include/asm-x86/agp.h
new file mode 100644 (file)
index 0000000..9348f1e
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "agp_32.h"
+#else
+# include "agp_64.h"
+#endif
diff --git a/include/asm-x86/alternative-asm.i b/include/asm-x86/alternative-asm.i
new file mode 100644 (file)
index 0000000..4f360cd
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "alternative-asm_32.i"
+#else
+# include "alternative-asm_64.i"
+#endif
diff --git a/include/asm-x86/alternative.h b/include/asm-x86/alternative.h
new file mode 100644 (file)
index 0000000..9eef6a3
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "alternative_32.h"
+#else
+# include "alternative_64.h"
+#endif
diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h
new file mode 100644 (file)
index 0000000..9fbcc0b
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "apic_32.h"
+#else
+# include "apic_64.h"
+#endif
diff --git a/include/asm-x86/apicdef.h b/include/asm-x86/apicdef.h
new file mode 100644 (file)
index 0000000..4542c22
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "apicdef_32.h"
+#else
+# include "apicdef_64.h"
+#endif
diff --git a/include/asm-x86/atomic.h b/include/asm-x86/atomic.h
new file mode 100644 (file)
index 0000000..4e1b887
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "atomic_32.h"
+#else
+# include "atomic_64.h"
+#endif
diff --git a/include/asm-x86/auxvec.h b/include/asm-x86/auxvec.h
new file mode 100644 (file)
index 0000000..7ff866f
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "auxvec_32.h"
+# else
+#  include "auxvec_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "auxvec_32.h"
+# else
+#  include "auxvec_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h
new file mode 100644 (file)
index 0000000..07e3f6d
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "bitops_32.h"
+#else
+# include "bitops_64.h"
+#endif
diff --git a/include/asm-x86/bug.h b/include/asm-x86/bug.h
new file mode 100644 (file)
index 0000000..c655d7f
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "bug_32.h"
+#else
+# include "bug_64.h"
+#endif
diff --git a/include/asm-x86/bugs.h b/include/asm-x86/bugs.h
new file mode 100644 (file)
index 0000000..ddf42d3
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "bugs_32.h"
+#else
+# include "bugs_64.h"
+#endif
diff --git a/include/asm-x86/byteorder.h b/include/asm-x86/byteorder.h
new file mode 100644 (file)
index 0000000..eb14b18
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "byteorder_32.h"
+# else
+#  include "byteorder_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "byteorder_32.h"
+# else
+#  include "byteorder_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/cache.h b/include/asm-x86/cache.h
new file mode 100644 (file)
index 0000000..c36d190
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "cache_32.h"
+#else
+# include "cache_64.h"
+#endif
diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h
new file mode 100644 (file)
index 0000000..e2df3b5
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "cacheflush_32.h"
+#else
+# include "cacheflush_64.h"
+#endif
diff --git a/include/asm-x86/checksum.h b/include/asm-x86/checksum.h
new file mode 100644 (file)
index 0000000..848850f
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "checksum_32.h"
+#else
+# include "checksum_64.h"
+#endif
diff --git a/include/asm-x86/cmpxchg.h b/include/asm-x86/cmpxchg.h
new file mode 100644 (file)
index 0000000..a460fa0
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "cmpxchg_32.h"
+#else
+# include "cmpxchg_64.h"
+#endif
similarity index 100%
rename from include/asm-i386/cpu.h
rename to include/asm-x86/cpu.h
diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h
new file mode 100644 (file)
index 0000000..b7160a4
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "cpufeature_32.h"
+#else
+# include "cpufeature_64.h"
+#endif
similarity index 91%
rename from include/asm-x86_64/cpufeature.h
rename to include/asm-x86/cpufeature_64.h
index 8baefc3beb2e1e7682c6000e7875c96db88c1fd5..2983501e8b3e4dc88f05bbf0f3b3dc0de83449d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * cpufeature.h
+ * cpufeature_32.h
  *
  * Defines x86 CPU feature bits
  */
@@ -7,7 +7,7 @@
 #ifndef __ASM_X8664_CPUFEATURE_H
 #define __ASM_X8664_CPUFEATURE_H
 
-#include <asm-i386/cpufeature.h>
+#include <asm/cpufeature_32.h>
 
 #undef  cpu_has_vme
 #define cpu_has_vme            0
diff --git a/include/asm-x86/cputime.h b/include/asm-x86/cputime.h
new file mode 100644 (file)
index 0000000..87c37cf
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "cputime_32.h"
+#else
+# include "cputime_64.h"
+#endif
diff --git a/include/asm-x86/current.h b/include/asm-x86/current.h
new file mode 100644 (file)
index 0000000..d2526d3
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "current_32.h"
+#else
+# include "current_64.h"
+#endif
diff --git a/include/asm-x86/debugreg.h b/include/asm-x86/debugreg.h
new file mode 100644 (file)
index 0000000..b6ce7e4
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "debugreg_32.h"
+# else
+#  include "debugreg_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "debugreg_32.h"
+# else
+#  include "debugreg_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/delay.h b/include/asm-x86/delay.h
new file mode 100644 (file)
index 0000000..10f2c71
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "delay_32.h"
+#else
+# include "delay_64.h"
+#endif
diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h
new file mode 100644 (file)
index 0000000..6065c50
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "desc_32.h"
+#else
+# include "desc_64.h"
+#endif
diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h
new file mode 100644 (file)
index 0000000..e2bcf7c
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "device_32.h"
+#else
+# include "device_64.h"
+#endif
diff --git a/include/asm-x86/div64.h b/include/asm-x86/div64.h
new file mode 100644 (file)
index 0000000..8ac7da6
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "div64_32.h"
+#else
+# include "div64_64.h"
+#endif
diff --git a/include/asm-x86/dma-mapping.h b/include/asm-x86/dma-mapping.h
new file mode 100644 (file)
index 0000000..58f790f
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "dma-mapping_32.h"
+#else
+# include "dma-mapping_64.h"
+#endif
diff --git a/include/asm-x86/dma.h b/include/asm-x86/dma.h
new file mode 100644 (file)
index 0000000..9f936c6
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "dma_32.h"
+#else
+# include "dma_64.h"
+#endif
diff --git a/include/asm-x86/dmi.h b/include/asm-x86/dmi.h
new file mode 100644 (file)
index 0000000..c9e4e8e
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "dmi_32.h"
+#else
+# include "dmi_64.h"
+#endif
diff --git a/include/asm-x86/dwarf2.h b/include/asm-x86/dwarf2.h
new file mode 100644 (file)
index 0000000..b3cbb0c
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "dwarf2_32.h"
+#else
+# include "dwarf2_64.h"
+#endif
diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h
new file mode 100644 (file)
index 0000000..5d4d218
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "e820_32.h"
+#else
+# include "e820_64.h"
+#endif
diff --git a/include/asm-x86/edac.h b/include/asm-x86/edac.h
new file mode 100644 (file)
index 0000000..f8b888e
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "edac_32.h"
+#else
+# include "edac_64.h"
+#endif
diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h
new file mode 100644 (file)
index 0000000..ed6bb6e
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "elf_32.h"
+# else
+#  include "elf_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "elf_32.h"
+# else
+#  include "elf_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/errno.h b/include/asm-x86/errno.h
new file mode 100644 (file)
index 0000000..9d511be
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "errno_32.h"
+# else
+#  include "errno_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "errno_32.h"
+# else
+#  include "errno_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/fb.h b/include/asm-x86/fb.h
new file mode 100644 (file)
index 0000000..238c7ca
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "fb_32.h"
+#else
+# include "fb_64.h"
+#endif
diff --git a/include/asm-x86/fixmap.h b/include/asm-x86/fixmap.h
new file mode 100644 (file)
index 0000000..382eb27
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "fixmap_32.h"
+#else
+# include "fixmap_64.h"
+#endif
diff --git a/include/asm-x86/floppy.h b/include/asm-x86/floppy.h
new file mode 100644 (file)
index 0000000..aecbb6d
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "floppy_32.h"
+#else
+# include "floppy_64.h"
+#endif
diff --git a/include/asm-x86/futex.h b/include/asm-x86/futex.h
new file mode 100644 (file)
index 0000000..1f4610e
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "futex_32.h"
+#else
+# include "futex_64.h"
+#endif
diff --git a/include/asm-x86/genapic.h b/include/asm-x86/genapic.h
new file mode 100644 (file)
index 0000000..d48bee6
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "genapic_32.h"
+#else
+# include "genapic_64.h"
+#endif
diff --git a/include/asm-x86/hardirq.h b/include/asm-x86/hardirq.h
new file mode 100644 (file)
index 0000000..314434d
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "hardirq_32.h"
+#else
+# include "hardirq_64.h"
+#endif
diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h
new file mode 100644 (file)
index 0000000..9eff486
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "hpet_32.h"
+#else
+# include "hpet_64.h"
+#endif
similarity index 93%
rename from include/asm-x86_64/hpet.h
rename to include/asm-x86/hpet_64.h
index 79bb950f82c5d12205391aeef810ebf1ef583b01..fd4decac93a8eea825d13d24a38226063e4f7ca6 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _ASM_X8664_HPET_H
 #define _ASM_X8664_HPET_H 1
 
-#include <asm-i386/hpet.h>
+#include <asm/hpet_32.h>
 
 #define HPET_TICK_RATE (HZ * 100000UL)
 
diff --git a/include/asm-x86/hw_irq.h b/include/asm-x86/hw_irq.h
new file mode 100644 (file)
index 0000000..bf02539
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "hw_irq_32.h"
+#else
+# include "hw_irq_64.h"
+#endif
diff --git a/include/asm-x86/i387.h b/include/asm-x86/i387.h
new file mode 100644 (file)
index 0000000..a8bbed3
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "i387_32.h"
+#else
+# include "i387_64.h"
+#endif
diff --git a/include/asm-x86/i8253.h b/include/asm-x86/i8253.h
new file mode 100644 (file)
index 0000000..b2a4f99
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "i8253_32.h"
+#else
+# include "i8253_64.h"
+#endif
similarity index 100%
rename from include/asm-i386/ide.h
rename to include/asm-x86/ide.h
diff --git a/include/asm-x86/intel_arch_perfmon.h b/include/asm-x86/intel_arch_perfmon.h
new file mode 100644 (file)
index 0000000..4f6d4e6
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "intel_arch_perfmon_32.h"
+#else
+# include "intel_arch_perfmon_64.h"
+#endif
diff --git a/include/asm-x86/io.h b/include/asm-x86/io.h
new file mode 100644 (file)
index 0000000..5a58b17
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "io_32.h"
+#else
+# include "io_64.h"
+#endif
diff --git a/include/asm-x86/io_apic.h b/include/asm-x86/io_apic.h
new file mode 100644 (file)
index 0000000..8849496
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "io_apic_32.h"
+#else
+# include "io_apic_64.h"
+#endif
diff --git a/include/asm-x86/ioctls.h b/include/asm-x86/ioctls.h
new file mode 100644 (file)
index 0000000..1e0fd48
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ioctls_32.h"
+# else
+#  include "ioctls_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ioctls_32.h"
+# else
+#  include "ioctls_64.h"
+# endif
+#endif
similarity index 100%
rename from include/asm-i386/ipc.h
rename to include/asm-x86/ipc.h
diff --git a/include/asm-x86/ipcbuf.h b/include/asm-x86/ipcbuf.h
new file mode 100644 (file)
index 0000000..eb2e448
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ipcbuf_32.h"
+# else
+#  include "ipcbuf_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ipcbuf_32.h"
+# else
+#  include "ipcbuf_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/irq.h b/include/asm-x86/irq.h
new file mode 100644 (file)
index 0000000..7ba9054
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "irq_32.h"
+#else
+# include "irq_64.h"
+#endif
diff --git a/include/asm-x86/irq_regs.h b/include/asm-x86/irq_regs.h
new file mode 100644 (file)
index 0000000..89c898a
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "irq_regs_32.h"
+#else
+# include "irq_regs_64.h"
+#endif
diff --git a/include/asm-x86/irqflags.h b/include/asm-x86/irqflags.h
new file mode 100644 (file)
index 0000000..1b695ff
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "irqflags_32.h"
+#else
+# include "irqflags_64.h"
+#endif
similarity index 100%
rename from include/asm-i386/ist.h
rename to include/asm-x86/ist.h
similarity index 100%
rename from include/asm-x86_64/k8.h
rename to include/asm-x86/k8.h
diff --git a/include/asm-x86/kdebug.h b/include/asm-x86/kdebug.h
new file mode 100644 (file)
index 0000000..3847910
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "kdebug_32.h"
+#else
+# include "kdebug_64.h"
+#endif
diff --git a/include/asm-x86/kexec.h b/include/asm-x86/kexec.h
new file mode 100644 (file)
index 0000000..718ddbf
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "kexec_32.h"
+#else
+# include "kexec_64.h"
+#endif
diff --git a/include/asm-x86/kmap_types.h b/include/asm-x86/kmap_types.h
new file mode 100644 (file)
index 0000000..e4ec724
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "kmap_types_32.h"
+#else
+# include "kmap_types_64.h"
+#endif
diff --git a/include/asm-x86/kprobes.h b/include/asm-x86/kprobes.h
new file mode 100644 (file)
index 0000000..b7bbd25
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "kprobes_32.h"
+#else
+# include "kprobes_64.h"
+#endif
diff --git a/include/asm-x86/ldt.h b/include/asm-x86/ldt.h
new file mode 100644 (file)
index 0000000..3d9cc20
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ldt_32.h"
+# else
+#  include "ldt_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ldt_32.h"
+# else
+#  include "ldt_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/linkage.h b/include/asm-x86/linkage.h
new file mode 100644 (file)
index 0000000..94b257f
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "linkage_32.h"
+#else
+# include "linkage_64.h"
+#endif
diff --git a/include/asm-x86/local.h b/include/asm-x86/local.h
new file mode 100644 (file)
index 0000000..c7a1b1c
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "local_32.h"
+#else
+# include "local_64.h"
+#endif
diff --git a/include/asm-x86/mc146818rtc.h b/include/asm-x86/mc146818rtc.h
new file mode 100644 (file)
index 0000000..5c2bb66
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mc146818rtc_32.h"
+#else
+# include "mc146818rtc_64.h"
+#endif
similarity index 100%
rename from include/asm-i386/mca.h
rename to include/asm-x86/mca.h
diff --git a/include/asm-x86/mce.h b/include/asm-x86/mce.h
new file mode 100644 (file)
index 0000000..cc8ca38
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mce_32.h"
+#else
+# include "mce_64.h"
+#endif
diff --git a/include/asm-x86/mman.h b/include/asm-x86/mman.h
new file mode 100644 (file)
index 0000000..322db07
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "mman_32.h"
+# else
+#  include "mman_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "mman_32.h"
+# else
+#  include "mman_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/mmu.h b/include/asm-x86/mmu.h
new file mode 100644 (file)
index 0000000..9c628cd
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mmu_32.h"
+#else
+# include "mmu_64.h"
+#endif
diff --git a/include/asm-x86/mmu_context.h b/include/asm-x86/mmu_context.h
new file mode 100644 (file)
index 0000000..6598450
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mmu_context_32.h"
+#else
+# include "mmu_context_64.h"
+#endif
similarity index 100%
rename from include/asm-i386/mmx.h
rename to include/asm-x86/mmx.h
diff --git a/include/asm-x86/mmzone.h b/include/asm-x86/mmzone.h
new file mode 100644 (file)
index 0000000..64217ea
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mmzone_32.h"
+#else
+# include "mmzone_64.h"
+#endif
diff --git a/include/asm-x86/module.h b/include/asm-x86/module.h
new file mode 100644 (file)
index 0000000..2b2f18d
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "module_32.h"
+#else
+# include "module_64.h"
+#endif
diff --git a/include/asm-x86/mpspec.h b/include/asm-x86/mpspec.h
new file mode 100644 (file)
index 0000000..8f268e8
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mpspec_32.h"
+#else
+# include "mpspec_64.h"
+#endif
diff --git a/include/asm-x86/msgbuf.h b/include/asm-x86/msgbuf.h
new file mode 100644 (file)
index 0000000..154f7d6
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "msgbuf_32.h"
+# else
+#  include "msgbuf_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "msgbuf_32.h"
+# else
+#  include "msgbuf_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h
new file mode 100644 (file)
index 0000000..2f87ce0
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "msr_32.h"
+# else
+#  include "msr_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "msr_32.h"
+# else
+#  include "msr_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/mtrr.h b/include/asm-x86/mtrr.h
new file mode 100644 (file)
index 0000000..34f633b
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "mtrr_32.h"
+# else
+#  include "mtrr_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "mtrr_32.h"
+# else
+#  include "mtrr_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/mutex.h b/include/asm-x86/mutex.h
new file mode 100644 (file)
index 0000000..a731b9c
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "mutex_32.h"
+#else
+# include "mutex_64.h"
+#endif
diff --git a/include/asm-x86/namei.h b/include/asm-x86/namei.h
new file mode 100644 (file)
index 0000000..732f8f0
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "namei_32.h"
+#else
+# include "namei_64.h"
+#endif
diff --git a/include/asm-x86/nmi.h b/include/asm-x86/nmi.h
new file mode 100644 (file)
index 0000000..53ccac1
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "nmi_32.h"
+#else
+# include "nmi_64.h"
+#endif
diff --git a/include/asm-x86/numa.h b/include/asm-x86/numa.h
new file mode 100644 (file)
index 0000000..27da400
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "numa_32.h"
+#else
+# include "numa_64.h"
+#endif
diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h
new file mode 100644 (file)
index 0000000..a757eb2
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "page_32.h"
+# else
+#  include "page_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "page_32.h"
+# else
+#  include "page_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/param.h b/include/asm-x86/param.h
new file mode 100644 (file)
index 0000000..640851b
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "param_32.h"
+# else
+#  include "param_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "param_32.h"
+# else
+#  include "param_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/parport.h b/include/asm-x86/parport.h
new file mode 100644 (file)
index 0000000..2a31157
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "parport_32.h"
+#else
+# include "parport_64.h"
+#endif
diff --git a/include/asm-x86/pci.h b/include/asm-x86/pci.h
new file mode 100644 (file)
index 0000000..a8cac8c
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "pci_32.h"
+#else
+# include "pci_64.h"
+#endif
diff --git a/include/asm-x86/percpu.h b/include/asm-x86/percpu.h
new file mode 100644 (file)
index 0000000..a1aaad2
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "percpu_32.h"
+#else
+# include "percpu_64.h"
+#endif
diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h
new file mode 100644 (file)
index 0000000..5886eed
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "pgalloc_32.h"
+#else
+# include "pgalloc_64.h"
+#endif
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
new file mode 100644 (file)
index 0000000..1039140
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "pgtable_32.h"
+#else
+# include "pgtable_64.h"
+#endif
diff --git a/include/asm-x86/posix_types.h b/include/asm-x86/posix_types.h
new file mode 100644 (file)
index 0000000..bb7133d
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "posix_types_32.h"
+# else
+#  include "posix_types_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "posix_types_32.h"
+# else
+#  include "posix_types_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h
new file mode 100644 (file)
index 0000000..46e1c04
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "processor_32.h"
+#else
+# include "processor_64.h"
+#endif
diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h
new file mode 100644 (file)
index 0000000..6824c49
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ptrace-abi_32.h"
+# else
+#  include "ptrace-abi_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ptrace-abi_32.h"
+# else
+#  include "ptrace-abi_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h
new file mode 100644 (file)
index 0000000..bc4d64a
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ptrace_32.h"
+# else
+#  include "ptrace_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ptrace_32.h"
+# else
+#  include "ptrace_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/required-features.h b/include/asm-x86/required-features.h
new file mode 100644 (file)
index 0000000..8b64f3e
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "required-features_32.h"
+#else
+# include "required-features_64.h"
+#endif
diff --git a/include/asm-x86/resource.h b/include/asm-x86/resource.h
new file mode 100644 (file)
index 0000000..732410a
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "resource_32.h"
+# else
+#  include "resource_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "resource_32.h"
+# else
+#  include "resource_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/resume-trace.h b/include/asm-x86/resume-trace.h
new file mode 100644 (file)
index 0000000..9b6dd09
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "resume-trace_32.h"
+#else
+# include "resume-trace_64.h"
+#endif
diff --git a/include/asm-x86/rtc.h b/include/asm-x86/rtc.h
new file mode 100644 (file)
index 0000000..1f0c98e
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "rtc_32.h"
+#else
+# include "rtc_64.h"
+#endif
diff --git a/include/asm-x86/rwlock.h b/include/asm-x86/rwlock.h
new file mode 100644 (file)
index 0000000..a3be7d8
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "rwlock_32.h"
+#else
+# include "rwlock_64.h"
+#endif
diff --git a/include/asm-x86/scatterlist.h b/include/asm-x86/scatterlist.h
new file mode 100644 (file)
index 0000000..3a1e762
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "scatterlist_32.h"
+#else
+# include "scatterlist_64.h"
+#endif
diff --git a/include/asm-x86/seccomp.h b/include/asm-x86/seccomp.h
new file mode 100644 (file)
index 0000000..c62e58a
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "seccomp_32.h"
+#else
+# include "seccomp_64.h"
+#endif
diff --git a/include/asm-x86/sections.h b/include/asm-x86/sections.h
new file mode 100644 (file)
index 0000000..ae6c69d
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "sections_32.h"
+#else
+# include "sections_64.h"
+#endif
diff --git a/include/asm-x86/segment.h b/include/asm-x86/segment.h
new file mode 100644 (file)
index 0000000..6050682
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "segment_32.h"
+#else
+# include "segment_64.h"
+#endif
diff --git a/include/asm-x86/semaphore.h b/include/asm-x86/semaphore.h
new file mode 100644 (file)
index 0000000..572c0b6
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "semaphore_32.h"
+#else
+# include "semaphore_64.h"
+#endif
diff --git a/include/asm-x86/sembuf.h b/include/asm-x86/sembuf.h
new file mode 100644 (file)
index 0000000..e42c971
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "sembuf_32.h"
+# else
+#  include "sembuf_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "sembuf_32.h"
+# else
+#  include "sembuf_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/serial.h b/include/asm-x86/serial.h
new file mode 100644 (file)
index 0000000..cf1b052
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "serial_32.h"
+#else
+# include "serial_64.h"
+#endif
diff --git a/include/asm-x86/setup.h b/include/asm-x86/setup.h
new file mode 100644 (file)
index 0000000..81c0d98
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "setup_32.h"
+# else
+#  include "setup_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "setup_32.h"
+# else
+#  include "setup_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/shmbuf.h b/include/asm-x86/shmbuf.h
new file mode 100644 (file)
index 0000000..e85f1cb
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "shmbuf_32.h"
+# else
+#  include "shmbuf_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "shmbuf_32.h"
+# else
+#  include "shmbuf_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/shmparam.h b/include/asm-x86/shmparam.h
new file mode 100644 (file)
index 0000000..165627c
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "shmparam_32.h"
+# else
+#  include "shmparam_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "shmparam_32.h"
+# else
+#  include "shmparam_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/sigcontext.h b/include/asm-x86/sigcontext.h
new file mode 100644 (file)
index 0000000..0d16cef
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "sigcontext_32.h"
+# else
+#  include "sigcontext_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "sigcontext_32.h"
+# else
+#  include "sigcontext_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/siginfo.h b/include/asm-x86/siginfo.h
new file mode 100644 (file)
index 0000000..0b8e4bb
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "siginfo_32.h"
+# else
+#  include "siginfo_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "siginfo_32.h"
+# else
+#  include "siginfo_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/signal.h b/include/asm-x86/signal.h
new file mode 100644 (file)
index 0000000..bf5a63f
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "signal_32.h"
+# else
+#  include "signal_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "signal_32.h"
+# else
+#  include "signal_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/smp.h b/include/asm-x86/smp.h
new file mode 100644 (file)
index 0000000..f2e8319
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "smp_32.h"
+#else
+# include "smp_64.h"
+#endif
diff --git a/include/asm-x86/sockios.h b/include/asm-x86/sockios.h
new file mode 100644 (file)
index 0000000..5a134fc
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "sockios_32.h"
+# else
+#  include "sockios_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "sockios_32.h"
+# else
+#  include "sockios_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/sparsemem.h b/include/asm-x86/sparsemem.h
new file mode 100644 (file)
index 0000000..3f203b1
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "sparsemem_32.h"
+#else
+# include "sparsemem_64.h"
+#endif
diff --git a/include/asm-x86/spinlock.h b/include/asm-x86/spinlock.h
new file mode 100644 (file)
index 0000000..d74d85e
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "spinlock_32.h"
+#else
+# include "spinlock_64.h"
+#endif
diff --git a/include/asm-x86/stat.h b/include/asm-x86/stat.h
new file mode 100644 (file)
index 0000000..3ff6b50
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "stat_32.h"
+# else
+#  include "stat_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "stat_32.h"
+# else
+#  include "stat_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/statfs.h b/include/asm-x86/statfs.h
new file mode 100644 (file)
index 0000000..327fb5d
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "statfs_32.h"
+# else
+#  include "statfs_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "statfs_32.h"
+# else
+#  include "statfs_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/string.h b/include/asm-x86/string.h
new file mode 100644 (file)
index 0000000..6dfd6d9
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "string_32.h"
+#else
+# include "string_64.h"
+#endif
diff --git a/include/asm-x86/suspend.h b/include/asm-x86/suspend.h
new file mode 100644 (file)
index 0000000..9bd521f
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "suspend_32.h"
+#else
+# include "suspend_64.h"
+#endif
diff --git a/include/asm-x86/system.h b/include/asm-x86/system.h
new file mode 100644 (file)
index 0000000..692562b
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "system_32.h"
+#else
+# include "system_64.h"
+#endif
diff --git a/include/asm-x86/termbits.h b/include/asm-x86/termbits.h
new file mode 100644 (file)
index 0000000..69f3080
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "termbits_32.h"
+# else
+#  include "termbits_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "termbits_32.h"
+# else
+#  include "termbits_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/termios.h b/include/asm-x86/termios.h
new file mode 100644 (file)
index 0000000..a4f4ae2
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "termios_32.h"
+# else
+#  include "termios_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "termios_32.h"
+# else
+#  include "termios_64.h"
+# endif
+#endif
similarity index 99%
rename from include/asm-i386/termios.h
rename to include/asm-x86/termios_32.h
index f520b7c16fa2f3178fcc0a44326d8b5d7690b189..6fdb2c841b73750839309d6a2534978dc2c5269f 100644 (file)
@@ -40,7 +40,6 @@ struct termio {
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
 #ifdef __KERNEL__
-#include <linux/module.h>
 
 /*     intr=^C         quit=^\         erase=del       kill=^U
        eof=^D          vtime=\0        vmin=\1         sxtc=\0
diff --git a/include/asm-x86/thread_info.h b/include/asm-x86/thread_info.h
new file mode 100644 (file)
index 0000000..d5fd12f
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "thread_info_32.h"
+#else
+# include "thread_info_64.h"
+#endif
diff --git a/include/asm-x86/timex.h b/include/asm-x86/timex.h
new file mode 100644 (file)
index 0000000..d01c18c
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "timex_32.h"
+#else
+# include "timex_64.h"
+#endif
diff --git a/include/asm-x86/tlb.h b/include/asm-x86/tlb.h
new file mode 100644 (file)
index 0000000..7d55c37
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "tlb_32.h"
+#else
+# include "tlb_64.h"
+#endif
diff --git a/include/asm-x86/tlbflush.h b/include/asm-x86/tlbflush.h
new file mode 100644 (file)
index 0000000..9af4cc8
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "tlbflush_32.h"
+#else
+# include "tlbflush_64.h"
+#endif
diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h
new file mode 100644 (file)
index 0000000..b10fde9
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "topology_32.h"
+#else
+# include "topology_64.h"
+#endif
similarity index 100%
rename from include/asm-i386/tsc.h
rename to include/asm-x86/tsc.h
diff --git a/include/asm-x86/types.h b/include/asm-x86/types.h
new file mode 100644 (file)
index 0000000..a777a9b
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "types_32.h"
+# else
+#  include "types_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "types_32.h"
+# else
+#  include "types_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h
new file mode 100644 (file)
index 0000000..9fefd29
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "uaccess_32.h"
+#else
+# include "uaccess_64.h"
+#endif
diff --git a/include/asm-x86/ucontext.h b/include/asm-x86/ucontext.h
new file mode 100644 (file)
index 0000000..175c8cb
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "ucontext_32.h"
+# else
+#  include "ucontext_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "ucontext_32.h"
+# else
+#  include "ucontext_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/unaligned.h b/include/asm-x86/unaligned.h
new file mode 100644 (file)
index 0000000..6806715
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "unaligned_32.h"
+#else
+# include "unaligned_64.h"
+#endif
diff --git a/include/asm-x86/unistd.h b/include/asm-x86/unistd.h
new file mode 100644 (file)
index 0000000..2a58ed3
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "unistd_32.h"
+# else
+#  include "unistd_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "unistd_32.h"
+# else
+#  include "unistd_64.h"
+# endif
+#endif
diff --git a/include/asm-x86/unwind.h b/include/asm-x86/unwind.h
new file mode 100644 (file)
index 0000000..7e4d7ad
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "unwind_32.h"
+#else
+# include "unwind_64.h"
+#endif
diff --git a/include/asm-x86/user.h b/include/asm-x86/user.h
new file mode 100644 (file)
index 0000000..484715a
--- /dev/null
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+# ifdef CONFIG_X86_32
+#  include "user_32.h"
+# else
+#  include "user_64.h"
+# endif
+#else
+# ifdef __i386__
+#  include "user_32.h"
+# else
+#  include "user_64.h"
+# endif
+#endif
similarity index 100%
rename from include/asm-i386/vga.h
rename to include/asm-x86/vga.h
similarity index 100%
rename from include/asm-i386/vic.h
rename to include/asm-x86/vic.h
similarity index 100%
rename from include/asm-i386/vmi.h
rename to include/asm-x86/vmi.h
diff --git a/include/asm-x86/xor.h b/include/asm-x86/xor.h
new file mode 100644 (file)
index 0000000..11b3bb8
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef CONFIG_X86_32
+# include "xor_32.h"
+#else
+# include "xor_64.h"
+#endif
diff --git a/include/asm-x86_64/Kbuild b/include/asm-x86_64/Kbuild
deleted file mode 100644 (file)
index 75a2def..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-include include/asm-generic/Kbuild.asm
-
-ALTARCH := i386
-ARCHDEF := defined __x86_64__
-ALTARCHDEF := defined __i386__
-
-header-y += boot.h
-header-y += bootsetup.h
-header-y += debugreg.h
-header-y += ldt.h
-header-y += msr-index.h
-header-y += prctl.h
-header-y += ptrace-abi.h
-header-y += sigcontext32.h
-header-y += ucontext.h
-header-y += vsyscall32.h
-
-unifdef-y += mce.h
-unifdef-y += msr.h
-unifdef-y += mtrr.h
-unifdef-y += vsyscall.h
diff --git a/include/asm-x86_64/boot.h b/include/asm-x86_64/boot.h
deleted file mode 100644 (file)
index 3c46cea..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/boot.h>
diff --git a/include/asm-x86_64/bootparam.h b/include/asm-x86_64/bootparam.h
deleted file mode 100644 (file)
index aa82e52..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/bootparam.h>
diff --git a/include/asm-x86_64/cpu.h b/include/asm-x86_64/cpu.h
deleted file mode 100644 (file)
index 8eea076..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/cpu.h>
diff --git a/include/asm-x86_64/emergency-restart.h b/include/asm-x86_64/emergency-restart.h
deleted file mode 100644 (file)
index 680c395..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_EMERGENCY_RESTART_H
-#define _ASM_EMERGENCY_RESTART_H
-
-extern void machine_emergency_restart(void);
-
-#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-x86_64/fcntl.h b/include/asm-x86_64/fcntl.h
deleted file mode 100644 (file)
index 46ab12d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/fcntl.h>
diff --git a/include/asm-x86_64/hypertransport.h b/include/asm-x86_64/hypertransport.h
deleted file mode 100644 (file)
index 5cbf9fa..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/hypertransport.h>
diff --git a/include/asm-x86_64/ide.h b/include/asm-x86_64/ide.h
deleted file mode 100644 (file)
index 4cef0ef..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/ide.h>
diff --git a/include/asm-x86_64/ioctl.h b/include/asm-x86_64/ioctl.h
deleted file mode 100644 (file)
index b279fe0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ioctl.h>
diff --git a/include/asm-x86_64/ist.h b/include/asm-x86_64/ist.h
deleted file mode 100644 (file)
index 338857e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/ist.h>
diff --git a/include/asm-x86_64/msidef.h b/include/asm-x86_64/msidef.h
deleted file mode 100644 (file)
index 083ad58..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/msidef.h>
diff --git a/include/asm-x86_64/msr-index.h b/include/asm-x86_64/msr-index.h
deleted file mode 100644 (file)
index d77a63f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/msr-index.h>
diff --git a/include/asm-x86_64/node.h b/include/asm-x86_64/node.h
deleted file mode 100644 (file)
index 0ee6f88..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/node.h>
diff --git a/include/asm-x86_64/poll.h b/include/asm-x86_64/poll.h
deleted file mode 100644 (file)
index c98509d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/poll.h>
diff --git a/include/asm-x86_64/processor-flags.h b/include/asm-x86_64/processor-flags.h
deleted file mode 100644 (file)
index ec99a57..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/processor-flags.h>
diff --git a/include/asm-x86_64/socket.h b/include/asm-x86_64/socket.h
deleted file mode 100644 (file)
index 90af60c..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _ASM_SOCKET_H
-#define _ASM_SOCKET_H
-
-#include <asm/sockios.h>
-
-/* For setsockopt(2) */
-#define SOL_SOCKET     1
-
-#define SO_DEBUG       1
-#define SO_REUSEADDR   2
-#define SO_TYPE                3
-#define SO_ERROR       4
-#define SO_DONTROUTE   5
-#define SO_BROADCAST   6
-#define SO_SNDBUF      7
-#define SO_RCVBUF      8
-#define SO_SNDBUFFORCE 32
-#define SO_RCVBUFFORCE 33
-#define SO_KEEPALIVE   9
-#define SO_OOBINLINE   10
-#define SO_NO_CHECK    11
-#define SO_PRIORITY    12
-#define SO_LINGER      13
-#define SO_BSDCOMPAT   14
-/* To add :#define SO_REUSEPORT 15 */
-#define SO_PASSCRED    16
-#define SO_PEERCRED    17
-#define SO_RCVLOWAT    18
-#define SO_SNDLOWAT    19
-#define SO_RCVTIMEO    20
-#define SO_SNDTIMEO    21
-
-/* Security levels - as per NRL IPv6 - don't actually do anything */
-#define SO_SECURITY_AUTHENTICATION             22
-#define SO_SECURITY_ENCRYPTION_TRANSPORT       23
-#define SO_SECURITY_ENCRYPTION_NETWORK         24
-
-#define SO_BINDTODEVICE        25
-
-/* Socket filtering */
-#define SO_ATTACH_FILTER        26
-#define SO_DETACH_FILTER        27
-
-#define SO_PEERNAME            28
-#define SO_TIMESTAMP           29
-#define SCM_TIMESTAMP          SO_TIMESTAMP
-
-#define SO_ACCEPTCONN          30
-
-#define SO_PEERSEC             31
-#define SO_PASSSEC             34
-#define SO_TIMESTAMPNS         35
-#define SCM_TIMESTAMPNS                SO_TIMESTAMPNS
-
-#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-x86_64/spinlock_types.h b/include/asm-x86_64/spinlock_types.h
deleted file mode 100644 (file)
index 4da9345..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __ASM_SPINLOCK_TYPES_H
-#define __ASM_SPINLOCK_TYPES_H
-
-#ifndef __LINUX_SPINLOCK_TYPES_H
-# error "please don't include this file directly"
-#endif
-
-typedef struct {
-       unsigned int slock;
-} raw_spinlock_t;
-
-#define __RAW_SPIN_LOCK_UNLOCKED       { 1 }
-
-typedef struct {
-       unsigned int lock;
-} raw_rwlock_t;
-
-#define __RAW_RW_LOCK_UNLOCKED         { RW_LOCK_BIAS }
-
-#endif
diff --git a/include/asm-x86_64/therm_throt.h b/include/asm-x86_64/therm_throt.h
deleted file mode 100644 (file)
index 5aac059..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/therm_throt.h>
diff --git a/include/asm-x86_64/tsc.h b/include/asm-x86_64/tsc.h
deleted file mode 100644 (file)
index d66ba6e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-i386/tsc.h>
diff --git a/include/asm-x86_64/vga.h b/include/asm-x86_64/vga.h
deleted file mode 100644 (file)
index 0ecf68a..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *     Access to VGA videoram
- *
- *     (c) 1998 Martin Mares <mj@ucw.cz>
- */
-
-#ifndef _LINUX_ASM_VGA_H_
-#define _LINUX_ASM_VGA_H_
-
-/*
- *     On the PC, we can just recalculate addresses and then
- *     access the videoram directly without any black magic.
- */
-
-#define VGA_MAP_MEM(x,s) (unsigned long)phys_to_virt(x)
-
-#define vga_readb(x) (*(x))
-#define vga_writeb(x,y) (*(y) = (x))
-
-#endif
index b690148657140aac33bf11c2e1e288a9398e6ac6..a271b67a8e2d72cdf6adc68d64ff1a74703040fb 100644 (file)
 #define I2C_DRIVERID_WM8750    90      /* Wolfson WM8750 audio codec */
 #define I2C_DRIVERID_WM8753    91      /* Wolfson WM8753 audio codec */
 #define I2C_DRIVERID_LM4857    92      /* LM4857 Audio Amplifier */
+#define I2C_DRIVERID_VP27SMPX  93      /* Panasonic VP27s tuner internal MPX */
 
 #define I2C_DRIVERID_I2CDEV    900
 #define I2C_DRIVERID_ARP        902    /* SMBus ARP Client              */
 #define I2C_HW_B_EM28XX                0x01001f /* em28xx video capture cards */
 #define I2C_HW_B_CX2341X       0x010020 /* Conexant CX2341X MPEG encoder cards */
 #define I2C_HW_B_INTELFB       0x010021 /* intel framebuffer driver */
+#define I2C_HW_B_CX23885       0x010022 /* conexant 23885 based tv cards (bus1) */
 
 /* --- PCF 8584 based algorithms                                       */
 #define I2C_HW_P_LP            0x020000 /* Parallel port interface */
similarity index 93%
rename from include/media/ivtv.h
rename to include/linux/ivtv.h
index 412b48ea8eda3bf219e29eae1a3877ab5bec90a5..794b8daa9378e6647064f34174b6849ba50bb2a8 100644 (file)
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef _LINUX_IVTV_H
-#define _LINUX_IVTV_H
+#ifndef __LINUX_IVTV_H__
+#define __LINUX_IVTV_H__
+
+#ifdef __KERNEL__
+#include <linux/compiler.h> /* need __user */
+#else
+#define __user
+#endif
+#include <linux/types.h>
 
 /* ivtv knows several distinct output modes: MPEG streaming,
    YUV streaming, YUV updates through user DMA and the passthrough
similarity index 56%
rename from drivers/media/video/ivtv/ivtv-video.h
rename to include/linux/ivtvfb.h
index c8ade5d3c413b9db5911df701ff6ffa6f2279f63..e980ba62ddcc23f405fa06a91d512bb25193312b 100644 (file)
@@ -1,6 +1,7 @@
 /*
-    saa7127 interface functions
-    Copyright (C) 2004-2007  Hans Verkuil <hverkuil@xs4all.nl>
+    On Screen Display cx23415 Framebuffer driver
+
+    Copyright (C) 2006, 2007  Ian Armstrong <ian@iarmst.demon.co.uk>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-void ivtv_set_wss(struct ivtv *itv, int enabled, int mode);
-void ivtv_set_cc(struct ivtv *itv, int mode, u8 cc1, u8 cc2, u8 cc3, u8 cc4);
-void ivtv_set_vps(struct ivtv *itv, int enabled, u8 vps1, u8 vps2, u8 vps3,
-                 u8 vps4, u8 vps5);
-void ivtv_video_set_io(struct ivtv *itv);
+#ifndef __LINUX_IVTVFB_H__
+#define __LINUX_IVTVFB_H__
+
+#ifdef __KERNEL__
+#include <linux/compiler.h> /* need __user */
+#else
+#define __user
+#endif
+#include <linux/types.h>
+
+/* Framebuffer external API */
+
+struct ivtvfb_dma_frame {
+       void __user *source;
+       unsigned long dest_offset;
+       int count;
+};
+
+#define IVTVFB_IOC_DMA_FRAME   _IOW('V', BASE_VIDIOC_PRIVATE+0, struct ivtvfb_dma_frame)
+#define FBIO_WAITFORVSYNC      _IOW('F', 0x20, u_int32_t)
+
+#endif
index badf702fcff417c73d137ed57eba6dcd77b79be7..0d508ac17d6452b5a35429fd38704c8de2c13de4 100644 (file)
@@ -55,7 +55,28 @@ struct sd_switch_caps {
        unsigned int            hs_max_dtr;
 };
 
+struct sdio_cccr {
+       unsigned int            sdio_vsn;
+       unsigned int            sd_vsn;
+       unsigned int            multi_block:1,
+                               low_speed:1,
+                               wide_bus:1,
+                               high_power:1,
+                               high_speed:1;
+};
+
+struct sdio_cis {
+       unsigned short          vendor;
+       unsigned short          device;
+       unsigned short          blksize;
+       unsigned int            max_dtr;
+};
+
 struct mmc_host;
+struct sdio_func;
+struct sdio_func_tuple;
+
+#define SDIO_MAX_FUNCS         7
 
 /*
  * MMC device
@@ -67,11 +88,13 @@ struct mmc_card {
        unsigned int            type;           /* card type */
 #define MMC_TYPE_MMC           0               /* MMC card */
 #define MMC_TYPE_SD            1               /* SD card */
+#define MMC_TYPE_SDIO          2               /* SDIO card */
        unsigned int            state;          /* (our) card state */
 #define MMC_STATE_PRESENT      (1<<0)          /* present in sysfs */
 #define MMC_STATE_READONLY     (1<<1)          /* card is read-only */
 #define MMC_STATE_HIGHSPEED    (1<<2)          /* card is in high speed mode */
 #define MMC_STATE_BLOCKADDR    (1<<3)          /* card uses block-addressing */
+
        u32                     raw_cid[4];     /* raw card CID */
        u32                     raw_csd[4];     /* raw card CSD */
        u32                     raw_scr[2];     /* raw card SCR */
@@ -80,10 +103,19 @@ struct mmc_card {
        struct mmc_ext_csd      ext_csd;        /* mmc v4 extended card specific */
        struct sd_scr           scr;            /* extra SD information */
        struct sd_switch_caps   sw_caps;        /* switch (CMD6) caps */
+
+       unsigned int            sdio_funcs;     /* number of SDIO functions */
+       struct sdio_cccr        cccr;           /* common card info */
+       struct sdio_cis         cis;            /* common tuple info */
+       struct sdio_func        *sdio_func[SDIO_MAX_FUNCS]; /* SDIO functions (devices) */
+       unsigned                num_info;       /* number of info strings */
+       const char              **info;         /* info strings */
+       struct sdio_func_tuple  *tuples;        /* unknown common tuples */
 };
 
 #define mmc_card_mmc(c)                ((c)->type == MMC_TYPE_MMC)
 #define mmc_card_sd(c)         ((c)->type == MMC_TYPE_SD)
+#define mmc_card_sdio(c)       ((c)->type == MMC_TYPE_SDIO)
 
 #define mmc_card_present(c)    ((c)->state & MMC_STATE_PRESENT)
 #define mmc_card_readonly(c)   ((c)->state & MMC_STATE_READONLY)
index 63a80ea611248fe2551243548fe3ebdd883851de..d0c3abed74c2cbb5cbc71c6bd563bd04dad03fdc 100644 (file)
@@ -25,14 +25,20 @@ struct mmc_command {
 #define MMC_RSP_CRC    (1 << 2)                /* expect valid crc */
 #define MMC_RSP_BUSY   (1 << 3)                /* card may send busy */
 #define MMC_RSP_OPCODE (1 << 4)                /* response contains opcode */
-#define MMC_CMD_MASK   (3 << 5)                /* command type */
+
+#define MMC_CMD_MASK   (3 << 5)                /* non-SPI command type */
 #define MMC_CMD_AC     (0 << 5)
 #define MMC_CMD_ADTC   (1 << 5)
 #define MMC_CMD_BC     (2 << 5)
 #define MMC_CMD_BCR    (3 << 5)
 
+#define MMC_RSP_SPI_S1 (1 << 7)                /* one status byte */
+#define MMC_RSP_SPI_S2 (1 << 8)                /* second byte */
+#define MMC_RSP_SPI_B4 (1 << 9)                /* four data bytes */
+#define MMC_RSP_SPI_BUSY (1 << 10)             /* card may send busy */
+
 /*
- * These are the response types, and correspond to valid bit
+ * These are the native response types, and correspond to valid bit
  * patterns of the above flags.  One additional valid pattern
  * is all zeros, which means we don't expect a response.
  */
@@ -41,11 +47,29 @@ struct mmc_command {
 #define MMC_RSP_R1B    (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
 #define MMC_RSP_R2     (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
 #define MMC_RSP_R3     (MMC_RSP_PRESENT)
+#define MMC_RSP_R4     (MMC_RSP_PRESENT)
+#define MMC_RSP_R5     (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
 #define MMC_RSP_R6     (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
 #define MMC_RSP_R7     (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
 
 #define mmc_resp_type(cmd)     ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
 
+/*
+ * These are the SPI response types for MMC, SD, and SDIO cards.
+ * Commands return R1, with maybe more info.  Zero is an error type;
+ * callers must always provide the appropriate MMC_RSP_SPI_Rx flags.
+ */
+#define MMC_RSP_SPI_R1 (MMC_RSP_SPI_S1)
+#define MMC_RSP_SPI_R1B        (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY)
+#define MMC_RSP_SPI_R2 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
+#define MMC_RSP_SPI_R3 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
+#define MMC_RSP_SPI_R4 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
+#define MMC_RSP_SPI_R5 (MMC_RSP_SPI_S1|MMC_RSP_SPI_S2)
+#define MMC_RSP_SPI_R7 (MMC_RSP_SPI_S1|MMC_RSP_SPI_B4)
+
+#define mmc_spi_resp_type(cmd) ((cmd)->flags & \
+               (MMC_RSP_SPI_S1|MMC_RSP_SPI_BUSY|MMC_RSP_SPI_S2|MMC_RSP_SPI_B4))
+
 /*
  * These are the command types.
  */
@@ -54,12 +78,19 @@ struct mmc_command {
        unsigned int            retries;        /* max number of retries */
        unsigned int            error;          /* command error */
 
-#define MMC_ERR_NONE   0
-#define MMC_ERR_TIMEOUT        1
-#define MMC_ERR_BADCRC 2
-#define MMC_ERR_FIFO   3
-#define MMC_ERR_FAILED 4
-#define MMC_ERR_INVALID        5
+/*
+ * Standard errno values are used for errors, but some have specific
+ * meaning in the MMC layer:
+ *
+ * ETIMEDOUT    Card took too long to respond
+ * EILSEQ       Basic format problem with the received or sent data
+ *              (e.g. CRC check failed, incorrect opcode in response
+ *              or bad end bit)
+ * EINVAL       Request cannot be performed because of restrictions
+ *              in hardware and/or the driver
+ * ENOMEDIUM    Host can determine that the slot is empty and is
+ *              actively failing requests
+ */
 
        struct mmc_data         *data;          /* data segment associated with cmd */
        struct mmc_request      *mrq;           /* associated request */
@@ -76,7 +107,6 @@ struct mmc_data {
 #define MMC_DATA_WRITE (1 << 8)
 #define MMC_DATA_READ  (1 << 9)
 #define MMC_DATA_STREAM        (1 << 10)
-#define MMC_DATA_MULTI (1 << 11)
 
        unsigned int            bytes_xfered;
 
@@ -104,9 +134,20 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
 extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
        struct mmc_command *, int);
 
-extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *, int);
+extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *);
 
-extern void mmc_claim_host(struct mmc_host *host);
+extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort);
 extern void mmc_release_host(struct mmc_host *host);
 
+/**
+ *     mmc_claim_host - exclusively claim a host
+ *     @host: mmc host to claim
+ *
+ *     Claim a host for a set of operations.
+ */
+static inline void mmc_claim_host(struct mmc_host *host)
+{
+       __mmc_claim_host(host, NULL);
+}
+
 #endif
index b1350dfd3e9108751b9fadd15dd8f1e61b77da2d..125eee1407ff1c5ee34d2cce2984d0a6fc14c5f0 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef LINUX_MMC_HOST_H
 #define LINUX_MMC_HOST_H
 
+#include <linux/leds.h>
+
 #include <linux/mmc/core.h>
 
 struct mmc_ios {
@@ -51,6 +53,7 @@ struct mmc_host_ops {
        void    (*request)(struct mmc_host *host, struct mmc_request *req);
        void    (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
        int     (*get_ro)(struct mmc_host *host);
+       void    (*enable_sdio_irq)(struct mmc_host *host, int enable);
 };
 
 struct mmc_card;
@@ -87,9 +90,10 @@ struct mmc_host {
 
 #define MMC_CAP_4_BIT_DATA     (1 << 0)        /* Can the host do 4 bit transfers */
 #define MMC_CAP_MULTIWRITE     (1 << 1)        /* Can accurately report bytes sent to card on error */
-#define MMC_CAP_BYTEBLOCK      (1 << 2)        /* Can do non-log2 block sizes */
-#define MMC_CAP_MMC_HIGHSPEED  (1 << 3)        /* Can do MMC high-speed timing */
-#define MMC_CAP_SD_HIGHSPEED   (1 << 4)        /* Can do SD high-speed timing */
+#define MMC_CAP_MMC_HIGHSPEED  (1 << 2)        /* Can do MMC high-speed timing */
+#define MMC_CAP_SD_HIGHSPEED   (1 << 3)        /* Can do SD high-speed timing */
+#define MMC_CAP_SDIO_IRQ       (1 << 4)        /* Can signal pending SDIO IRQs */
+#define MMC_CAP_SPI            (1 << 5)        /* Talks only SPI protocols */
 
        /* host specific block data */
        unsigned int            max_seg_size;   /* see blk_queue_max_segment_size */
@@ -106,6 +110,14 @@ struct mmc_host {
        struct mmc_ios          ios;            /* current io bus settings */
        u32                     ocr;            /* the current OCR setting */
 
+       /* group bitfields together to minimize padding */
+       unsigned int            use_spi_crc:1;
+       unsigned int            claimed:1;      /* host exclusively claimed */
+       unsigned int            bus_dead:1;     /* bus has been released */
+#ifdef CONFIG_MMC_DEBUG
+       unsigned int            removed:1;      /* host is being removed */
+#endif
+
        unsigned int            mode;           /* current card mode of host */
 #define MMC_MODE_MMC           0
 #define MMC_MODE_SD            1
@@ -113,16 +125,19 @@ struct mmc_host {
        struct mmc_card         *card;          /* device attached to this host */
 
        wait_queue_head_t       wq;
-       unsigned int            claimed:1;      /* host exclusively claimed */
 
        struct delayed_work     detect;
-#ifdef CONFIG_MMC_DEBUG
-       unsigned int            removed:1;      /* host is being removed */
-#endif
 
        const struct mmc_bus_ops *bus_ops;      /* current bus driver */
        unsigned int            bus_refs;       /* reference counter */
-       unsigned int            bus_dead:1;     /* bus has been released */
+
+       unsigned int            sdio_irqs;
+       struct task_struct      *sdio_irq_thread;
+       atomic_t                sdio_irq_thread_abort;
+
+#ifdef CONFIG_LEDS_TRIGGERS
+       struct led_trigger      *led;           /* activity led */
+#endif
 
        unsigned long           private[0] ____cacheline_aligned;
 };
@@ -137,6 +152,8 @@ static inline void *mmc_priv(struct mmc_host *host)
        return (void *)host->private;
 }
 
+#define mmc_host_is_spi(host)  ((host)->caps & MMC_CAP_SPI)
+
 #define mmc_dev(x)     ((x)->parent)
 #define mmc_classdev(x)        (&(x)->class_dev)
 #define mmc_hostname(x)        ((x)->class_dev.bus_id)
@@ -147,5 +164,11 @@ extern int mmc_resume_host(struct mmc_host *);
 extern void mmc_detect_change(struct mmc_host *, unsigned long delay);
 extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
 
+static inline void mmc_signal_sdio_irq(struct mmc_host *host)
+{
+       host->ops->enable_sdio_irq(host, 0);
+       wake_up_process(host->sdio_irq_thread);
+}
+
 #endif
 
index e3ed9b95040ee51a4c5fac786b66736df2150b63..4236fbf0b6fbb831f4f617352e43ba3716d5188e 100644 (file)
@@ -27,7 +27,7 @@
 
 /* Standard MMC commands (4.1)           type  argument     response */
    /* class 1 */
-#define        MMC_GO_IDLE_STATE         0   /* bc                          */
+#define MMC_GO_IDLE_STATE         0   /* bc                          */
 #define MMC_SEND_OP_COND          1   /* bcr  [31:0] OCR         R3  */
 #define MMC_ALL_SEND_CID          2   /* bcr                     R2  */
 #define MMC_SET_RELATIVE_ADDR     3   /* ac   [31:16] RCA        R1  */
 #define MMC_SEND_CID             10   /* ac   [31:16] RCA        R2  */
 #define MMC_READ_DAT_UNTIL_STOP  11   /* adtc [31:0] dadr        R1  */
 #define MMC_STOP_TRANSMISSION    12   /* ac                      R1b */
-#define MMC_SEND_STATUS                 13   /* ac   [31:16] RCA        R1  */
+#define MMC_SEND_STATUS          13   /* ac   [31:16] RCA        R1  */
 #define MMC_GO_INACTIVE_STATE    15   /* ac   [31:16] RCA            */
+#define MMC_SPI_READ_OCR         58   /* spi                  spi_R3 */
+#define MMC_SPI_CRC_ON_OFF       59   /* spi  [0:0] flag      spi_R1 */
 
   /* class 2 */
 #define MMC_SET_BLOCKLEN         16   /* ac   [31:0] block len   R1  */
  */
 
 /*
-  MMC status in R1
+  MMC status in R1, for native mode (SPI bits are different)
   Type
-       e : error bit
+       e : error bit
        s : status bit
        r : detected and set for the actual command response
        x : detected and set during command execution. the host must poll
             the card by sending status command in order to read these bits.
   Clear condition
-       a : according to the card state
+       a : according to the card state
        b : always related to the previous command. Reception of
             a valid command will clear it (with a delay of one command)
        c : clear by read
 #define R1_CARD_ECC_DISABLED   (1 << 14)       /* sx, a */
 #define R1_ERASE_RESET         (1 << 13)       /* sr, c */
 #define R1_STATUS(x)            (x & 0xFFFFE000)
-#define R1_CURRENT_STATE(x)            ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
+#define R1_CURRENT_STATE(x)    ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
 #define R1_READY_FOR_DATA      (1 << 8)        /* sx, a */
 #define R1_APP_CMD             (1 << 5)        /* sr, c */
 
+/*
+ * MMC/SD in SPI mode reports R1 status always, and R2 for SEND_STATUS
+ * R1 is the low order byte; R2 is the next highest byte, when present.
+ */
+#define R1_SPI_IDLE            (1 << 0)
+#define R1_SPI_ERASE_RESET     (1 << 1)
+#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
+#define R1_SPI_COM_CRC         (1 << 3)
+#define R1_SPI_ERASE_SEQ       (1 << 4)
+#define R1_SPI_ADDRESS         (1 << 5)
+#define R1_SPI_PARAMETER       (1 << 6)
+/* R1 bit 7 is always zero */
+#define R2_SPI_CARD_LOCKED     (1 << 8)
+#define R2_SPI_WP_ERASE_SKIP   (1 << 9)        /* or lock/unlock fail */
+#define R2_SPI_LOCK_UNLOCK_FAIL        R2_SPI_WP_ERASE_SKIP
+#define R2_SPI_ERROR           (1 << 10)
+#define R2_SPI_CC_ERROR                (1 << 11)
+#define R2_SPI_CARD_ECC_ERROR  (1 << 12)
+#define R2_SPI_WP_VIOLATION    (1 << 13)
+#define R2_SPI_ERASE_PARAM     (1 << 14)
+#define R2_SPI_OUT_OF_RANGE    (1 << 15)       /* or CSD overwrite */
+#define R2_SPI_CSD_OVERWRITE   R2_SPI_OUT_OF_RANGE
+
 /* These are unpacked versions of the actual responses */
 
 struct _mmc_csd {
@@ -182,6 +207,7 @@ struct _mmc_csd {
  */
 #define CCC_BASIC              (1<<0)  /* (0) Basic protocol functions */
                                        /* (CMD0,1,2,3,4,7,9,10,12,13,15) */
+                                       /* (and for SPI, CMD58,59) */
 #define CCC_STREAM_READ                (1<<1)  /* (1) Stream read commands */
                                        /* (CMD11) */
 #define CCC_BLOCK_READ         (1<<2)  /* (2) Block read commands */
@@ -227,6 +253,7 @@ struct _mmc_csd {
 #define EXT_CSD_BUS_WIDTH      183     /* R/W */
 #define EXT_CSD_HS_TIMING      185     /* R/W */
 #define EXT_CSD_CARD_TYPE      196     /* RO */
+#define EXT_CSD_REV            192     /* RO */
 #define EXT_CSD_SEC_CNT                212     /* RO, 4 bytes */
 
 /*
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
new file mode 100644 (file)
index 0000000..47ba464
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ *  include/linux/mmc/sdio.h
+ *
+ *  Copyright 2006-2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef MMC_SDIO_H
+#define MMC_SDIO_H
+
+/* SDIO commands                         type  argument     response */
+#define SD_IO_SEND_OP_COND          5 /* bcr  [23:0] OCR         R4  */
+#define SD_IO_RW_DIRECT            52 /* ac   [31:0] See below   R5  */
+#define SD_IO_RW_EXTENDED          53 /* adtc [31:0] See below   R5  */
+
+/*
+ * SD_IO_RW_DIRECT argument format:
+ *
+ *      [31] R/W flag
+ *      [30:28] Function number
+ *      [27] RAW flag
+ *      [25:9] Register address
+ *      [7:0] Data
+ */
+
+/*
+ * SD_IO_RW_EXTENDED argument format:
+ *
+ *      [31] R/W flag
+ *      [30:28] Function number
+ *      [27] Block mode
+ *      [26] Increment address
+ *      [25:9] Register address
+ *      [8:0] Byte/block count
+ */
+
+/*
+  SDIO status in R5
+  Type
+       e : error bit
+       s : status bit
+       r : detected and set for the actual command response
+       x : detected and set during command execution. the host must poll
+            the card by sending status command in order to read these bits.
+  Clear condition
+       a : according to the card state
+       b : always related to the previous command. Reception of
+            a valid command will clear it (with a delay of one command)
+       c : clear by read
+ */
+
+#define R5_COM_CRC_ERROR       (1 << 15)       /* er, b */
+#define R5_ILLEGAL_COMMAND     (1 << 14)       /* er, b */
+#define R5_ERROR               (1 << 11)       /* erx, c */
+#define R5_FUNCTION_NUMBER     (1 << 9)        /* er, c */
+#define R5_OUT_OF_RANGE                (1 << 8)        /* er, c */
+#define R5_STATUS(x)           (x & 0xCB00)
+#define R5_IO_CURRENT_STATE(x) ((x & 0x3000) >> 12) /* s, b */
+
+/*
+ * Card Common Control Registers (CCCR)
+ */
+
+#define SDIO_CCCR_CCCR         0x00
+
+#define  SDIO_CCCR_REV_1_00    0       /* CCCR/FBR Version 1.00 */
+#define  SDIO_CCCR_REV_1_10    1       /* CCCR/FBR Version 1.10 */
+#define  SDIO_CCCR_REV_1_20    2       /* CCCR/FBR Version 1.20 */
+
+#define  SDIO_SDIO_REV_1_00    0       /* SDIO Spec Version 1.00 */
+#define  SDIO_SDIO_REV_1_10    1       /* SDIO Spec Version 1.10 */
+#define  SDIO_SDIO_REV_1_20    2       /* SDIO Spec Version 1.20 */
+#define  SDIO_SDIO_REV_2_00    3       /* SDIO Spec Version 2.00 */
+
+#define SDIO_CCCR_SD           0x01
+
+#define  SDIO_SD_REV_1_01      0       /* SD Physical Spec Version 1.01 */
+#define  SDIO_SD_REV_1_10      1       /* SD Physical Spec Version 1.10 */
+#define  SDIO_SD_REV_2_00      2       /* SD Physical Spec Version 2.00 */
+
+#define SDIO_CCCR_IOEx         0x02
+#define SDIO_CCCR_IORx         0x03
+
+#define SDIO_CCCR_IENx         0x04    /* Function/Master Interrupt Enable */
+#define SDIO_CCCR_INTx         0x05    /* Function Interrupt Pending */
+
+#define SDIO_CCCR_ABORT                0x06    /* function abort/card reset */
+
+#define SDIO_CCCR_IF           0x07    /* bus interface controls */
+
+#define  SDIO_BUS_WIDTH_1BIT   0x00
+#define  SDIO_BUS_WIDTH_4BIT   0x02
+
+#define  SDIO_BUS_CD_DISABLE     0x80  /* disable pull-up on DAT3 (pin 1) */
+
+#define SDIO_CCCR_CAPS         0x08
+
+#define  SDIO_CCCR_CAP_SDC     0x01    /* can do CMD52 while data transfer */
+#define  SDIO_CCCR_CAP_SMB     0x02    /* can do multi-block xfers (CMD53) */
+#define  SDIO_CCCR_CAP_SRW     0x04    /* supports read-wait protocol */
+#define  SDIO_CCCR_CAP_SBS     0x08    /* supports suspend/resume */
+#define  SDIO_CCCR_CAP_S4MI    0x10    /* interrupt during 4-bit CMD53 */
+#define  SDIO_CCCR_CAP_E4MI    0x20    /* enable ints during 4-bit CMD53 */
+#define  SDIO_CCCR_CAP_LSC     0x40    /* low speed card */
+#define  SDIO_CCCR_CAP_4BLS    0x80    /* 4 bit low speed card */
+
+#define SDIO_CCCR_CIS          0x09    /* common CIS pointer (3 bytes) */
+
+/* Following 4 regs are valid only if SBS is set */
+#define SDIO_CCCR_SUSPEND      0x0c
+#define SDIO_CCCR_SELx         0x0d
+#define SDIO_CCCR_EXECx                0x0e
+#define SDIO_CCCR_READYx       0x0f
+
+#define SDIO_CCCR_BLKSIZE      0x10
+
+#define SDIO_CCCR_POWER                0x12
+
+#define  SDIO_POWER_SMPC       0x01    /* Supports Master Power Control */
+#define  SDIO_POWER_EMPC       0x02    /* Enable Master Power Control */
+
+#define SDIO_CCCR_SPEED                0x13
+
+#define  SDIO_SPEED_SHS                0x01    /* Supports High-Speed mode */
+#define  SDIO_SPEED_EHS                0x02    /* Enable High-Speed mode */
+
+/*
+ * Function Basic Registers (FBR)
+ */
+
+#define SDIO_FBR_BASE(f)       ((f) * 0x100) /* base of function f's FBRs */
+
+#define SDIO_FBR_STD_IF                0x00
+
+#define  SDIO_FBR_SUPPORTS_CSA 0x40    /* supports Code Storage Area */
+#define  SDIO_FBR_ENABLE_CSA   0x80    /* enable Code Storage Area */
+
+#define SDIO_FBR_STD_IF_EXT    0x01
+
+#define SDIO_FBR_POWER         0x02
+
+#define  SDIO_FBR_POWER_SPS    0x01    /* Supports Power Selection */
+#define  SDIO_FBR_POWER_EPS    0x02    /* Enable (low) Power Selection */
+
+#define SDIO_FBR_CIS           0x09    /* CIS pointer (3 bytes) */
+
+
+#define SDIO_FBR_CSA           0x0C    /* CSA pointer (3 bytes) */
+
+#define SDIO_FBR_CSA_DATA      0x0F
+
+#define SDIO_FBR_BLKSIZE       0x10    /* block size (2 bytes) */
+
+#endif
+
diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
new file mode 100644 (file)
index 0000000..b050f4d
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ *  include/linux/mmc/sdio_func.h
+ *
+ *  Copyright 2007 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef MMC_SDIO_FUNC_H
+#define MMC_SDIO_FUNC_H
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+
+struct mmc_card;
+struct sdio_func;
+
+typedef void (sdio_irq_handler_t)(struct sdio_func *);
+
+/*
+ * SDIO function CIS tuple (unknown to the core)
+ */
+struct sdio_func_tuple {
+       struct sdio_func_tuple *next;
+       unsigned char code;
+       unsigned char size;
+       unsigned char data[0];
+};
+
+/*
+ * SDIO function devices
+ */
+struct sdio_func {
+       struct mmc_card         *card;          /* the card this device belongs to */
+       struct device           dev;            /* the device */
+       sdio_irq_handler_t      *irq_handler;   /* IRQ callback */
+       unsigned int            num;            /* function number */
+
+       unsigned char           class;          /* standard interface class */
+       unsigned short          vendor;         /* vendor id */
+       unsigned short          device;         /* device id */
+
+       unsigned                max_blksize;    /* maximum block size */
+       unsigned                cur_blksize;    /* current block size */
+
+       unsigned int            state;          /* function state */
+#define SDIO_STATE_PRESENT     (1<<0)          /* present in sysfs */
+
+       u8                      tmpbuf[4];      /* DMA:able scratch buffer */
+
+       unsigned                num_info;       /* number of info strings */
+       const char              **info;         /* info strings */
+
+       struct sdio_func_tuple *tuples;
+};
+
+#define sdio_func_present(f)   ((f)->state & SDIO_STATE_PRESENT)
+
+#define sdio_func_set_present(f) ((f)->state |= SDIO_STATE_PRESENT)
+
+#define sdio_func_id(f)                ((f)->dev.bus_id)
+
+#define sdio_get_drvdata(f)    dev_get_drvdata(&(f)->dev)
+#define sdio_set_drvdata(f,d)  dev_set_drvdata(&(f)->dev, d)
+
+/*
+ * SDIO function device driver
+ */
+struct sdio_driver {
+       char *name;
+       const struct sdio_device_id *id_table;
+
+       int (*probe)(struct sdio_func *, const struct sdio_device_id *);
+       void (*remove)(struct sdio_func *);
+
+       struct device_driver drv;
+};
+
+/**
+ * SDIO_DEVICE - macro used to describe a specific SDIO device
+ * @vend: the 16 bit manufacturer code
+ * @dev: the 16 bit function id
+ *
+ * This macro is used to create a struct sdio_device_id that matches a
+ * specific device. The class field will be set to SDIO_ANY_ID.
+ */
+#define SDIO_DEVICE(vend,dev) \
+       .class = SDIO_ANY_ID, \
+       .vendor = (vend), .device = (dev)
+
+/**
+ * SDIO_DEVICE_CLASS - macro used to describe a specific SDIO device class
+ * @dev_class: the 8 bit standard interface code
+ *
+ * This macro is used to create a struct sdio_device_id that matches a
+ * specific standard SDIO function type.  The vendor and device fields will
+ * be set to SDIO_ANY_ID.
+ */
+#define SDIO_DEVICE_CLASS(dev_class) \
+       .class = (dev_class), \
+       .vendor = SDIO_ANY_ID, .device = SDIO_ANY_ID
+
+extern int sdio_register_driver(struct sdio_driver *);
+extern void sdio_unregister_driver(struct sdio_driver *);
+
+/*
+ * SDIO I/O operations
+ */
+extern void sdio_claim_host(struct sdio_func *func);
+extern void sdio_release_host(struct sdio_func *func);
+
+extern int sdio_enable_func(struct sdio_func *func);
+extern int sdio_disable_func(struct sdio_func *func);
+
+extern int sdio_set_block_size(struct sdio_func *func, unsigned blksz);
+
+extern int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler);
+extern int sdio_release_irq(struct sdio_func *func);
+
+extern unsigned char sdio_readb(struct sdio_func *func,
+       unsigned int addr, int *err_ret);
+extern unsigned short sdio_readw(struct sdio_func *func,
+       unsigned int addr, int *err_ret);
+extern unsigned long sdio_readl(struct sdio_func *func,
+       unsigned int addr, int *err_ret);
+
+extern int sdio_memcpy_fromio(struct sdio_func *func, void *dst,
+       unsigned int addr, int count);
+extern int sdio_readsb(struct sdio_func *func, void *dst,
+       unsigned int addr, int count);
+
+extern void sdio_writeb(struct sdio_func *func, unsigned char b,
+       unsigned int addr, int *err_ret);
+extern void sdio_writew(struct sdio_func *func, unsigned short b,
+       unsigned int addr, int *err_ret);
+extern void sdio_writel(struct sdio_func *func, unsigned long b,
+       unsigned int addr, int *err_ret);
+
+extern int sdio_memcpy_toio(struct sdio_func *func, unsigned int addr,
+       void *src, int count);
+extern int sdio_writesb(struct sdio_func *func, unsigned int addr,
+       void *src, int count);
+
+extern unsigned char sdio_f0_readb(struct sdio_func *func,
+       unsigned int addr, int *err_ret);
+extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b,
+       unsigned int addr, int *err_ret);
+
+#endif
+
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
new file mode 100644 (file)
index 0000000..09306d4
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * SDIO Classes, Interface Types, Manufacturer IDs, etc.
+ */
+
+#ifndef MMC_SDIO_IDS_H
+#define MMC_SDIO_IDS_H
+
+/*
+ * Standard SDIO Function Interfaces
+ */
+
+#define SDIO_CLASS_NONE                0x00    /* Not a SDIO standard interface */
+#define SDIO_CLASS_UART                0x01    /* standard UART interface */
+#define SDIO_CLASS_BT_A                0x02    /* Type-A BlueTooth std interface */
+#define SDIO_CLASS_BT_B                0x03    /* Type-B BlueTooth std interface */
+#define SDIO_CLASS_GPS         0x04    /* GPS standard interface */
+#define SDIO_CLASS_CAMERA      0x05    /* Camera standard interface */
+#define SDIO_CLASS_PHS         0x06    /* PHS standard interface */
+#define SDIO_CLASS_WLAN                0x07    /* WLAN interface */
+#define SDIO_CLASS_ATA         0x08    /* Embedded SDIO-ATA std interface */
+
+
+#endif
index 4dc5fa8be781760aa307cff8d01488f270c47b9a..e47e5951058be53593f68e9c8d955418a0e82ccf 100644 (file)
@@ -340,4 +340,15 @@ struct parisc_device_id {
 #define PA_HVERSION_ANY_ID     0xffff
 #define PA_SVERSION_ANY_ID     0xffffffff
 
+/* SDIO */
+
+#define SDIO_ANY_ID (~0)
+
+struct sdio_device_id {
+       __u8    class;                  /* Standard interface or SDIO_ANY_ID */
+       __u16   vendor;                 /* Vendor or SDIO_ANY_ID */
+       __u16   device;                 /* Device ID or SDIO_ANY_ID */
+       kernel_ulong_t driver_data;     /* Data private to the driver */
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
index 506b9ae241fd4b034998e553ac3237e1ef736adf..cfee06bca2d3e615c7bfcc6c2b3d6d670f666496 100644 (file)
 #define PCI_DEVICE_ID_RICOH_RL5C476    0x0476
 #define PCI_DEVICE_ID_RICOH_RL5C478    0x0478
 #define PCI_DEVICE_ID_RICOH_R5C822     0x0822
+#define PCI_DEVICE_ID_RICOH_R5C832     0x0832
+#define PCI_DEVICE_ID_RICOH_R5C843     0x0843
 
 #define PCI_VENDOR_ID_DLINK            0x1186
 #define PCI_DEVICE_ID_DLINK_DGE510T    0x4c00
diff --git a/include/linux/spi/mmc_spi.h b/include/linux/spi/mmc_spi.h
new file mode 100644 (file)
index 0000000..e9bbe3e
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __LINUX_SPI_MMC_SPI_H
+#define __LINUX_SPI_MMC_SPI_H
+
+struct device;
+struct mmc_host;
+
+/* Put this in platform_data of a device being used to manage an MMC/SD
+ * card slot.  (Modeled after PXA mmc glue; see that for usage examples.)
+ *
+ * REVISIT This is not a spi-specific notion.  Any card slot should be
+ * able to handle it.  If the MMC core doesn't adopt this kind of notion,
+ * switch the "struct device *" parameters over to "struct spi_device *".
+ */
+struct mmc_spi_platform_data {
+       /* driver activation and (optional) card detect irq hookup */
+       int (*init)(struct device *,
+               irqreturn_t (*)(int, void *),
+               void *);
+       void (*exit)(struct device *, void *);
+
+       /* sense switch on sd cards */
+       int (*get_ro)(struct device *);
+
+       /* how long to debounce card detect, in msecs */
+       u16 detect_delay;
+
+       /* power management */
+       u16 powerup_msecs;              /* delay of up to 250 msec */
+       u32 ocr_mask;                   /* available voltages */
+       void (*setpower)(struct device *, unsigned int maskval);
+};
+
+#endif /* __LINUX_SPI_MMC_SPI_H */
index ae9b24c12f6a36b43ce0868255d38b9ad7228cbd..1f503e94eff1491f6a9d98bc92a3e970c226d00f 100644 (file)
@@ -271,6 +271,7 @@ struct v4l2_pix_format
 
 /*      Pixel format         FOURCC                        depth  Description  */
 #define V4L2_PIX_FMT_RGB332  v4l2_fourcc('R','G','B','1') /*  8  RGB-3-3-2     */
+#define V4L2_PIX_FMT_RGB444  v4l2_fourcc('R','4','4','4') /* 16  xxxxrrrr ggggbbbb */
 #define V4L2_PIX_FMT_RGB555  v4l2_fourcc('R','G','B','O') /* 16  RGB-5-5-5     */
 #define V4L2_PIX_FMT_RGB565  v4l2_fourcc('R','G','B','P') /* 16  RGB-5-6-5     */
 #define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16  RGB-5-5-5 BE  */
@@ -280,6 +281,7 @@ struct v4l2_pix_format
 #define V4L2_PIX_FMT_BGR32   v4l2_fourcc('B','G','R','4') /* 32  BGR-8-8-8-8   */
 #define V4L2_PIX_FMT_RGB32   v4l2_fourcc('R','G','B','4') /* 32  RGB-8-8-8-8   */
 #define V4L2_PIX_FMT_GREY    v4l2_fourcc('G','R','E','Y') /*  8  Greyscale     */
+#define V4L2_PIX_FMT_PAL8    v4l2_fourcc('P','A','L','8') /*  8  8-bit palette */
 #define V4L2_PIX_FMT_YVU410  v4l2_fourcc('Y','V','U','9') /*  9  YVU 4:1:0     */
 #define V4L2_PIX_FMT_YVU420  v4l2_fourcc('Y','V','1','2') /* 12  YVU 4:2:0     */
 #define V4L2_PIX_FMT_YUYV    v4l2_fourcc('Y','U','Y','V') /* 16  YUV 4:2:2     */
@@ -287,6 +289,10 @@ struct v4l2_pix_format
 #define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16  YVU422 planar */
 #define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16  YVU411 planar */
 #define V4L2_PIX_FMT_Y41P    v4l2_fourcc('Y','4','1','P') /* 12  YUV 4:1:1     */
+#define V4L2_PIX_FMT_YUV444  v4l2_fourcc('Y','4','4','4') /* 16  xxxxyyyy uuuuvvvv */
+#define V4L2_PIX_FMT_YUV555  v4l2_fourcc('Y','U','V','O') /* 16  YUV-5-5-5     */
+#define V4L2_PIX_FMT_YUV565  v4l2_fourcc('Y','U','V','P') /* 16  YUV-5-6-5     */
+#define V4L2_PIX_FMT_YUV32   v4l2_fourcc('Y','U','V','4') /* 32  YUV-8-8-8-8   */
 
 /* two planes -- one Y, one Cr + Cb interleaved  */
 #define V4L2_PIX_FMT_NV12    v4l2_fourcc('N','V','1','2') /* 12  Y/CbCr 4:2:0  */
@@ -298,7 +304,6 @@ struct v4l2_pix_format
 #define V4L2_PIX_FMT_YYUV    v4l2_fourcc('Y','Y','U','V') /* 16  YUV 4:2:2     */
 #define V4L2_PIX_FMT_HI240   v4l2_fourcc('H','I','2','4') /*  8  8-bit color   */
 #define V4L2_PIX_FMT_HM12    v4l2_fourcc('H','M','1','2') /*  8  YUV 4:2:0 16x16 macroblocks */
-#define V4L2_PIX_FMT_RGB444  v4l2_fourcc('R','4','4','4') /* 16  xxxxrrrr ggggbbbb */
 
 /* see http://www.siliconimaging.com/RGB%20Bayer.htm */
 #define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B','A','8','1') /*  8  BGBG.. GRGR.. */
index 38c12fed753580573852bf9648b2f2b22ec9d542..af8071d7620d1e3405e342a16b2aba9851aa62cb 100644 (file)
@@ -91,7 +91,7 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func,
 int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params,
                struct v4l2_queryctrl *qctrl);
 const char **cx2341x_ctrl_get_menu(u32 id);
-int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params,
+int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
                struct v4l2_ext_controls *ctrls, unsigned int cmd);
 void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p);
 void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix);
index 9807a7c158300253df641b92af06afc7680fe551..7a785fa7721262aad3816fef70be06f4cfb46b1a 100644 (file)
@@ -140,6 +140,7 @@ extern IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_asus_pc39[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE];
 
 #endif
 
index 67703249b2454b4adb54ed2731bfdd07a63e6462..cd3ff2c29d5e04828dc6a7d5ddb1da5f7f83fe4c 100644 (file)
@@ -146,7 +146,6 @@ struct saa7146_dev
 
 /* from saa7146_i2c.c */
 int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate);
-int saa7146_i2c_transfer(struct saa7146_dev *saa, const struct i2c_msg *msgs, int num, int retries);
 
 /* from saa7146_core.c */
 extern struct list_head saa7146_devices;
index cce20ed5cf6c221ab61360f05436fd399067d698..e49f7e156061c8dd699060a5b6c1e3edd4c3c268 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/videodev.h>
 #include <media/v4l2-common.h>
 #include <media/saa7146.h>
-#include <media/video-buf.h>
+#include <media/videobuf-dma-sg.h>
 
 #define MAX_SAA7146_CAPTURE_BUFFERS    32      /* arbitrary */
 #define BUFFER_TIMEOUT     (HZ/2)  /* 0.5 seconds */
index e5ad3fcfe9845d1ba8a37babcd3871461a141f29..b201371416a0c793473b1fdd96dc9885f06746d5 100644 (file)
@@ -79,6 +79,10 @@ struct tuner_params {
        /* Select 18% (or according to datasheet 0%) L standard PLL gating,
           vs the driver default of 36%. */
        unsigned int default_pll_gating_18:1;
+       /* IF to use in radio mode.  Tuners with a separate radio IF filter
+          seem to use 10.7, while those without use 33.3 for PAL/SECAM tuners
+          and 41.3 for NTSC tuners. 0 = 10.7, 1 = 33.3, 2 = 41.3 */
+       unsigned int radio_if:2;
        /* Default tda9887 TOP value in dB for the low band. Default is 0.
           Range: -16:+15 */
        signed int default_top_low:5;
index 160381c72e4bcdf5c930d0fa9f3db60f3cde86af..c03dceb926051695afbaba9499ce50e56a7c3699 100644 (file)
@@ -146,6 +146,7 @@ extern int tuner_debug;
 #define TDA9887_AUTOMUTE               (1<<18)
 #define TDA9887_GATING_18              (1<<19)
 #define TDA9887_GAIN_NORMAL            (1<<20)
+#define TDA9887_RIF_41_3               (1<<21)  /* radio IF1 41.3 vs 33.3 */
 
 #ifdef __KERNEL__
 
index 09d16c4f00f7a55ecb6bb37bb0fdf034643209ac..8ae42c41dd08d5bb351f3958491f7a442b1659df 100644 (file)
@@ -65,6 +65,9 @@ enum {
        V4L2_IDENT_CX23415 = 415,
        V4L2_IDENT_CX23416 = 416,
 
+       /* module vp27smpx: just ident 2700 */
+       V4L2_IDENT_VP27SMPX = 2700,
+
        /* module wm8739: just ident 8739 */
        V4L2_IDENT_WM8739 = 8739,
 
index 17f8f3a2f0a3e4214120d63b9047356eefa459a4..e75d5e6c4cea083ed8429b1fe1adaa09d6e63cd9 100644 (file)
@@ -23,8 +23,6 @@
 #include <linux/videodev2.h>
 #endif
 
-#include <linux/fs.h>
-
 #define VIDEO_MAJOR    81
 /* Minor device allocation */
 #define MINOR_VFL_TYPE_GRABBER_MIN   0
@@ -88,8 +86,11 @@ struct video_device
        /* device ops */
        const struct file_operations *fops;
 
+       /* sysfs */
+       struct device class_dev;        /* v4l device */
+       struct device *dev;             /* device parent */
+
        /* device info */
-       struct device *dev;
        char name[32];
        int type;       /* v4l1 */
        int type2;      /* v4l2 */
@@ -334,7 +335,6 @@ void *priv;
        /* for videodev.c intenal usage -- please don't touch */
        int users;                     /* video_exclusive_{open|close} ... */
        struct mutex lock;             /* ... helper function uses these   */
-       struct class_device class_dev; /* sysfs */
 };
 
 /* Class-dev to video-device */
@@ -362,18 +362,18 @@ extern int video_usercopy(struct inode *inode, struct file *file,
 
 static inline int __must_check
 video_device_create_file(struct video_device *vfd,
-                        struct class_device_attribute *attr)
+                        struct device_attribute *attr)
 {
-       int ret = class_device_create_file(&vfd->class_dev, attr);
+       int ret = device_create_file(&vfd->class_dev, attr);
        if (ret < 0)
                printk(KERN_WARNING "%s error: %d\n", __FUNCTION__, ret);
        return ret;
 }
 static inline void
 video_device_remove_file(struct video_device *vfd,
-                        struct class_device_attribute *attr)
+                        struct device_attribute *attr)
 {
-       class_device_remove_file(&vfd->class_dev, attr);
+       device_remove_file(&vfd->class_dev, attr);
 }
 
 #endif /* CONFIG_VIDEO_V4L1_COMPAT */
diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h
new file mode 100644 (file)
index 0000000..066ebfc
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * include/media/v4l2-int-device.h
+ *
+ * V4L2 internal ioctl interface.
+ *
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * Contact: Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef V4L2_INT_DEVICE_H
+#define V4L2_INT_DEVICE_H
+
+#include <linux/module.h>
+#include <media/v4l2-common.h>
+
+#define V4L2NAMESIZE 32
+
+/*
+ *
+ * The internal V4L2 device interface core.
+ *
+ */
+
+enum v4l2_int_type {
+       v4l2_int_type_master = 1,
+       v4l2_int_type_slave
+};
+
+struct v4l2_int_device;
+
+struct v4l2_int_master {
+       int (*attach)(struct v4l2_int_device *master,
+                     struct v4l2_int_device *slave);
+       void (*detach)(struct v4l2_int_device *master);
+};
+
+typedef int (v4l2_int_ioctl_func)(struct v4l2_int_device *);
+typedef int (v4l2_int_ioctl_func_0)(struct v4l2_int_device *);
+typedef int (v4l2_int_ioctl_func_1)(struct v4l2_int_device *, void *);
+
+struct v4l2_int_ioctl_desc {
+       int num;
+       v4l2_int_ioctl_func *func;
+};
+
+struct v4l2_int_slave {
+       /* Don't touch master. */
+       struct v4l2_int_device *master;
+
+       char attach_to[V4L2NAMESIZE];
+
+       int num_ioctls;
+       struct v4l2_int_ioctl_desc *ioctls;
+};
+
+struct v4l2_int_device {
+       /* Don't touch head. */
+       struct list_head head;
+
+       struct module *module;
+
+       char name[V4L2NAMESIZE];
+
+       enum v4l2_int_type type;
+       union {
+               struct v4l2_int_master *master;
+               struct v4l2_int_slave *slave;
+       } u;
+
+       void *priv;
+};
+
+int v4l2_int_device_register(struct v4l2_int_device *d);
+void v4l2_int_device_unregister(struct v4l2_int_device *d);
+
+int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd);
+int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg);
+
+/*
+ *
+ * Types and definitions for IOCTL commands.
+ *
+ */
+
+/* Slave interface type. */
+enum v4l2_if_type {
+       /*
+        * Parallel 8-, 10- or 12-bit interface, used by for example
+        * on certain image sensors.
+        */
+       V4L2_IF_TYPE_BT656,
+};
+
+enum v4l2_if_type_bt656_mode {
+       /*
+        * Modes without Bt synchronisation codes. Separate
+        * synchronisation signal lines are used.
+        */
+       V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT,
+       V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT,
+       V4L2_IF_TYPE_BT656_MODE_NOBT_12BIT,
+       /*
+        * Use Bt synchronisation codes. The vertical and horizontal
+        * synchronisation is done based on synchronisation codes.
+        */
+       V4L2_IF_TYPE_BT656_MODE_BT_8BIT,
+       V4L2_IF_TYPE_BT656_MODE_BT_10BIT,
+};
+
+struct v4l2_if_type_bt656 {
+       /*
+        * 0: Frame begins when vsync is high.
+        * 1: Frame begins when vsync changes from low to high.
+        */
+       unsigned frame_start_on_rising_vs:1;
+       /* Use Bt synchronisation codes for sync correction. */
+       unsigned bt_sync_correct:1;
+       /* Swap every two adjacent image data elements. */
+       unsigned swap:1;
+       /* Inverted latch clock polarity from slave. */
+       unsigned latch_clk_inv:1;
+       /* Hs polarity. 0 is active high, 1 active low. */
+       unsigned nobt_hs_inv:1;
+       /* Vs polarity. 0 is active high, 1 active low. */
+       unsigned nobt_vs_inv:1;
+       enum v4l2_if_type_bt656_mode mode;
+       /* Minimum accepted bus clock for slave (in Hz). */
+       u32 clock_min;
+       /* Maximum accepted bus clock for slave. */
+       u32 clock_max;
+       /*
+        * Current wish of the slave. May only change in response to
+        * ioctls that affect image capture.
+        */
+       u32 clock_curr;
+};
+
+struct v4l2_ifparm {
+       enum v4l2_if_type if_type;
+       union {
+               struct v4l2_if_type_bt656 bt656;
+       } u;
+};
+
+/* IOCTL command numbers. */
+enum v4l2_int_ioctl_num {
+       /*
+        *
+        * "Proper" V4L ioctls, as in struct video_device.
+        *
+        */
+       vidioc_int_enum_fmt_cap_num = 1,
+       vidioc_int_g_fmt_cap_num,
+       vidioc_int_s_fmt_cap_num,
+       vidioc_int_try_fmt_cap_num,
+       vidioc_int_queryctrl_num,
+       vidioc_int_g_ctrl_num,
+       vidioc_int_s_ctrl_num,
+       vidioc_int_g_parm_num,
+       vidioc_int_s_parm_num,
+
+       /*
+        *
+        * Strictly internal ioctls.
+        *
+        */
+       /* Initialise the device when slave attaches to the master. */
+       vidioc_int_dev_init_num = 1000,
+       /* Delinitialise the device at slave detach. */
+       vidioc_int_dev_exit_num,
+       /* Set device power state: 0 is off, non-zero is on. */
+       vidioc_int_s_power_num,
+       /* Get slave interface parameters. */
+       vidioc_int_g_ifparm_num,
+       /* Does the slave need to be reset after VIDIOC_DQBUF? */
+       vidioc_int_g_needs_reset_num,
+
+       /*
+        *
+        * VIDIOC_INT_* ioctls.
+        *
+        */
+       /* VIDIOC_INT_RESET */
+       vidioc_int_reset_num,
+       /* VIDIOC_INT_INIT */
+       vidioc_int_init_num,
+       /* VIDIOC_INT_G_CHIP_IDENT */
+       vidioc_int_g_chip_ident_num,
+
+       /*
+        *
+        * Start of private ioctls.
+        *
+        */
+       vidioc_int_priv_start_num = 2000,
+};
+
+/*
+ *
+ * IOCTL wrapper functions for better type checking.
+ *
+ */
+
+#define V4L2_INT_WRAPPER_0(name)                                       \
+       static inline int vidioc_int_##name(struct v4l2_int_device *d)  \
+       {                                                               \
+               return v4l2_int_ioctl_0(d, vidioc_int_##name##_num);    \
+       }                                                               \
+                                                                       \
+       static inline struct v4l2_int_ioctl_desc                        \
+       vidioc_int_##name##_cb(int (*func)                              \
+                              (struct v4l2_int_device *))              \
+       {                                                               \
+               struct v4l2_int_ioctl_desc desc;                        \
+                                                                       \
+               desc.num = vidioc_int_##name##_num;                     \
+               desc.func = (v4l2_int_ioctl_func *)func;                \
+                                                                       \
+               return desc;                                            \
+       }
+
+#define V4L2_INT_WRAPPER_1(name, arg_type, asterisk)                   \
+       static inline int vidioc_int_##name(struct v4l2_int_device *d,  \
+                                           arg_type asterisk arg)      \
+       {                                                               \
+               return v4l2_int_ioctl_1(d, vidioc_int_##name##_num,     \
+                                       (void *)(unsigned long)arg);    \
+       }                                                               \
+                                                                       \
+       static inline struct v4l2_int_ioctl_desc                        \
+       vidioc_int_##name##_cb(int (*func)                              \
+                              (struct v4l2_int_device *,               \
+                               arg_type asterisk))                     \
+       {                                                               \
+               struct v4l2_int_ioctl_desc desc;                        \
+                                                                       \
+               desc.num = vidioc_int_##name##_num;                     \
+               desc.func = (v4l2_int_ioctl_func *)func;                \
+                                                                       \
+               return desc;                                            \
+       }
+
+V4L2_INT_WRAPPER_1(enum_fmt_cap, struct v4l2_fmtdesc, *);
+V4L2_INT_WRAPPER_1(g_fmt_cap, struct v4l2_format, *);
+V4L2_INT_WRAPPER_1(s_fmt_cap, struct v4l2_format, *);
+V4L2_INT_WRAPPER_1(try_fmt_cap, struct v4l2_format, *);
+V4L2_INT_WRAPPER_1(queryctrl, struct v4l2_queryctrl, *);
+V4L2_INT_WRAPPER_1(g_ctrl, struct v4l2_control, *);
+V4L2_INT_WRAPPER_1(s_ctrl, struct v4l2_control, *);
+V4L2_INT_WRAPPER_1(g_parm, struct v4l2_streamparm, *);
+V4L2_INT_WRAPPER_1(s_parm, struct v4l2_streamparm, *);
+
+V4L2_INT_WRAPPER_0(dev_init);
+V4L2_INT_WRAPPER_0(dev_exit);
+V4L2_INT_WRAPPER_1(s_power, int, );
+V4L2_INT_WRAPPER_1(g_ifparm, struct v4l2_ifparm, *);
+V4L2_INT_WRAPPER_1(g_needs_reset, void, *);
+
+V4L2_INT_WRAPPER_0(reset);
+V4L2_INT_WRAPPER_0(init);
+V4L2_INT_WRAPPER_1(g_chip_ident, int, *);
+
+#endif
similarity index 56%
rename from include/media/video-buf.h
rename to include/media/videobuf-core.h
index d6f079476db34dc7b020177205b04a53a483deb1..9fa09fb800a11d07c3913d319ac7a176a7ac8c28 100644 (file)
 /*
+ * generic helper functions for handling video4linux capture buffers
  *
- * generic helper functions for video4linux capture buffers, to handle
- * memory management and PCI DMA.
- * Right now, bttv, saa7134, saa7146 and cx88 use it.
- *
- * The functions expect the hardware being able to scatter gatter
- * (i.e. the buffers are not linear in physical memory, but fragmented
- * into PAGE_SIZE chunks).  They also assume the driver does not need
- * to touch the video data.
- *
- * device specific map/unmap/sync stuff now are mapped as file operations
- * to allow its usage by USB and virtual devices.
+ * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
  *
+ * Highly based on video-buf written originally by:
  * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
  * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org>
  * (c) 2006 Ted Walther and John Sokol
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation; either version 2
  */
 
-#include <linux/videodev2.h>
 #include <linux/poll.h>
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+#include <linux/videodev.h>
+#endif
+#include <linux/videodev2.h>
 
 #define UNSET (-1U)
 
-/* --------------------------------------------------------------------- */
-
-/*
- * Return a scatterlist for some page-aligned vmalloc()'ed memory
- * block (NULL on errors).  Memory for the scatterlist is allocated
- * using kmalloc.  The caller must free the memory.
- */
-struct scatterlist* videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages);
-
-/*
- * Return a scatterlist for a an array of userpages (NULL on errors).
- * Memory for the scatterlist is allocated using kmalloc.  The caller
- * must free the memory.
- */
-struct scatterlist* videobuf_pages_to_sg(struct page **pages, int nr_pages,
-                                        int offset);
 
 struct videobuf_buffer;
 struct videobuf_queue;
 
 /* --------------------------------------------------------------------- */
 
-/*
- * A small set of helper functions to manage buffers (both userland
- * and kernel) for DMA.
- *
- * videobuf_dma_init_*()
- *     creates a buffer.  The userland version takes a userspace
- *     pointer + length.  The kernel version just wants the size and
- *     does memory allocation too using vmalloc_32().
- *
- * videobuf_dma_*()
- *     see Documentation/DMA-mapping.txt, these functions to
- *     basically the same.  The map function does also build a
- *     scatterlist for the buffer (and unmap frees it ...)
- *
- * videobuf_dma_free()
- *     no comment ...
- *
- */
-
-struct videobuf_dmabuf {
-       u32                 magic;
-
-       /* for userland buffer */
-       int                 offset;
-       struct page         **pages;
-
-       /* for kernel buffers */
-       void                *vmalloc;
-
-       /* Stores the userspace pointer to vmalloc area */
-       void                *varea;
-
-       /* for overlay buffers (pci-pci dma) */
-       dma_addr_t          bus_addr;
-
-       /* common */
-       struct scatterlist  *sglist;
-       int                 sglen;
-       int                 nr_pages;
-       int                 direction;
-};
-
-void videobuf_dma_init(struct videobuf_dmabuf *dma);
-int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
-                          unsigned long data, unsigned long size);
-int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
-                            int nr_pages);
-int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
-                             dma_addr_t addr, int nr_pages);
-int videobuf_dma_free(struct videobuf_dmabuf *dma);
-
-int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma);
-int videobuf_dma_sync(struct videobuf_queue* q,struct videobuf_dmabuf *dma);
-int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma);
-
-       /*FIXME: these variants are used only on *-alsa code, where videobuf is
-        * used without queue
-        */
-int videobuf_pci_dma_map(struct pci_dev *pci,struct videobuf_dmabuf *dma);
-int videobuf_pci_dma_unmap(struct pci_dev *pci,struct videobuf_dmabuf *dma);
-
-/* --------------------------------------------------------------------- */
-
 /*
  * A small set of helper functions to manage video4linux buffers.
  *
@@ -162,26 +77,33 @@ struct videobuf_buffer {
        unsigned int            input;
        enum v4l2_field         field;
        enum videobuf_state     state;
-       struct videobuf_dmabuf  dma;
        struct list_head        stream;  /* QBUF/DQBUF list */
 
-       /* for mmap'ed buffers */
-       enum v4l2_memory        memory;
-       size_t                  boff;    /* buffer offset (mmap + overlay) */
-       size_t                  bsize;   /* buffer size */
-       unsigned long           baddr;   /* buffer addr (userland ptr!) */
-       struct videobuf_mapping *map;
-
        /* touched by irq handler */
        struct list_head        queue;
        wait_queue_head_t       done;
        unsigned int            field_count;
        struct timeval          ts;
-};
 
-typedef int (vb_map_sg_t)(void *dev,struct scatterlist *sglist,int nr_pages,
-                                       int direction);
+       /* Memory type */
+       enum v4l2_memory        memory;
+
+       /* buffer size */
+       size_t                  bsize;
+
+       /* buffer offset (mmap + overlay) */
+       size_t                  boff;
 
+       /* buffer addr (userland ptr!) */
+       unsigned long           baddr;
+
+       /* for mmap'ed buffers */
+       struct videobuf_mapping *map;
+
+       /* Private pointer to allow specific methods to store their data */
+       int                     privsize;
+       void                    *priv;
+};
 
 struct videobuf_queue_ops {
        int (*buf_setup)(struct videobuf_queue *q,
@@ -193,14 +115,37 @@ struct videobuf_queue_ops {
                          struct videobuf_buffer *vb);
        void (*buf_release)(struct videobuf_queue *q,
                            struct videobuf_buffer *vb);
+};
 
-       /* Helper operations - device dependent.
-        * If null, videobuf_init defaults all to PCI handling
-        */
+#define MAGIC_QTYPE_OPS        0x12261003
+
+/* Helper operations - device type dependent */
+struct videobuf_qtype_ops {
+       u32                     magic;
 
-       vb_map_sg_t     *vb_map_sg;
-       vb_map_sg_t     *vb_dma_sync_sg;
-       vb_map_sg_t     *vb_unmap_sg;
+       void* (*alloc)          (size_t size);
+       int (*iolock)           (struct videobuf_queue* q,
+                                struct videobuf_buffer *vb,
+                                struct v4l2_framebuffer *fbuf);
+       int (*mmap)             (struct videobuf_queue *q,
+                                unsigned int *count,
+                                unsigned int *size,
+                                enum v4l2_memory memory);
+       int (*sync)             (struct videobuf_queue* q,
+                                struct videobuf_buffer *buf);
+       int (*copy_to_user)     (struct videobuf_queue *q,
+                                char __user *data,
+                                size_t count,
+                                int nonblocking);
+       int (*copy_stream)      (struct videobuf_queue *q,
+                                char __user *data,
+                                size_t count,
+                                size_t pos,
+                                int vbihack,
+                                int nonblocking);
+       int (*mmap_free)        (struct videobuf_queue *q);
+       int (*mmap_mapper)      (struct videobuf_queue *q,
+                               struct vm_area_struct *vma);
 };
 
 struct videobuf_queue {
@@ -215,6 +160,7 @@ struct videobuf_queue {
        enum v4l2_field            last;   /* for field=V4L2_FIELD_ALTERNATE */
        struct videobuf_buffer     *bufs[VIDEO_MAX_FRAME];
        struct videobuf_queue_ops  *ops;
+       struct videobuf_qtype_ops  *int_ops;
 
        /* capture via mmap() + ioctl(QBUF/DQBUF) */
        unsigned int               streaming;
@@ -229,28 +175,25 @@ struct videobuf_queue {
        void                       *priv_data;
 };
 
-void* videobuf_alloc(unsigned int size);
 int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
 int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
                struct v4l2_framebuffer *fbuf);
 
-/* Maps fops to PCI stuff */
-void videobuf_queue_pci(struct videobuf_queue* q);
+void *videobuf_alloc(struct videobuf_queue* q);
 
-void videobuf_queue_init(struct videobuf_queue *q,
+void videobuf_queue_core_init(struct videobuf_queue *q,
                         struct videobuf_queue_ops *ops,
                         void *dev,
                         spinlock_t *irqlock,
                         enum v4l2_buf_type type,
                         enum v4l2_field field,
                         unsigned int msize,
-                        void *priv);
+                        void *priv,
+                        struct videobuf_qtype_ops *int_ops);
 int  videobuf_queue_is_busy(struct videobuf_queue *q);
 void videobuf_queue_cancel(struct videobuf_queue *q);
 
 enum v4l2_field videobuf_next_field(struct videobuf_queue *q);
-void videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb,
-                    enum v4l2_buf_type type);
 int videobuf_reqbufs(struct videobuf_queue *q,
                     struct v4l2_requestbuffers *req);
 int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b);
@@ -258,6 +201,10 @@ int videobuf_qbuf(struct videobuf_queue *q,
                  struct v4l2_buffer *b);
 int videobuf_dqbuf(struct videobuf_queue *q,
                   struct v4l2_buffer *b, int nonblocking);
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+int videobuf_cgmbuf(struct videobuf_queue *q,
+                   struct video_mbuf *mbuf, int count);
+#endif
 int videobuf_streamon(struct videobuf_queue *q);
 int videobuf_streamoff(struct videobuf_queue *q);
 
diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h
new file mode 100644 (file)
index 0000000..3810503
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * helper functions for PCI DMA video4linux capture buffers
+ *
+ * The functions expect the hardware being able to scatter gatter
+ * (i.e. the buffers are not linear in physical memory, but fragmented
+ * into PAGE_SIZE chunks).  They also assume the driver does not need
+ * to touch the video data.
+ *
+ * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
+ *
+ * Highly based on video-buf written originally by:
+ * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org>
+ * (c) 2006 Mauro Carvalho Chehab, <mchehab@infradead.org>
+ * (c) 2006 Ted Walther and John Sokol
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2
+ */
+
+#include <media/videobuf-core.h>
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * Return a scatterlist for some page-aligned vmalloc()'ed memory
+ * block (NULL on errors).  Memory for the scatterlist is allocated
+ * using kmalloc.  The caller must free the memory.
+ */
+struct scatterlist* videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages);
+
+/*
+ * Return a scatterlist for a an array of userpages (NULL on errors).
+ * Memory for the scatterlist is allocated using kmalloc.  The caller
+ * must free the memory.
+ */
+struct scatterlist* videobuf_pages_to_sg(struct page **pages, int nr_pages,
+                                        int offset);
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * A small set of helper functions to manage buffers (both userland
+ * and kernel) for DMA.
+ *
+ * videobuf_dma_init_*()
+ *     creates a buffer.  The userland version takes a userspace
+ *     pointer + length.  The kernel version just wants the size and
+ *     does memory allocation too using vmalloc_32().
+ *
+ * videobuf_dma_*()
+ *     see Documentation/DMA-mapping.txt, these functions to
+ *     basically the same.  The map function does also build a
+ *     scatterlist for the buffer (and unmap frees it ...)
+ *
+ * videobuf_dma_free()
+ *     no comment ...
+ *
+ */
+
+struct videobuf_dmabuf {
+       u32                 magic;
+
+       /* for userland buffer */
+       int                 offset;
+       struct page         **pages;
+
+       /* for kernel buffers */
+       void                *vmalloc;
+
+       /* Stores the userspace pointer to vmalloc area */
+       void                *varea;
+
+       /* for overlay buffers (pci-pci dma) */
+       dma_addr_t          bus_addr;
+
+       /* common */
+       struct scatterlist  *sglist;
+       int                 sglen;
+       int                 nr_pages;
+       int                 direction;
+};
+
+struct videbuf_pci_sg_memory
+{
+       u32                 magic;
+
+       /* for mmap'ed buffers */
+       struct videobuf_dmabuf  dma;
+};
+
+void videobuf_dma_init(struct videobuf_dmabuf *dma);
+int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
+                          unsigned long data, unsigned long size);
+int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
+                            int nr_pages);
+int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
+                             dma_addr_t addr, int nr_pages);
+int videobuf_dma_free(struct videobuf_dmabuf *dma);
+
+int videobuf_dma_map(struct videobuf_queue* q,struct videobuf_dmabuf *dma);
+int videobuf_dma_sync(struct videobuf_queue* q,struct videobuf_dmabuf *dma);
+int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma);
+struct videobuf_dmabuf *videobuf_to_dma (struct videobuf_buffer *buf);
+
+void *videobuf_pci_alloc (size_t size);
+
+void videobuf_queue_pci_init(struct videobuf_queue* q,
+                        struct videobuf_queue_ops *ops,
+                        void *dev,
+                        spinlock_t *irqlock,
+                        enum v4l2_buf_type type,
+                        enum v4l2_field field,
+                        unsigned int msize,
+                        void *priv);
+
+       /*FIXME: these variants are used only on *-alsa code, where videobuf is
+        * used without queue
+        */
+int videobuf_pci_dma_map(struct pci_dev *pci,struct videobuf_dmabuf *dma);
+int videobuf_pci_dma_unmap(struct pci_dev *pci,struct videobuf_dmabuf *dma);
+
diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h
new file mode 100644 (file)
index 0000000..26a8958
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * helper functions for vmalloc capture buffers
+ *
+ * The functions expect the hardware being able to scatter gatter
+ * (i.e. the buffers are not linear in physical memory, but fragmented
+ * into PAGE_SIZE chunks).  They also assume the driver does not need
+ * to touch the video data.
+ *
+ * (c) 2007 Mauro Carvalho Chehab, <mchehab@infradead.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2
+ */
+
+#include <media/videobuf-core.h>
+
+/* --------------------------------------------------------------------- */
+
+struct videbuf_vmalloc_memory
+{
+       u32                 magic;
+
+       void                *vmalloc;
+
+       /* remap_vmalloc_range seems to need to run after mmap() on some cases */
+       struct vm_area_struct *vma;
+};
+
+void videobuf_queue_vmalloc_init(struct videobuf_queue* q,
+                        struct videobuf_queue_ops *ops,
+                        void *dev,
+                        spinlock_t *irqlock,
+                        enum v4l2_buf_type type,
+                        enum v4l2_field field,
+                        unsigned int msize,
+                        void *priv);
+
+void *videobuf_to_vmalloc (struct videobuf_buffer *buf);
+
+void videobuf_vmalloc_free (struct videobuf_buffer *buf);
index f7844f6aa487a8c77fc08ff0edf11a8e0ab20d16..663158627155151d60315059a81f1b02d68af697 100755 (executable)
@@ -12,6 +12,7 @@
 #      sh64 port by Paul Mundt
 #      Random bits by Matt Mackall <mpm@selenic.com>
 #      M68k port by Geert Uytterhoeven and Andreas Schwab
+#      AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com>
 #
 #      Usage:
 #      objdump -d vmlinux | stackcheck.pl [arch]
@@ -37,6 +38,10 @@ my (@stack, $re, $x, $xs);
        if ($arch eq 'arm') {
                #c0008ffc:      e24dd064        sub     sp, sp, #100    ; 0x64
                $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
+       } elsif ($arch eq 'avr32') {
+               #8000008a:       20 1d           sub sp,4
+               #80000ca8:       fa cd 05 b0     sub sp,sp,1456
+               $re = qr/^.*sub.*sp.*,([0-9]{1,8})/o;
        } elsif ($arch =~ /^i[3456]86$/) {
                #c0105234:       81 ec ac 05 00 00       sub    $0x5ac,%esp
                $re = qr/^.*[as][du][db]    \$(0x$x{1,8}),\%esp$/o;
index 0dcc01ce45a608f576365b5a341a2edc43c23a67..366f8c7f62bf6de4d82a1ae543e6157a7de07548 100755 (executable)
@@ -119,5 +119,5 @@ sed -n -e '/^\#define/ { s/[^_]*__NR_\([^[:space:]]*\).*/\
 \#endif/p }' $1
 }
 
-(ignore_list && syscall_list ${srctree}/include/asm-i386/unistd.h) | \
+(ignore_list && syscall_list ${srctree}/include/asm-x86/unistd_32.h) | \
 $* -E -x c - > /dev/null
index 8a09021d8c59ab7da6474b90dfbec9f46e3582f6..1e5d4d6931955bbf9432b3309c13b0ef0b8192c5 100644 (file)
@@ -484,6 +484,22 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id,
        return 1;
 }
 
+/* Looks like: sdio:cNvNdN. */
+static int do_sdio_entry(const char *filename,
+                       struct sdio_device_id *id, char *alias)
+{
+       id->class = TO_NATIVE(id->class);
+       id->vendor = TO_NATIVE(id->vendor);
+       id->device = TO_NATIVE(id->device);
+
+       strcpy(alias, "sdio:");
+       ADD(alias, "c", id->class != (__u8)SDIO_ANY_ID, id->class);
+       ADD(alias, "v", id->vendor != (__u16)SDIO_ANY_ID, id->vendor);
+       ADD(alias, "d", id->device != (__u16)SDIO_ANY_ID, id->device);
+
+       return 1;
+}
+
 /* Ignore any prefix, eg. v850 prepends _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -599,6 +615,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
                do_table(symval, sym->st_size,
                         sizeof(struct parisc_device_id), "parisc",
                         do_parisc_entry, mod);
+       else if (sym_is(symname, "__mod_sdio_device_table"))
+               do_table(symval, sym->st_size,
+                        sizeof(struct sdio_device_id), "sdio",
+                        do_sdio_entry, mod);
 }
 
 /* Now add out buffered information to the generated C source */
index f34373853ef845fea8222b3c6ecb95b779573e9f..c6e88c652c2f941647f0d04b3cd982fc6c4e7ab5 100755 (executable)
@@ -105,7 +105,7 @@ sub linux_objects
        if (/.*\.o$/ &&
                ! (
                m:/built-in.o$:
-               || m:arch/i386/kernel/vsyscall-syms.o$:
+               || m:arch/x86/kernel/vsyscall-syms.o$:
                || m:arch/ia64/ia32/ia32.o$:
                || m:arch/ia64/kernel/gate-syms.o$:
                || m:arch/ia64/lib/__divdi3.o$:
@@ -328,9 +328,9 @@ sub list_multiply_defined
                        }
                        # Special case for i386 entry code
                        if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ &&
-                           $def{$name}[0] eq "arch/i386/kernel/vsyscall-int80.o" &&
-                           $def{$name}[1] eq "arch/i386/kernel/vsyscall-sysenter.o") {
-                               &drop_def("arch/i386/kernel/vsyscall-sysenter.o", $name);
+                           $def{$name}[0] eq "arch/x86/kernel/vsyscall-int80_32.o" &&
+                           $def{$name}[1] eq "arch/x86/kernel/vsyscall-sysenter_32.o") {
+                               &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name);
                                next;
                        }
                        printf "$name is multiply defined in :-\n";