diff --git a/[refs] b/[refs]
index eb8a93870a7c..5b0fc53ce488 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: cbc749518235b0f1dacb867c8c25059a1b876276
+refs/heads/master: 5c8c755ce508a9d41d8a8d80fff387cb4e2929fc
diff --git a/trunk/CREDITS b/trunk/CREDITS
index 192f749eba25..7fb4c73e0228 100644
--- a/trunk/CREDITS
+++ b/trunk/CREDITS
@@ -1097,7 +1097,7 @@ S: 80050-430 - Curitiba - Paran
S: Brazil
N: Kumar Gala
-E: galak@kernel.crashing.org
+E: kumar.gala@freescale.com
D: Embedded PowerPC 6xx/7xx/74xx/82xx/83xx/85xx support
S: Austin, Texas 78729
S: USA
diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile
index 1c955883cf58..7018f5c6a447 100644
--- a/trunk/Documentation/DocBook/Makefile
+++ b/trunk/Documentation/DocBook/Makefile
@@ -20,12 +20,6 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
# +--> DIR=file (htmldocs)
# +--> man/ (mandocs)
-
-# for PDF and PS output you can choose between xmlto and docbook-utils tools
-PDF_METHOD = $(prefer-db2x)
-PS_METHOD = $(prefer-db2x)
-
-
###
# The targets that may be used.
.PHONY: xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs
@@ -99,39 +93,27 @@ C-procfs-example = procfs_example.xml
C-procfs-example2 = $(addprefix $(obj)/,$(C-procfs-example))
$(obj)/procfs-guide.xml: $(C-procfs-example2)
-notfoundtemplate = echo "*** You have to install docbook-utils or xmlto ***"; \
- exit 1
-db2xtemplate = db2TYPE -o $(dir $@) $<
-xmltotemplate = xmlto TYPE $(XMLTOFLAGS) -o $(dir $@) $<
-
-# determine which methods are available
-ifeq ($(shell which db2ps >/dev/null 2>&1 && echo found),found)
- use-db2x = db2x
- prefer-db2x = db2x
-else
- use-db2x = notfound
- prefer-db2x = $(use-xmlto)
-endif
-ifeq ($(shell which xmlto >/dev/null 2>&1 && echo found),found)
- use-xmlto = xmlto
- prefer-xmlto = xmlto
-else
- use-xmlto = notfound
- prefer-xmlto = $(use-db2x)
-endif
+###
+# Rules to generate postscript, PDF and HTML
+# db2html creates a directory. Generate a html file used for timestamp
-# the commands, generated from the chosen template
-quiet_cmd_db2ps = PS $@
- cmd_db2ps = $(subst TYPE,ps, $($(PS_METHOD)template))
+quiet_cmd_db2ps = XMLTO $@
+ cmd_db2ps = xmlto ps $(XMLTOFLAGS) -o $(dir $@) $<
%.ps : %.xml
+ @(which xmlto > /dev/null 2>&1) || \
+ (echo "*** You need to install xmlto ***"; \
+ exit 1)
$(call cmd,db2ps)
-quiet_cmd_db2pdf = PDF $@
- cmd_db2pdf = $(subst TYPE,pdf, $($(PDF_METHOD)template))
+quiet_cmd_db2pdf = XMLTO $@
+ cmd_db2pdf = xmlto pdf $(XMLTOFLAGS) -o $(dir $@) $<
%.pdf : %.xml
+ @(which xmlto > /dev/null 2>&1) || \
+ (echo "*** You need to install xmlto ***"; \
+ exit 1)
$(call cmd,db2pdf)
-quiet_cmd_db2html = HTML $@
+quiet_cmd_db2html = XMLTO $@
cmd_db2html = xmlto xhtml $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \
echo ' \
Goto $(patsubst %.html,%,$(notdir $@))
' > $@
@@ -145,7 +127,7 @@ quiet_cmd_db2html = HTML $@
@if [ ! -z "$(PNG-$(basename $(notdir $@)))" ]; then \
cp $(PNG-$(basename $(notdir $@))) $(patsubst %.html,%,$@); fi
-quiet_cmd_db2man = MAN $@
+quiet_cmd_db2man = XMLTO $@
cmd_db2man = if grep -q refentry $<; then xmlto man $(XMLTOFLAGS) -o $(obj)/man $< ; gzip -f $(obj)/man/*.9; fi
%.9 : %.xml
@(which xmlto > /dev/null 2>&1) || \
diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl
index 0519c9dc0065..a8316b1a3e3d 100644
--- a/trunk/Documentation/DocBook/kernel-api.tmpl
+++ b/trunk/Documentation/DocBook/kernel-api.tmpl
@@ -68,7 +68,9 @@ X!Iinclude/linux/kobject.h
Kernel utility functions
!Iinclude/linux/kernel.h
-!Ekernel/printk.c
+
!Ekernel/panic.c
!Ekernel/sys.c
!Ekernel/rcupdate.c
diff --git a/trunk/Documentation/DocBook/stylesheet.xsl b/trunk/Documentation/DocBook/stylesheet.xsl
index 3ccce886c349..64be9f7ee3bb 100644
--- a/trunk/Documentation/DocBook/stylesheet.xsl
+++ b/trunk/Documentation/DocBook/stylesheet.xsl
@@ -3,5 +3,4 @@
1
ansi
80
-
diff --git a/trunk/Documentation/atomic_ops.txt b/trunk/Documentation/atomic_ops.txt
index 23a1c2402bcc..8eedaa24f5e2 100644
--- a/trunk/Documentation/atomic_ops.txt
+++ b/trunk/Documentation/atomic_ops.txt
@@ -115,33 +115,6 @@ boolean is return which indicates whether the resulting counter value
is negative. It requires explicit memory barrier semantics around the
operation.
-Then:
-
- int atomic_cmpxchg(atomic_t *v, int old, int new);
-
-This performs an atomic compare exchange operation on the atomic value v,
-with the given old and new values. Like all atomic_xxx operations,
-atomic_cmpxchg will only satisfy its atomicity semantics as long as all
-other accesses of *v are performed through atomic_xxx operations.
-
-atomic_cmpxchg requires explicit memory barriers around the operation.
-
-The semantics for atomic_cmpxchg are the same as those defined for 'cas'
-below.
-
-Finally:
-
- int atomic_add_unless(atomic_t *v, int a, int u);
-
-If the atomic value v is not equal to u, this function adds a to v, and
-returns non zero. If v is equal to u then it returns zero. This is done as
-an atomic operation.
-
-atomic_add_unless requires explicit memory barriers around the operation.
-
-atomic_inc_not_zero, equivalent to atomic_add_unless(v, 1, 0)
-
-
If a caller requires memory barrier semantics around an atomic_t
operation which does not return a value, a set of interfaces are
defined which accomplish this:
diff --git a/trunk/Documentation/oops-tracing.txt b/trunk/Documentation/oops-tracing.txt
index 9f30ac6ca47b..c563842ed805 100644
--- a/trunk/Documentation/oops-tracing.txt
+++ b/trunk/Documentation/oops-tracing.txt
@@ -30,9 +30,7 @@ the disk is not available then you have three options :-
(1) Hand copy the text from the screen and type it in after the machine
has restarted. Messy but it is the only option if you have not
- planned for a crash. Alternatively, you can take a picture of
- the screen with a digital camera - not nice, but better than
- nothing.
+ planned for a crash.
(2) Boot with a serial console (see Documentation/serial-console.txt),
run a null modem to a second machine and capture the output there
diff --git a/trunk/Documentation/video4linux/CARDLIST.bttv b/trunk/Documentation/video4linux/CARDLIST.bttv
index 330246ac80f8..2404099996ac 100644
--- a/trunk/Documentation/video4linux/CARDLIST.bttv
+++ b/trunk/Documentation/video4linux/CARDLIST.bttv
@@ -140,4 +140,3 @@
139 -> Prolink PixelView PlayTV MPEG2 PV-M4900
140 -> Osprey 440 [0070:ff07]
141 -> Asound Skyeye PCTV
-142 -> Sabrent TV-FM (bttv version)
diff --git a/trunk/Documentation/video4linux/CARDLIST.saa7134 b/trunk/Documentation/video4linux/CARDLIST.saa7134
index efb708ec116a..57c9d631db56 100644
--- a/trunk/Documentation/video4linux/CARDLIST.saa7134
+++ b/trunk/Documentation/video4linux/CARDLIST.saa7134
@@ -80,5 +80,3 @@
79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
80 -> ASUS Digimatrix TV [1043:0210]
81 -> Philips Tiger reference design [1131:2018]
- 82 -> MSI TV@Anywhere plus [1462:6231]
-
diff --git a/trunk/Documentation/video4linux/CARDLIST.tuner b/trunk/Documentation/video4linux/CARDLIST.tuner
index 9d6544ea9f41..ec840ca6f455 100644
--- a/trunk/Documentation/video4linux/CARDLIST.tuner
+++ b/trunk/Documentation/video4linux/CARDLIST.tuner
@@ -67,4 +67,3 @@ tuner=65 - Ymec TVF66T5-B/DFF
tuner=66 - LG NTSC (TALN mini series)
tuner=67 - Philips TD1316 Hybrid Tuner
tuner=68 - Philips TUV1236D ATSC/NTSC dual in
-tuner=69 - Tena TNF 5335 MF
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index 509927e40bbb..2313de23b0da 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -1565,7 +1565,7 @@ S: Maintained
LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX
P: Kumar Gala
-M: galak@kernel.crashing.org
+M: kumar.gala@freescale.com
W: http://www.penguinppc.org/
L: linuxppc-embedded@ozlabs.org
S: Maintained
@@ -1873,16 +1873,6 @@ L: linux-tr@linuxtr.net
W: http://www.linuxtr.net
S: Maintained
-OMNIKEY CARDMAN 4000 DRIVER
-P: Harald Welte
-M: laforge@gnumonks.org
-S: Maintained
-
-OMNIKEY CARDMAN 4040 DRIVER
-P: Harald Welte
-M: laforge@gnumonks.org
-S: Maintained
-
ONSTREAM SCSI TAPE DRIVER
P: Willem Riede
M: osst@riede.org
diff --git a/trunk/Makefile b/trunk/Makefile
index c31914400953..8560b79268ba 100644
--- a/trunk/Makefile
+++ b/trunk/Makefile
@@ -1193,17 +1193,6 @@ else
__srctree = $(srctree)/
endif
-ifeq ($(ALLSOURCE_ARCHS),)
-ifeq ($(ARCH),um)
-ALLINCLUDE_ARCHS := $(ARCH) $(SUBARCH)
-else
-ALLINCLUDE_ARCHS := $(ARCH)
-endif
-else
-#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behaviour.
-ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS)
-endif
-
ALLSOURCE_ARCHS := $(ARCH)
define all-sources
@@ -1219,7 +1208,7 @@ define all-sources
find $(__srctree)include $(RCS_FIND_IGNORE) \
\( -name config -o -name 'asm-*' \) -prune \
-o -name '*.[chS]' -print; \
- for ARCH in $(ALLINCLUDE_ARCHS) ; do \
+ for ARCH in $(ALLSOURCE_ARCHS) ; do \
find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \
-name '*.[chS]' -print; \
done ; \
diff --git a/trunk/README b/trunk/README
index 61c4f7429233..4ee7dda88ba3 100644
--- a/trunk/README
+++ b/trunk/README
@@ -81,11 +81,6 @@ INSTALLING the kernel:
failed patches (xxx# or xxx.rej). If there are, either you or me has
made a mistake.
- Unlike patches for the 2.6.x kernels, patches for the 2.6.x.y kernels
- (also known as the -stable kernels) are not incremental but instead apply
- directly to the base 2.6.x kernel. Please read
- Documentation/applying-patches.txt for more information.
-
Alternatively, the script patch-kernel can be used to automate this
process. It determines the current kernel version and applies any
patches found.
diff --git a/trunk/arch/arm/kernel/apm.c b/trunk/arch/arm/kernel/apm.c
index a2843be05557..b0bbd1e62ebb 100644
--- a/trunk/arch/arm/kernel/apm.c
+++ b/trunk/arch/arm/kernel/apm.c
@@ -20,7 +20,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/trunk/arch/frv/kernel/pm.c b/trunk/arch/frv/kernel/pm.c
index 712c3c24c954..1a1e8a119c3d 100644
--- a/trunk/arch/frv/kernel/pm.c
+++ b/trunk/arch/frv/kernel/pm.c
@@ -14,7 +14,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig
index 6004bb0795e0..dbf90ad6eac3 100644
--- a/trunk/arch/i386/Kconfig
+++ b/trunk/arch/i386/Kconfig
@@ -699,7 +699,7 @@ depends on PM && !X86_VISWS
config APM
tristate "APM (Advanced Power Management) BIOS support"
- depends on PM && PM_LEGACY
+ depends on PM
---help---
APM is a BIOS specification for saving power using several different
techniques. This is mostly useful for battery powered laptops with
diff --git a/trunk/arch/i386/kernel/apm.c b/trunk/arch/i386/kernel/apm.c
index 1e60acbed3c1..003548b8735f 100644
--- a/trunk/arch/i386/kernel/apm.c
+++ b/trunk/arch/i386/kernel/apm.c
@@ -218,7 +218,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/trunk/arch/i386/kernel/cpu/intel.c b/trunk/arch/i386/kernel/cpu/intel.c
index c28d26fb5f24..43601de0f633 100644
--- a/trunk/arch/i386/kernel/cpu/intel.c
+++ b/trunk/arch/i386/kernel/cpu/intel.c
@@ -6,7 +6,6 @@
#include
#include
#include
-#include
#include
#include
@@ -265,52 +264,5 @@ __init int intel_cpu_init(void)
return 0;
}
-#ifndef CONFIG_X86_CMPXCHG
-unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new)
-{
- u8 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u8 *)ptr;
- if (prev == old)
- *(u8 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u8);
-
-unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new)
-{
- u16 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u16 *)ptr;
- if (prev == old)
- *(u16 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u16);
-
-unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
-{
- u32 prev;
- unsigned long flags;
-
- /* Poor man's cmpxchg for 386. Unsuitable for SMP */
- local_irq_save(flags);
- prev = *(u32 *)ptr;
- if (prev == old)
- *(u32 *)ptr = new;
- local_irq_restore(flags);
- return prev;
-}
-EXPORT_SYMBOL(cmpxchg_386_u32);
-#endif
-
// arch_initcall(intel_cpu_init);
diff --git a/trunk/arch/i386/kernel/entry.S b/trunk/arch/i386/kernel/entry.S
index e50b93155249..9e24f7b207ee 100644
--- a/trunk/arch/i386/kernel/entry.S
+++ b/trunk/arch/i386/kernel/entry.S
@@ -560,10 +560,11 @@ nmi_stack_fixup:
nmi_debug_stack_check:
cmpw $__KERNEL_CS,16(%esp)
jne nmi_stack_correct
- cmpl $debug,(%esp)
- jb nmi_stack_correct
+ cmpl $debug - 1,(%esp)
+ jle nmi_stack_correct
cmpl $debug_esp_fix_insn,(%esp)
- ja nmi_stack_correct
+ jle nmi_debug_stack_fixup
+nmi_debug_stack_fixup:
FIX_STACK(24,nmi_stack_correct, 1)
jmp nmi_stack_correct
diff --git a/trunk/arch/i386/kernel/timers/timer_pit.c b/trunk/arch/i386/kernel/timers/timer_pit.c
index b9b6bd56b9ba..e42e46d35159 100644
--- a/trunk/arch/i386/kernel/timers/timer_pit.c
+++ b/trunk/arch/i386/kernel/timers/timer_pit.c
@@ -25,9 +25,8 @@ static int __init init_pit(char* override)
{
/* check clock override */
if (override[0] && strncmp(override,"pit",3))
- printk(KERN_ERR "Warning: clock= override failed. Defaulting "
- "to PIT\n");
- init_cpu_khz();
+ printk(KERN_ERR "Warning: clock= override failed. Defaulting to PIT\n");
+
count_p = LATCH;
return 0;
}
diff --git a/trunk/arch/i386/mm/init.c b/trunk/arch/i386/mm/init.c
index 06e26f006238..542d9298da5e 100644
--- a/trunk/arch/i386/mm/init.c
+++ b/trunk/arch/i386/mm/init.c
@@ -28,7 +28,6 @@
#include
#include
#include
-#include
#include
#include
@@ -268,7 +267,7 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base)
pkmap_page_table = pte;
}
-static void __devinit free_new_highpage(struct page *page)
+void __devinit free_new_highpage(struct page *page)
{
set_page_count(page, 1);
__free_page(page);
diff --git a/trunk/arch/m68k/fpsp040/skeleton.S b/trunk/arch/m68k/fpsp040/skeleton.S
index a1629194e3fd..9571a21d6ad4 100644
--- a/trunk/arch/m68k/fpsp040/skeleton.S
+++ b/trunk/arch/m68k/fpsp040/skeleton.S
@@ -381,8 +381,10 @@ fpsp_done:
.Lnotkern:
SAVE_ALL_INT
GET_CURRENT(%d0)
- | deliver signals, reschedule etc..
- jra ret_from_exception
+ tstb %curptr@(TASK_NEEDRESCHED)
+ jne ret_from_exception | deliver signals,
+ | reschedule etc..
+ RESTORE_ALL
|
| mem_write --- write to user or supervisor address space
diff --git a/trunk/arch/m68k/ifpsp060/iskeleton.S b/trunk/arch/m68k/ifpsp060/iskeleton.S
index b2dbdf5ee309..4ba2c74da93d 100644
--- a/trunk/arch/m68k/ifpsp060/iskeleton.S
+++ b/trunk/arch/m68k/ifpsp060/iskeleton.S
@@ -75,8 +75,10 @@ _060_isp_done:
.Lnotkern:
SAVE_ALL_INT
GET_CURRENT(%d0)
- | deliver signals, reschedule etc..
- jra ret_from_exception
+ tstb %curptr@(TASK_NEEDRESCHED)
+ jne ret_from_exception | deliver signals,
+ | reschedule etc..
+ RESTORE_ALL
|
| _060_real_chk():
diff --git a/trunk/arch/m68k/kernel/asm-offsets.c b/trunk/arch/m68k/kernel/asm-offsets.c
index c787c5ba9513..cee3317b8665 100644
--- a/trunk/arch/m68k/kernel/asm-offsets.c
+++ b/trunk/arch/m68k/kernel/asm-offsets.c
@@ -25,8 +25,12 @@ int main(void)
DEFINE(TASK_STATE, offsetof(struct task_struct, state));
DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+ DEFINE(TASK_WORK, offsetof(struct task_struct, thread.work));
+ DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, thread.work.need_resched));
+ DEFINE(TASK_SYSCALL_TRACE, offsetof(struct task_struct, thread.work.syscall_trace));
+ DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, thread.work.sigpending));
+ DEFINE(TASK_NOTIFY_RESUME, offsetof(struct task_struct, thread.work.notify_resume));
DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
- DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
DEFINE(TASK_MM, offsetof(struct task_struct, mm));
DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
@@ -41,10 +45,6 @@ int main(void)
DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
- /* offsets into the thread_info struct */
- DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
- DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
-
/* offsets into the pt_regs */
DEFINE(PT_D0, offsetof(struct pt_regs, d0));
DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
diff --git a/trunk/arch/m68k/kernel/entry.S b/trunk/arch/m68k/kernel/entry.S
index 320fde05dc63..23ca60a45552 100644
--- a/trunk/arch/m68k/kernel/entry.S
+++ b/trunk/arch/m68k/kernel/entry.S
@@ -44,7 +44,9 @@
#include
-.globl system_call, buserr, trap, resume
+.globl system_call, buserr, trap
+.globl resume, ret_from_exception
+.globl ret_from_signal
.globl inthandler, sys_call_table
.globl sys_fork, sys_clone, sys_vfork
.globl ret_from_interrupt, bad_interrupt
@@ -56,7 +58,7 @@ ENTRY(buserr)
movel %sp,%sp@- | stack frame pointer argument
bsrl buserr_c
addql #4,%sp
- jra .Lret_from_exception
+ jra ret_from_exception
ENTRY(trap)
SAVE_ALL_INT
@@ -64,7 +66,7 @@ ENTRY(trap)
movel %sp,%sp@- | stack frame pointer argument
bsrl trap_c
addql #4,%sp
- jra .Lret_from_exception
+ jra ret_from_exception
| After a fork we jump here directly from resume,
| so that %d1 contains the previous task
@@ -73,31 +75,30 @@ ENTRY(ret_from_fork)
movel %d1,%sp@-
jsr schedule_tail
addql #4,%sp
- jra .Lret_from_exception
+ jra ret_from_exception
-do_trace_entry:
- movel #-ENOSYS,%sp@(PT_D0) | needed for strace
- subql #4,%sp
- SAVE_SWITCH_STACK
- jbsr syscall_trace
- RESTORE_SWITCH_STACK
- addql #4,%sp
- movel %sp@(PT_ORIG_D0),%d0
- cmpl #NR_syscalls,%d0
- jcs syscall
badsys:
movel #-ENOSYS,%sp@(PT_D0)
- jra ret_from_syscall
+ jra ret_from_exception
-do_trace_exit:
+do_trace:
+ movel #-ENOSYS,%sp@(PT_D0) | needed for strace
subql #4,%sp
SAVE_SWITCH_STACK
jbsr syscall_trace
RESTORE_SWITCH_STACK
addql #4,%sp
- jra .Lret_from_exception
+ movel %sp@(PT_ORIG_D0),%d1
+ movel #-ENOSYS,%d0
+ cmpl #NR_syscalls,%d1
+ jcc 1f
+ jbsr @(sys_call_table,%d1:l:4)@(0)
+1: movel %d0,%sp@(PT_D0) | save the return value
+ subql #4,%sp | dummy return address
+ SAVE_SWITCH_STACK
+ jbsr syscall_trace
-ENTRY(ret_from_signal)
+ret_from_signal:
RESTORE_SWITCH_STACK
addql #4,%sp
/* on 68040 complete pending writebacks if any */
@@ -110,7 +111,7 @@ ENTRY(ret_from_signal)
addql #4,%sp
1:
#endif
- jra .Lret_from_exception
+ jra ret_from_exception
ENTRY(system_call)
SAVE_ALL_SYS
@@ -119,34 +120,30 @@ ENTRY(system_call)
| save top of frame
movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
- | syscall trace?
- tstb %curptr@(TASK_INFO+TINFO_FLAGS+2)
- jmi do_trace_entry
+ tstb %curptr@(TASK_SYSCALL_TRACE)
+ jne do_trace
cmpl #NR_syscalls,%d0
jcc badsys
-syscall:
jbsr @(sys_call_table,%d0:l:4)@(0)
movel %d0,%sp@(PT_D0) | save the return value
-ret_from_syscall:
+
|oriw #0x0700,%sr
- movew %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0
+ movel %curptr@(TASK_WORK),%d0
jne syscall_exit_work
1: RESTORE_ALL
syscall_exit_work:
btst #5,%sp@(PT_SR) | check if returning to kernel
bnes 1b | if so, skip resched, signals
- lslw #1,%d0
- jcs do_trace_exit
- jmi do_delayed_trace
- lslw #8,%d0
- jmi do_signal_return
- pea resume_userspace
- jra schedule
+ tstw %d0
+ jeq do_signal_return
+ tstb %d0
+ jne do_delayed_trace
+ pea resume_userspace
+ jmp schedule
-ENTRY(ret_from_exception)
-.Lret_from_exception:
+ret_from_exception:
btst #5,%sp@(PT_SR) | check if returning to kernel
bnes 1f | if so, skip resched, signals
| only allow interrupts when we are really the last one on the
@@ -155,18 +152,19 @@ ENTRY(ret_from_exception)
andw #ALLOWINT,%sr
resume_userspace:
- moveb %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0
+ movel %curptr@(TASK_WORK),%d0
+ lsrl #8,%d0
jne exit_work
1: RESTORE_ALL
exit_work:
| save top of frame
movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
- lslb #1,%d0
- jmi do_signal_return
- pea resume_userspace
- jra schedule
+ tstb %d0
+ jeq do_signal_return
+ pea resume_userspace
+ jmp schedule
do_signal_return:
|andw #ALLOWINT,%sr
@@ -256,7 +254,7 @@ ret_from_interrupt:
/* check if we need to do software interrupts */
tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING
- jeq .Lret_from_exception
+ jeq ret_from_exception
pea ret_from_exception
jra do_softirq
diff --git a/trunk/arch/m68k/kernel/ptrace.c b/trunk/arch/m68k/kernel/ptrace.c
index 540638ca81f9..7e54422685cf 100644
--- a/trunk/arch/m68k/kernel/ptrace.c
+++ b/trunk/arch/m68k/kernel/ptrace.c
@@ -109,7 +109,7 @@ static inline void singlestep_disable(struct task_struct *child)
{
unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
- clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+ child->thread.work.delayed_trace = 0;
}
/*
@@ -118,7 +118,7 @@ static inline void singlestep_disable(struct task_struct *child)
void ptrace_disable(struct task_struct *child)
{
singlestep_disable(child);
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ child->thread.work.syscall_trace = 0;
}
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -198,9 +198,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
goto out_eio;
if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ child->thread.work.syscall_trace = ~0;
else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ child->thread.work.syscall_trace = 0;
child->exit_code = data;
singlestep_disable(child);
wake_up_process(child);
@@ -223,10 +223,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
if (!valid_signal(data))
goto out_eio;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ child->thread.work.syscall_trace = 0;
tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
- set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+ child->thread.work.delayed_trace = 1;
child->exit_code = data;
/* give it a chance to run. */
@@ -288,6 +288,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
asmlinkage void syscall_trace(void)
{
+ if (!current->thread.work.delayed_trace &&
+ !current->thread.work.syscall_trace)
+ return;
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
/*
diff --git a/trunk/arch/mips/au1000/common/power.c b/trunk/arch/mips/au1000/common/power.c
index f4926315fb68..f85093b8d54d 100644
--- a/trunk/arch/mips/au1000/common/power.c
+++ b/trunk/arch/mips/au1000/common/power.c
@@ -32,7 +32,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/trunk/arch/mips/au1000/common/usbdev.c b/trunk/arch/mips/au1000/common/usbdev.c
index 2cab7629702c..0b21bed7ee55 100644
--- a/trunk/arch/mips/au1000/common/usbdev.c
+++ b/trunk/arch/mips/au1000/common/usbdev.c
@@ -348,7 +348,7 @@ endpoint_stall(endpoint_t * ep)
{
u32 cs;
- warn("%s", __FUNCTION__);
+ warn(__FUNCTION__);
cs = au_readl(ep->reg->ctrl_stat) | USBDEV_CS_STALL;
au_writel(cs, ep->reg->ctrl_stat);
@@ -360,7 +360,7 @@ endpoint_unstall(endpoint_t * ep)
{
u32 cs;
- warn("%s", __FUNCTION__);
+ warn(__FUNCTION__);
cs = au_readl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL;
au_writel(cs, ep->reg->ctrl_stat);
diff --git a/trunk/arch/powerpc/kernel/head_fsl_booke.S b/trunk/arch/powerpc/kernel/head_fsl_booke.S
index 8d60fa99fc4b..5063c603fad4 100644
--- a/trunk/arch/powerpc/kernel/head_fsl_booke.S
+++ b/trunk/arch/powerpc/kernel/head_fsl_booke.S
@@ -24,7 +24,7 @@
* Copyright 2002-2004 MontaVista Software, Inc.
* PowerPC 44x support, Matt Porter
* Copyright 2004 Freescale Semiconductor, Inc
- * PowerPC e500 modifications, Kumar Gala
+ * PowerPC e500 modifications, Kumar Gala
*
* 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
diff --git a/trunk/arch/powerpc/kernel/ioctl32.c b/trunk/arch/powerpc/kernel/ioctl32.c
index 0fa3d27fef01..3fa6a93adbd0 100644
--- a/trunk/arch/powerpc/kernel/ioctl32.c
+++ b/trunk/arch/powerpc/kernel/ioctl32.c
@@ -40,6 +40,10 @@ IOCTL_TABLE_START
#define DECLARES
#include "compat_ioctl.c"
+/* Little p (/dev/rtc, /dev/envctrl, etc.) */
+COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
+COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
+
IOCTL_TABLE_END
int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/trunk/arch/powerpc/mm/fsl_booke_mmu.c b/trunk/arch/powerpc/mm/fsl_booke_mmu.c
index 5d581bb3aa12..af9ca0eb6d55 100644
--- a/trunk/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/trunk/arch/powerpc/mm/fsl_booke_mmu.c
@@ -1,5 +1,5 @@
/*
- * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
+ * Modifications by Kumar Gala (kumar.gala@freescale.com) to support
* E500 Book E processors.
*
* Copyright 2004 Freescale Semiconductor, Inc
diff --git a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c
index 26539cda6023..86124a94c9af 100644
--- a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -7,7 +7,7 @@
* Copyright (c) 2004 Freescale Semiconductor, Inc
*
* Author: Andy Fleming
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
diff --git a/trunk/arch/powerpc/xmon/xmon.c b/trunk/arch/powerpc/xmon/xmon.c
index c45a6ad5f3b7..ef4356b29a97 100644
--- a/trunk/arch/powerpc/xmon/xmon.c
+++ b/trunk/arch/powerpc/xmon/xmon.c
@@ -19,7 +19,6 @@
#include
#include
#include
-#include
#include
#include
diff --git a/trunk/arch/ppc/kernel/head_fsl_booke.S b/trunk/arch/ppc/kernel/head_fsl_booke.S
index 8d60fa99fc4b..5063c603fad4 100644
--- a/trunk/arch/ppc/kernel/head_fsl_booke.S
+++ b/trunk/arch/ppc/kernel/head_fsl_booke.S
@@ -24,7 +24,7 @@
* Copyright 2002-2004 MontaVista Software, Inc.
* PowerPC 44x support, Matt Porter
* Copyright 2004 Freescale Semiconductor, Inc
- * PowerPC e500 modifications, Kumar Gala
+ * PowerPC e500 modifications, Kumar Gala
*
* 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
diff --git a/trunk/arch/ppc/mm/fsl_booke_mmu.c b/trunk/arch/ppc/mm/fsl_booke_mmu.c
index 5d581bb3aa12..af9ca0eb6d55 100644
--- a/trunk/arch/ppc/mm/fsl_booke_mmu.c
+++ b/trunk/arch/ppc/mm/fsl_booke_mmu.c
@@ -1,5 +1,5 @@
/*
- * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
+ * Modifications by Kumar Gala (kumar.gala@freescale.com) to support
* E500 Book E processors.
*
* Copyright 2004 Freescale Semiconductor, Inc
diff --git a/trunk/arch/ppc/platforms/83xx/mpc834x_sys.c b/trunk/arch/ppc/platforms/83xx/mpc834x_sys.c
index 04bdc39bf47b..98edc75f4105 100644
--- a/trunk/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/trunk/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -3,7 +3,7 @@
*
* MPC834x SYS board specific routines
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 Freescale Semiconductor Inc.
*
@@ -73,19 +73,12 @@ mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
* A B C D
*/
{
- {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */
- {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */
- {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x13 */
- {0, 0, 0, 0},
- {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x15 */
- {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x16 */
- {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x17 */
- {PIRQB, PIRQC, PIRQD, PIRQA}, /* idsel 0x18 */
- {0, 0, 0, 0}, /* idsel 0x19 */
- {0, 0, 0, 0}, /* idsel 0x20 */
+ {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */
+ {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */
+ {PIRQD, PIRQA, PIRQB, PIRQC} /* idsel 0x13 */
};
- const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4;
+ const long min_idsel = 0x11, max_idsel = 0x13, irqs_per_slot = 4;
return PCI_IRQ_TABLE_LOOKUP;
}
diff --git a/trunk/arch/ppc/platforms/83xx/mpc834x_sys.h b/trunk/arch/ppc/platforms/83xx/mpc834x_sys.h
index 2e514d316fb8..58e44c042535 100644
--- a/trunk/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/trunk/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -3,7 +3,7 @@
*
* MPC834X SYS common board definitions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 Freescale Semiconductor, Inc.
*
diff --git a/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c b/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c
index c5cde97c6ef0..7e952c1228cb 100644
--- a/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -3,7 +3,7 @@
*
* MPC8540ADS board specific routines
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/platforms/85xx/mpc8540_ads.h b/trunk/arch/ppc/platforms/85xx/mpc8540_ads.h
index e48ca3a97397..3d05d7c4a938 100644
--- a/trunk/arch/ppc/platforms/85xx/mpc8540_ads.h
+++ b/trunk/arch/ppc/platforms/85xx/mpc8540_ads.h
@@ -3,7 +3,7 @@
*
* MPC8540ADS board definitions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/platforms/85xx/mpc8555_cds.h b/trunk/arch/ppc/platforms/85xx/mpc8555_cds.h
index 1a8e6c67355d..e0e75568bc57 100644
--- a/trunk/arch/ppc/platforms/85xx/mpc8555_cds.h
+++ b/trunk/arch/ppc/platforms/85xx/mpc8555_cds.h
@@ -3,7 +3,7 @@
*
* MPC8555CDS board definitions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c b/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c
index 8e39a5517092..208433f1e93a 100644
--- a/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c
+++ b/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c
@@ -3,7 +3,7 @@
*
* MPC8560ADS board specific routines
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/platforms/85xx/mpc8560_ads.h b/trunk/arch/ppc/platforms/85xx/mpc8560_ads.h
index 143ae7eefa7c..7df885d73e9d 100644
--- a/trunk/arch/ppc/platforms/85xx/mpc8560_ads.h
+++ b/trunk/arch/ppc/platforms/85xx/mpc8560_ads.h
@@ -3,7 +3,7 @@
*
* MPC8540ADS board definitions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
index 17ce48fe3503..16ad092d8a06 100644
--- a/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
+++ b/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
@@ -3,7 +3,7 @@
*
* MPC85xx ADS board common routines
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.h b/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
index 7b26bcc5d10d..84acf6e8d45e 100644
--- a/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
+++ b/trunk/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
@@ -3,7 +3,7 @@
*
* MPC85XX ADS common board definitions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index d8991b88dc9c..a21156967a5e 100644
--- a/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -3,7 +3,7 @@
*
* MPC85xx CDS board specific routines
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor, Inc
*
diff --git a/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.h b/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
index 5b588cfd0e41..12b292c6ae32 100644
--- a/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
+++ b/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
@@ -3,7 +3,7 @@
*
* MPC85xx CDS board definitions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor, Inc
*
diff --git a/trunk/arch/ppc/platforms/85xx/sbc8560.c b/trunk/arch/ppc/platforms/85xx/sbc8560.c
index 45a5b81b4ed1..b4ee1707a836 100644
--- a/trunk/arch/ppc/platforms/85xx/sbc8560.c
+++ b/trunk/arch/ppc/platforms/85xx/sbc8560.c
@@ -3,7 +3,7 @@
*
* Wind River SBC8560 board specific routines
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/platforms/pmac_feature.c b/trunk/arch/ppc/platforms/pmac_feature.c
index 1e69b0593162..58884a63ebdb 100644
--- a/trunk/arch/ppc/platforms/pmac_feature.c
+++ b/trunk/arch/ppc/platforms/pmac_feature.c
@@ -2317,14 +2317,6 @@ static struct pmac_mb_def pmac_mb_defs[] = {
PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
},
- { "PowerBook5,8", "PowerBook G4 15\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,9", "PowerBook G4 17\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
{ "PowerBook6,1", "PowerBook G4 12\"",
PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
diff --git a/trunk/arch/ppc/platforms/pq2ads.c b/trunk/arch/ppc/platforms/pq2ads.c
index 71c9fca1fe9b..6a1475c1e128 100644
--- a/trunk/arch/ppc/platforms/pq2ads.c
+++ b/trunk/arch/ppc/platforms/pq2ads.c
@@ -3,7 +3,7 @@
*
* PQ2ADS platform support
*
- * Author: Kumar Gala
+ * Author: Kumar Gala
* Derived from: est8260_setup.c by Allen Curtis
*
* Copyright 2004 Freescale Semiconductor, Inc.
diff --git a/trunk/arch/ppc/syslib/ipic.h b/trunk/arch/ppc/syslib/ipic.h
index a7ce7da8785c..2b56a4fcf373 100644
--- a/trunk/arch/ppc/syslib/ipic.h
+++ b/trunk/arch/ppc/syslib/ipic.h
@@ -3,7 +3,7 @@
*
* IPIC private definitions and structure.
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 Freescale Semiconductor, Inc
*
diff --git a/trunk/arch/ppc/syslib/mpc83xx_devices.c b/trunk/arch/ppc/syslib/mpc83xx_devices.c
index 847df4409982..f43fbf9a9389 100644
--- a/trunk/arch/ppc/syslib/mpc83xx_devices.c
+++ b/trunk/arch/ppc/syslib/mpc83xx_devices.c
@@ -3,7 +3,7 @@
*
* MPC83xx Device descriptions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/syslib/mpc83xx_sys.c b/trunk/arch/ppc/syslib/mpc83xx_sys.c
index a1523989aff4..da743446789b 100644
--- a/trunk/arch/ppc/syslib/mpc83xx_sys.c
+++ b/trunk/arch/ppc/syslib/mpc83xx_sys.c
@@ -3,7 +3,7 @@
*
* MPC83xx System descriptions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/syslib/mpc85xx_devices.c b/trunk/arch/ppc/syslib/mpc85xx_devices.c
index 69949d255658..2ede677a0a53 100644
--- a/trunk/arch/ppc/syslib/mpc85xx_devices.c
+++ b/trunk/arch/ppc/syslib/mpc85xx_devices.c
@@ -3,7 +3,7 @@
*
* MPC85xx Device descriptions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/syslib/mpc85xx_sys.c b/trunk/arch/ppc/syslib/mpc85xx_sys.c
index 397cfbcce5ea..cb68d8c58348 100644
--- a/trunk/arch/ppc/syslib/mpc85xx_sys.c
+++ b/trunk/arch/ppc/syslib/mpc85xx_sys.c
@@ -3,7 +3,7 @@
*
* MPC85xx System descriptions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/syslib/mpc8xx_devices.c b/trunk/arch/ppc/syslib/mpc8xx_devices.c
index 92dc98b36bde..2b5f0e701687 100644
--- a/trunk/arch/ppc/syslib/mpc8xx_devices.c
+++ b/trunk/arch/ppc/syslib/mpc8xx_devices.c
@@ -3,7 +3,7 @@
*
* MPC8xx Device descriptions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug
*
diff --git a/trunk/arch/ppc/syslib/mpc8xx_sys.c b/trunk/arch/ppc/syslib/mpc8xx_sys.c
index d3c617521603..3cc27d29e3af 100644
--- a/trunk/arch/ppc/syslib/mpc8xx_sys.c
+++ b/trunk/arch/ppc/syslib/mpc8xx_sys.c
@@ -3,7 +3,7 @@
*
* MPC8xx System descriptions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug
*
diff --git a/trunk/arch/ppc/syslib/ppc83xx_setup.c b/trunk/arch/ppc/syslib/ppc83xx_setup.c
index 1b5fe9e398d4..4da168a6ad03 100644
--- a/trunk/arch/ppc/syslib/ppc83xx_setup.c
+++ b/trunk/arch/ppc/syslib/ppc83xx_setup.c
@@ -3,7 +3,7 @@
*
* MPC83XX common board code
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/syslib/ppc83xx_setup.h b/trunk/arch/ppc/syslib/ppc83xx_setup.h
index a122a7322e5e..c766c1a5f786 100644
--- a/trunk/arch/ppc/syslib/ppc83xx_setup.h
+++ b/trunk/arch/ppc/syslib/ppc83xx_setup.h
@@ -3,7 +3,7 @@
*
* MPC83XX common board definitions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/syslib/ppc85xx_common.c b/trunk/arch/ppc/syslib/ppc85xx_common.c
index 19ad537225e4..da841dacdc13 100644
--- a/trunk/arch/ppc/syslib/ppc85xx_common.c
+++ b/trunk/arch/ppc/syslib/ppc85xx_common.c
@@ -3,7 +3,7 @@
*
* MPC85xx support routines
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/syslib/ppc85xx_common.h b/trunk/arch/ppc/syslib/ppc85xx_common.h
index 94edf32151dd..2c8f304441bf 100644
--- a/trunk/arch/ppc/syslib/ppc85xx_common.h
+++ b/trunk/arch/ppc/syslib/ppc85xx_common.h
@@ -3,7 +3,7 @@
*
* MPC85xx support routines
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/syslib/ppc85xx_setup.c b/trunk/arch/ppc/syslib/ppc85xx_setup.c
index 1a47ff4b831d..de2f90576577 100644
--- a/trunk/arch/ppc/syslib/ppc85xx_setup.c
+++ b/trunk/arch/ppc/syslib/ppc85xx_setup.c
@@ -3,7 +3,7 @@
*
* MPC85XX common board code
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/syslib/ppc85xx_setup.h b/trunk/arch/ppc/syslib/ppc85xx_setup.h
index e340b0545fb5..6e6cfe162faf 100644
--- a/trunk/arch/ppc/syslib/ppc85xx_setup.h
+++ b/trunk/arch/ppc/syslib/ppc85xx_setup.h
@@ -3,7 +3,7 @@
*
* MPC85XX common board definitions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2004 Freescale Semiconductor Inc.
*
diff --git a/trunk/arch/ppc/syslib/ppc_sys.c b/trunk/arch/ppc/syslib/ppc_sys.c
index c0b93c4191ee..603f01190816 100644
--- a/trunk/arch/ppc/syslib/ppc_sys.c
+++ b/trunk/arch/ppc/syslib/ppc_sys.c
@@ -3,7 +3,7 @@
*
* PPC System library functions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 Freescale Semiconductor Inc.
* Copyright 2005 MontaVista, Inc. by Vitaly Bordug
diff --git a/trunk/arch/ppc/syslib/pq2_devices.c b/trunk/arch/ppc/syslib/pq2_devices.c
index 6ff3aab82fc3..e960fe935325 100644
--- a/trunk/arch/ppc/syslib/pq2_devices.c
+++ b/trunk/arch/ppc/syslib/pq2_devices.c
@@ -3,7 +3,7 @@
*
* PQ2 Device descriptions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* 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
diff --git a/trunk/arch/ppc/syslib/pq2_sys.c b/trunk/arch/ppc/syslib/pq2_sys.c
index 36d6e2179940..7b6c9ebdb9e3 100644
--- a/trunk/arch/ppc/syslib/pq2_sys.c
+++ b/trunk/arch/ppc/syslib/pq2_sys.c
@@ -3,7 +3,7 @@
*
* PQ2 System descriptions
*
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* 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
diff --git a/trunk/arch/ppc64/kernel/prom.c b/trunk/arch/ppc64/kernel/prom.c
index 47cc26e78957..fbad2c360784 100644
--- a/trunk/arch/ppc64/kernel/prom.c
+++ b/trunk/arch/ppc64/kernel/prom.c
@@ -1261,7 +1261,6 @@ prom_n_addr_cells(struct device_node* np)
/* No #address-cells property for the root node, default to 1 */
return 1;
}
-EXPORT_SYMBOL_GPL(prom_n_addr_cells);
int
prom_n_size_cells(struct device_node* np)
@@ -1277,7 +1276,6 @@ prom_n_size_cells(struct device_node* np)
/* No #size-cells property for the root node, default to 1 */
return 1;
}
-EXPORT_SYMBOL_GPL(prom_n_size_cells);
/**
* Work out the sense (active-low level / active-high edge)
diff --git a/trunk/arch/sparc/lib/atomic32.c b/trunk/arch/sparc/lib/atomic32.c
index cb3cf0f22822..2e64e8c3e8e5 100644
--- a/trunk/arch/sparc/lib/atomic32.c
+++ b/trunk/arch/sparc/lib/atomic32.c
@@ -37,43 +37,17 @@ int __atomic_add_return(int i, atomic_t *v)
spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
return ret;
}
-EXPORT_SYMBOL(__atomic_add_return);
-int atomic_cmpxchg(atomic_t *v, int old, int new)
+void atomic_set(atomic_t *v, int i)
{
- int ret;
unsigned long flags;
-
spin_lock_irqsave(ATOMIC_HASH(v), flags);
- ret = v->counter;
- if (likely(ret == old))
- v->counter = new;
-
- spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
- return ret;
-}
-int atomic_add_unless(atomic_t *v, int a, int u)
-{
- int ret;
- unsigned long flags;
+ v->counter = i;
- spin_lock_irqsave(ATOMIC_HASH(v), flags);
- ret = v->counter;
- if (ret != u)
- v->counter += a;
spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
- return ret != u;
}
-static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
-/* Atomic operations are already serializing */
-void atomic_set(atomic_t *v, int i)
-{
- unsigned long flags;
-
- spin_lock_irqsave(ATOMIC_HASH(v), flags);
- v->counter = i;
- spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
-}
+EXPORT_SYMBOL(__atomic_add_return);
EXPORT_SYMBOL(atomic_set);
+
diff --git a/trunk/arch/sparc/lib/bitext.c b/trunk/arch/sparc/lib/bitext.c
index 2e168d16547f..94b05e8c906c 100644
--- a/trunk/arch/sparc/lib/bitext.c
+++ b/trunk/arch/sparc/lib/bitext.c
@@ -10,7 +10,6 @@
*/
#include
-#include
#include
#include
diff --git a/trunk/arch/sparc64/kernel/ioctl32.c b/trunk/arch/sparc64/kernel/ioctl32.c
index 196b208665a2..e62214354bb5 100644
--- a/trunk/arch/sparc64/kernel/ioctl32.c
+++ b/trunk/arch/sparc64/kernel/ioctl32.c
@@ -12,10 +12,86 @@
#define INCLUDES
#include "compat_ioctl.c"
#include
+#include
+
+/* Use this to get at 32-bit user passed pointers.
+ * See sys_sparc32.c for description about it.
+ */
+#define A(__x) compat_ptr(__x)
#define CODE
#include "compat_ioctl.c"
+struct fbcmap32 {
+ int index; /* first element (0 origin) */
+ int count;
+ u32 red;
+ u32 green;
+ u32 blue;
+};
+
+#define FBIOPUTCMAP32 _IOW('F', 3, struct fbcmap32)
+#define FBIOGETCMAP32 _IOW('F', 4, struct fbcmap32)
+
+static int fbiogetputcmap(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct fbcmap32 __user *argp = (void __user *)arg;
+ struct fbcmap __user *p = compat_alloc_user_space(sizeof(*p));
+ u32 addr;
+ int ret;
+
+ ret = copy_in_user(p, argp, 2 * sizeof(int));
+ ret |= get_user(addr, &argp->red);
+ ret |= put_user(compat_ptr(addr), &p->red);
+ ret |= get_user(addr, &argp->green);
+ ret |= put_user(compat_ptr(addr), &p->green);
+ ret |= get_user(addr, &argp->blue);
+ ret |= put_user(compat_ptr(addr), &p->blue);
+ if (ret)
+ return -EFAULT;
+ return sys_ioctl(fd, (cmd == FBIOPUTCMAP32) ? FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, (unsigned long)p);
+}
+
+struct fbcursor32 {
+ short set; /* what to set, choose from the list above */
+ short enable; /* cursor on/off */
+ struct fbcurpos pos; /* cursor position */
+ struct fbcurpos hot; /* cursor hot spot */
+ struct fbcmap32 cmap; /* color map info */
+ struct fbcurpos size; /* cursor bit map size */
+ u32 image; /* cursor image bits */
+ u32 mask; /* cursor mask bits */
+};
+
+#define FBIOSCURSOR32 _IOW('F', 24, struct fbcursor32)
+#define FBIOGCURSOR32 _IOW('F', 25, struct fbcursor32)
+
+static int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct fbcursor __user *p = compat_alloc_user_space(sizeof(*p));
+ struct fbcursor32 __user *argp = (void __user *)arg;
+ compat_uptr_t addr;
+ int ret;
+
+ ret = copy_in_user(p, argp,
+ 2 * sizeof (short) + 2 * sizeof(struct fbcurpos));
+ ret |= copy_in_user(&p->size, &argp->size, sizeof(struct fbcurpos));
+ ret |= copy_in_user(&p->cmap, &argp->cmap, 2 * sizeof(int));
+ ret |= get_user(addr, &argp->cmap.red);
+ ret |= put_user(compat_ptr(addr), &p->cmap.red);
+ ret |= get_user(addr, &argp->cmap.green);
+ ret |= put_user(compat_ptr(addr), &p->cmap.green);
+ ret |= get_user(addr, &argp->cmap.blue);
+ ret |= put_user(compat_ptr(addr), &p->cmap.blue);
+ ret |= get_user(addr, &argp->mask);
+ ret |= put_user(compat_ptr(addr), &p->mask);
+ ret |= get_user(addr, &argp->image);
+ ret |= put_user(compat_ptr(addr), &p->image);
+ if (ret)
+ return -EFAULT;
+ return sys_ioctl (fd, FBIOSCURSOR, (unsigned long)p);
+}
+
#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl)
#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
#define IOCTL_TABLE_START \
@@ -27,6 +103,22 @@ IOCTL_TABLE_START
#include
#define DECLARES
#include "compat_ioctl.c"
+COMPATIBLE_IOCTL(FBIOGTYPE)
+COMPATIBLE_IOCTL(FBIOSATTR)
+COMPATIBLE_IOCTL(FBIOGATTR)
+COMPATIBLE_IOCTL(FBIOSVIDEO)
+COMPATIBLE_IOCTL(FBIOGVIDEO)
+COMPATIBLE_IOCTL(FBIOGCURSOR32) /* This is not implemented yet. Later it should be converted... */
+COMPATIBLE_IOCTL(FBIOSCURPOS)
+COMPATIBLE_IOCTL(FBIOGCURPOS)
+COMPATIBLE_IOCTL(FBIOGCURMAX)
+/* Little k */
+/* Little v, the video4linux ioctls */
+/* And these ioctls need translation */
+/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
+HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap)
+HANDLE_IOCTL(FBIOGETCMAP32, fbiogetputcmap)
+HANDLE_IOCTL(FBIOSCURSOR32, fbiogscursor)
#if 0
HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl)
HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl)
diff --git a/trunk/arch/um/Kconfig b/trunk/arch/um/Kconfig
index 563301fe5df8..3b5f47c46907 100644
--- a/trunk/arch/um/Kconfig
+++ b/trunk/arch/um/Kconfig
@@ -7,6 +7,7 @@ config UML
bool
default y
+# XXX: does UM have a mmu/swap?
config MMU
bool
default y
@@ -35,6 +36,12 @@ config IRQ_RELEASE_METHOD
bool
default y
+menu "Host processor type and features"
+
+source "arch/i386/Kconfig.cpu"
+
+endmenu
+
menu "UML-specific options"
config MODE_TT
@@ -202,8 +209,7 @@ config MAGIC_SYSRQ
config SMP
bool "Symmetric multi-processing support (EXPERIMENTAL)"
default n
- #SMP_BROKEN is for x86_64.
- depends on MODE_TT && EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN))
+ depends on (MODE_TT && EXPERIMENTAL && !SMP_BROKEN) || (BROKEN && SMP_BROKEN)
help
This option enables UML SMP support.
It is NOT related to having a real SMP box. Not directly, at least.
diff --git a/trunk/arch/um/Kconfig.i386 b/trunk/arch/um/Kconfig.i386
index c71b39a677aa..5d92cacd56c6 100644
--- a/trunk/arch/um/Kconfig.i386
+++ b/trunk/arch/um/Kconfig.i386
@@ -1,9 +1,3 @@
-menu "Host processor type and features"
-
-source "arch/i386/Kconfig.cpu"
-
-endmenu
-
config UML_X86
bool
default y
@@ -48,3 +42,7 @@ config ARCH_HAS_SC_SIGNALS
config ARCH_REUSE_HOST_VSYSCALL_AREA
bool
default y
+
+config X86_CMPXCHG
+ bool
+ default y
diff --git a/trunk/arch/um/Makefile-i386 b/trunk/arch/um/Makefile-i386
index 7a0e04e34bf9..1f7dcb064aee 100644
--- a/trunk/arch/um/Makefile-i386
+++ b/trunk/arch/um/Makefile-i386
@@ -35,3 +35,4 @@ cflags-y += $(call cc-option,-mpreferred-stack-boundary=2)
CFLAGS += $(cflags-y)
USER_CFLAGS += $(cflags-y)
+
diff --git a/trunk/arch/um/drivers/chan_kern.c b/trunk/arch/um/drivers/chan_kern.c
index 5b58fad45290..16e7dc89f61d 100644
--- a/trunk/arch/um/drivers/chan_kern.c
+++ b/trunk/arch/um/drivers/chan_kern.c
@@ -89,7 +89,8 @@ static int not_configged_write(int fd, const char *buf, int len, void *data)
return(-EIO);
}
-static int not_configged_console_write(int fd, const char *buf, int len)
+static int not_configged_console_write(int fd, const char *buf, int len,
+ void *data)
{
my_puts("Using a channel type which is configured out of "
"UML\n");
@@ -298,7 +299,7 @@ int console_write_chan(struct list_head *chans, const char *buf, int len)
chan = list_entry(ele, struct chan, list);
if(!chan->output || (chan->ops->console_write == NULL))
continue;
- n = chan->ops->console_write(chan->fd, buf, len);
+ n = chan->ops->console_write(chan->fd, buf, len, chan->data);
if(chan->primary) ret = n;
}
return(ret);
diff --git a/trunk/arch/um/drivers/chan_user.c b/trunk/arch/um/drivers/chan_user.c
index 5d50d4a44abf..1c55d5802489 100644
--- a/trunk/arch/um/drivers/chan_user.c
+++ b/trunk/arch/um/drivers/chan_user.c
@@ -20,7 +20,7 @@
#include "choose-mode.h"
#include "mode.h"
-int generic_console_write(int fd, const char *buf, int n)
+int generic_console_write(int fd, const char *buf, int n, void *unused)
{
struct termios save, new;
int err;
diff --git a/trunk/arch/um/drivers/daemon_user.c b/trunk/arch/um/drivers/daemon_user.c
index 1bb085b2824d..c1b03f7c1daa 100644
--- a/trunk/arch/um/drivers/daemon_user.c
+++ b/trunk/arch/um/drivers/daemon_user.c
@@ -98,7 +98,7 @@ static int connect_to_switch(struct daemon_data *pri)
printk("daemon_open : control setup request failed, err = %d\n",
-n);
err = -ENOTCONN;
- goto out_free;
+ goto out;
}
n = os_read_file(pri->control, sun, sizeof(*sun));
@@ -106,14 +106,12 @@ static int connect_to_switch(struct daemon_data *pri)
printk("daemon_open : read of data socket failed, err = %d\n",
-n);
err = -ENOTCONN;
- goto out_free;
+ goto out_close;
}
pri->data_addr = sun;
return(fd);
- out_free:
- kfree(sun);
out_close:
os_close_file(fd);
out:
diff --git a/trunk/arch/um/drivers/fd.c b/trunk/arch/um/drivers/fd.c
index 3296e86a03a5..f0b888f66e05 100644
--- a/trunk/arch/um/drivers/fd.c
+++ b/trunk/arch/um/drivers/fd.c
@@ -76,6 +76,13 @@ static void fd_close(int fd, void *d)
}
}
+static int fd_console_write(int fd, const char *buf, int n, void *d)
+{
+ struct fd_chan *data = d;
+
+ return(generic_console_write(fd, buf, n, &data->tt));
+}
+
struct chan_ops fd_ops = {
.type = "fd",
.init = fd_init,
@@ -83,7 +90,7 @@ struct chan_ops fd_ops = {
.close = fd_close,
.read = generic_read,
.write = generic_write,
- .console_write = generic_console_write,
+ .console_write = fd_console_write,
.window_size = generic_window_size,
.free = generic_free,
.winch = 1,
diff --git a/trunk/arch/um/drivers/mcast_user.c b/trunk/arch/um/drivers/mcast_user.c
index afe85bfa66e0..5db136e2651c 100644
--- a/trunk/arch/um/drivers/mcast_user.c
+++ b/trunk/arch/um/drivers/mcast_user.c
@@ -54,7 +54,7 @@ static int mcast_open(void *data)
struct mcast_data *pri = data;
struct sockaddr_in *sin = pri->mcast_addr;
struct ip_mreq mreq;
- int fd, yes = 1, err = -EINVAL;
+ int fd, yes = 1, err = 0;
if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
@@ -63,40 +63,40 @@ static int mcast_open(void *data)
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0){
- err = -errno;
printk("mcast_open : data socket failed, errno = %d\n",
errno);
+ err = -errno;
goto out;
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
- err = -errno;
printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
errno);
+ err = -errno;
goto out_close;
}
/* set ttl according to config */
if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
sizeof(pri->ttl)) < 0) {
- err = -errno;
printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
errno);
+ err = -errno;
goto out_close;
}
/* set LOOP, so data does get fed back to local sockets */
if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
- err = -errno;
printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
errno);
+ err = -errno;
goto out_close;
}
/* bind socket to mcast address */
if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
- err = -errno;
printk("mcast_open : data bind failed, errno = %d\n", errno);
+ err = -errno;
goto out_close;
}
@@ -105,22 +105,22 @@ static int mcast_open(void *data)
mreq.imr_interface.s_addr = 0;
if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
&mreq, sizeof(mreq)) < 0) {
- err = -errno;
printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
errno);
printk("There appears not to be a multicast-capable network "
"interface on the host.\n");
printk("eth0 should be configured in order to use the "
"multicast transport.\n");
- goto out_close;
+ err = -errno;
+ goto out_close;
}
return fd;
out_close:
- os_close_file(fd);
+ os_close_file(fd);
out:
- return err;
+ return err;
}
static void mcast_close(int fd, void *data)
diff --git a/trunk/arch/um/drivers/port_user.c b/trunk/arch/um/drivers/port_user.c
index c43e8bb32502..ed4a1a6c5d83 100644
--- a/trunk/arch/um/drivers/port_user.c
+++ b/trunk/arch/um/drivers/port_user.c
@@ -100,6 +100,13 @@ static void port_close(int fd, void *d)
os_close_file(fd);
}
+static int port_console_write(int fd, const char *buf, int n, void *d)
+{
+ struct port_chan *data = d;
+
+ return(generic_console_write(fd, buf, n, &data->tt));
+}
+
struct chan_ops port_ops = {
.type = "port",
.init = port_init,
@@ -107,7 +114,7 @@ struct chan_ops port_ops = {
.close = port_close,
.read = generic_read,
.write = generic_write,
- .console_write = generic_console_write,
+ .console_write = port_console_write,
.window_size = generic_window_size,
.free = port_free,
.winch = 1,
diff --git a/trunk/arch/um/drivers/pty.c b/trunk/arch/um/drivers/pty.c
index 1c555c38de4d..0306a1b215b7 100644
--- a/trunk/arch/um/drivers/pty.c
+++ b/trunk/arch/um/drivers/pty.c
@@ -118,6 +118,13 @@ static int pty_open(int input, int output, int primary, void *d,
return(fd);
}
+static int pty_console_write(int fd, const char *buf, int n, void *d)
+{
+ struct pty_chan *data = d;
+
+ return(generic_console_write(fd, buf, n, &data->tt));
+}
+
struct chan_ops pty_ops = {
.type = "pty",
.init = pty_chan_init,
@@ -125,7 +132,7 @@ struct chan_ops pty_ops = {
.close = generic_close,
.read = generic_read,
.write = generic_write,
- .console_write = generic_console_write,
+ .console_write = pty_console_write,
.window_size = generic_window_size,
.free = generic_free,
.winch = 0,
@@ -138,7 +145,7 @@ struct chan_ops pts_ops = {
.close = generic_close,
.read = generic_read,
.write = generic_write,
- .console_write = generic_console_write,
+ .console_write = pty_console_write,
.window_size = generic_window_size,
.free = generic_free,
.winch = 0,
diff --git a/trunk/arch/um/drivers/tty.c b/trunk/arch/um/drivers/tty.c
index 94c9265a4f2c..6fbb670ee274 100644
--- a/trunk/arch/um/drivers/tty.c
+++ b/trunk/arch/um/drivers/tty.c
@@ -60,6 +60,13 @@ static int tty_open(int input, int output, int primary, void *d,
return(fd);
}
+static int tty_console_write(int fd, const char *buf, int n, void *d)
+{
+ struct tty_chan *data = d;
+
+ return(generic_console_write(fd, buf, n, &data->tt));
+}
+
struct chan_ops tty_ops = {
.type = "tty",
.init = tty_chan_init,
@@ -67,7 +74,7 @@ struct chan_ops tty_ops = {
.close = generic_close,
.read = generic_read,
.write = generic_write,
- .console_write = generic_console_write,
+ .console_write = tty_console_write,
.window_size = generic_window_size,
.free = generic_free,
.winch = 0,
diff --git a/trunk/arch/um/drivers/xterm.c b/trunk/arch/um/drivers/xterm.c
index aaa636661043..b530f1a6540d 100644
--- a/trunk/arch/um/drivers/xterm.c
+++ b/trunk/arch/um/drivers/xterm.c
@@ -194,6 +194,13 @@ static void xterm_free(void *d)
free(d);
}
+static int xterm_console_write(int fd, const char *buf, int n, void *d)
+{
+ struct xterm_chan *data = d;
+
+ return(generic_console_write(fd, buf, n, &data->tt));
+}
+
struct chan_ops xterm_ops = {
.type = "xterm",
.init = xterm_init,
@@ -201,7 +208,7 @@ struct chan_ops xterm_ops = {
.close = xterm_close,
.read = generic_read,
.write = generic_write,
- .console_write = generic_console_write,
+ .console_write = xterm_console_write,
.window_size = generic_window_size,
.free = xterm_free,
.winch = 1,
diff --git a/trunk/arch/um/include/chan_user.h b/trunk/arch/um/include/chan_user.h
index 659bb3cac32f..f77d9aa4c164 100644
--- a/trunk/arch/um/include/chan_user.h
+++ b/trunk/arch/um/include/chan_user.h
@@ -25,7 +25,7 @@ struct chan_ops {
void (*close)(int, void *);
int (*read)(int, char *, void *);
int (*write)(int, const char *, int, void *);
- int (*console_write)(int, const char *, int);
+ int (*console_write)(int, const char *, int, void *);
int (*window_size)(int, void *, unsigned short *, unsigned short *);
void (*free)(void *);
int winch;
@@ -37,7 +37,7 @@ extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops,
extern void generic_close(int fd, void *unused);
extern int generic_read(int fd, char *c_out, void *unused);
extern int generic_write(int fd, const char *buf, int n, void *unused);
-extern int generic_console_write(int fd, const char *buf, int n);
+extern int generic_console_write(int fd, const char *buf, int n, void *state);
extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
unsigned short *cols_out);
extern void generic_free(void *data);
diff --git a/trunk/arch/um/include/um_uaccess.h b/trunk/arch/um/include/um_uaccess.h
index f8760a3f43b0..84c0868cd561 100644
--- a/trunk/arch/um/include/um_uaccess.h
+++ b/trunk/arch/um/include/um_uaccess.h
@@ -17,25 +17,8 @@
#include "uaccess-skas.h"
#endif
-#define __under_task_size(addr, size) \
- (((unsigned long) (addr) < TASK_SIZE) && \
- (((unsigned long) (addr) + (size)) < TASK_SIZE))
-
-#define __access_ok_vsyscall(type, addr, size) \
- ((type == VERIFY_READ) && \
- ((unsigned long) (addr) >= FIXADDR_USER_START) && \
- ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
- ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))
-
-#define __addr_range_nowrap(addr, size) \
- ((unsigned long) (addr) <= ((unsigned long) (addr) + (size)))
-
#define access_ok(type, addr, size) \
- (__addr_range_nowrap(addr, size) && \
- (__under_task_size(addr, size) || \
- __access_ok_vsyscall(type, addr, size) || \
- segment_eq(get_fs(), KERNEL_DS) || \
- CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)))
+ CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
static inline int copy_from_user(void *to, const void __user *from, int n)
{
diff --git a/trunk/arch/um/kernel/skas/include/uaccess-skas.h b/trunk/arch/um/kernel/skas/include/uaccess-skas.h
index f611f83ad4ff..7da0c2def0ef 100644
--- a/trunk/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/trunk/arch/um/kernel/skas/include/uaccess-skas.h
@@ -9,8 +9,14 @@
#include "asm/errno.h"
#include "asm/fixmap.h"
-/* No SKAS-specific checking. */
-#define access_ok_skas(type, addr, size) 0
+#define access_ok_skas(type, addr, size) \
+ ((segment_eq(get_fs(), KERNEL_DS)) || \
+ (((unsigned long) (addr) < TASK_SIZE) && \
+ ((unsigned long) (addr) + (size) <= TASK_SIZE)) || \
+ ((type == VERIFY_READ ) && \
+ ((unsigned long) (addr) >= FIXADDR_USER_START) && \
+ ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
+ ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
extern int copy_from_user_skas(void *to, const void __user *from, int n);
extern int copy_to_user_skas(void __user *to, const void *from, int n);
diff --git a/trunk/arch/um/kernel/skas/uaccess.c b/trunk/arch/um/kernel/skas/uaccess.c
index a5a47528dec7..75195281081e 100644
--- a/trunk/arch/um/kernel/skas/uaccess.c
+++ b/trunk/arch/um/kernel/skas/uaccess.c
@@ -143,7 +143,7 @@ int copy_from_user_skas(void *to, const void __user *from, int n)
return(0);
}
- return(access_ok(VERIFY_READ, from, n) ?
+ return(access_ok_skas(VERIFY_READ, from, n) ?
buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
n);
}
@@ -164,7 +164,7 @@ int copy_to_user_skas(void __user *to, const void *from, int n)
return(0);
}
- return(access_ok(VERIFY_WRITE, to, n) ?
+ return(access_ok_skas(VERIFY_WRITE, to, n) ?
buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
n);
}
@@ -193,7 +193,7 @@ int strncpy_from_user_skas(char *dst, const char __user *src, int count)
return(strnlen(dst, count));
}
- if(!access_ok(VERIFY_READ, src, 1))
+ if(!access_ok_skas(VERIFY_READ, src, 1))
return(-EFAULT);
n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
@@ -221,7 +221,7 @@ int clear_user_skas(void __user *mem, int len)
return(0);
}
- return(access_ok(VERIFY_WRITE, mem, len) ?
+ return(access_ok_skas(VERIFY_WRITE, mem, len) ?
buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
}
diff --git a/trunk/arch/um/kernel/trap_kern.c b/trunk/arch/um/kernel/trap_kern.c
index 0d4c10a73607..95c8f8733baf 100644
--- a/trunk/arch/um/kernel/trap_kern.c
+++ b/trunk/arch/um/kernel/trap_kern.c
@@ -95,16 +95,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
pte = pte_offset_kernel(pmd, address);
} while(!pte_present(*pte));
err = 0;
- /* The below warning was added in place of
- * pte_mkyoung(); if (is_write) pte_mkdirty();
- * If it's triggered, we'd see normally a hang here (a clean pte is
- * marked read-only to emulate the dirty bit).
- * However, the generic code can mark a PTE writable but clean on a
- * concurrent read fault, triggering this harmlessly. So comment it out.
- */
-#if 0
WARN_ON(!pte_young(*pte) || (is_write && !pte_dirty(*pte)));
-#endif
flush_tlb_page(vma, address);
out:
up_read(&mm->mmap_sem);
diff --git a/trunk/arch/um/kernel/tt/include/uaccess-tt.h b/trunk/arch/um/kernel/tt/include/uaccess-tt.h
index b9bfe9c481c4..dc2ebfa8c54f 100644
--- a/trunk/arch/um/kernel/tt/include/uaccess-tt.h
+++ b/trunk/arch/um/kernel/tt/include/uaccess-tt.h
@@ -19,13 +19,19 @@
extern unsigned long end_vm;
extern unsigned long uml_physmem;
+#define under_task_size(addr, size) \
+ (((unsigned long) (addr) < TASK_SIZE) && \
+ (((unsigned long) (addr) + (size)) < TASK_SIZE))
+
#define is_stack(addr, size) \
(((unsigned long) (addr) < STACK_TOP) && \
((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
(((unsigned long) (addr) + (size)) <= STACK_TOP))
#define access_ok_tt(type, addr, size) \
- (is_stack(addr, size))
+ ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
+ (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
+ (under_task_size(addr, size) || is_stack(addr, size))))
extern unsigned long get_fault_addr(void);
diff --git a/trunk/arch/um/kernel/tt/uaccess.c b/trunk/arch/um/kernel/tt/uaccess.c
index 1cb60726567e..a72aa632972f 100644
--- a/trunk/arch/um/kernel/tt/uaccess.c
+++ b/trunk/arch/um/kernel/tt/uaccess.c
@@ -8,7 +8,7 @@
int copy_from_user_tt(void *to, const void __user *from, int n)
{
- if(!access_ok(VERIFY_READ, from, n))
+ if(!access_ok_tt(VERIFY_READ, from, n))
return(n);
return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr,
@@ -17,7 +17,7 @@ int copy_from_user_tt(void *to, const void __user *from, int n)
int copy_to_user_tt(void __user *to, const void *from, int n)
{
- if(!access_ok(VERIFY_WRITE, to, n))
+ if(!access_ok_tt(VERIFY_WRITE, to, n))
return(n);
return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr,
@@ -28,7 +28,7 @@ int strncpy_from_user_tt(char *dst, const char __user *src, int count)
{
int n;
- if(!access_ok(VERIFY_READ, src, 1))
+ if(!access_ok_tt(VERIFY_READ, src, 1))
return(-EFAULT);
n = __do_strncpy_from_user(dst, src, count,
@@ -47,7 +47,7 @@ int __clear_user_tt(void __user *mem, int len)
int clear_user_tt(void __user *mem, int len)
{
- if(!access_ok(VERIFY_WRITE, mem, len))
+ if(!access_ok_tt(VERIFY_WRITE, mem, len))
return(len);
return(__do_clear_user(mem, len, ¤t->thread.fault_addr,
diff --git a/trunk/arch/x86_64/kernel/i8259.c b/trunk/arch/x86_64/kernel/i8259.c
index a9368d4c4aba..c6c9791d77c1 100644
--- a/trunk/arch/x86_64/kernel/i8259.c
+++ b/trunk/arch/x86_64/kernel/i8259.c
@@ -515,7 +515,7 @@ void i8254_timer_resume(void)
}
static struct sysdev_class timer_sysclass = {
- set_kset_name("timer_pit"),
+ set_kset_name("timer"),
.resume = timer_resume,
};
diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c
index 2b64f5852bfd..ecacca9c877e 100644
--- a/trunk/block/cfq-iosched.c
+++ b/trunk/block/cfq-iosched.c
@@ -861,8 +861,8 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
* store what was left of this slice, if the queue idled out
* or was preempted
*/
- if (time_after(cfqq->slice_end, now))
- cfqq->slice_left = cfqq->slice_end - now;
+ if (time_after(now, cfqq->slice_end))
+ cfqq->slice_left = now - cfqq->slice_end;
else
cfqq->slice_left = 0;
@@ -999,7 +999,7 @@ cfq_prio_to_maxrq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
/*
* get next queue for service
*/
-static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
+static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd, int force)
{
unsigned long now = jiffies;
struct cfq_queue *cfqq;
@@ -1023,7 +1023,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
*/
if (!RB_EMPTY(&cfqq->sort_list))
goto keep_queue;
- else if (cfq_cfqq_class_sync(cfqq) &&
+ else if (!force && cfq_cfqq_class_sync(cfqq) &&
time_before(now, cfqq->slice_end)) {
if (cfq_arm_slice_timer(cfqd, cfqq))
return NULL;
@@ -1091,42 +1091,6 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
return dispatched;
}
-static int
-cfq_forced_dispatch_cfqqs(struct list_head *list)
-{
- int dispatched = 0;
- struct cfq_queue *cfqq, *next;
- struct cfq_rq *crq;
-
- list_for_each_entry_safe(cfqq, next, list, cfq_list) {
- while ((crq = cfqq->next_crq)) {
- cfq_dispatch_insert(cfqq->cfqd->queue, crq);
- dispatched++;
- }
- BUG_ON(!list_empty(&cfqq->fifo));
- }
- return dispatched;
-}
-
-static int
-cfq_forced_dispatch(struct cfq_data *cfqd)
-{
- int i, dispatched = 0;
-
- for (i = 0; i < CFQ_PRIO_LISTS; i++)
- dispatched += cfq_forced_dispatch_cfqqs(&cfqd->rr_list[i]);
-
- dispatched += cfq_forced_dispatch_cfqqs(&cfqd->busy_rr);
- dispatched += cfq_forced_dispatch_cfqqs(&cfqd->cur_rr);
- dispatched += cfq_forced_dispatch_cfqqs(&cfqd->idle_rr);
-
- cfq_slice_expired(cfqd, 0);
-
- BUG_ON(cfqd->busy_queues);
-
- return dispatched;
-}
-
static int
cfq_dispatch_requests(request_queue_t *q, int force)
{
@@ -1136,10 +1100,7 @@ cfq_dispatch_requests(request_queue_t *q, int force)
if (!cfqd->busy_queues)
return 0;
- if (unlikely(force))
- return cfq_forced_dispatch(cfqd);
-
- cfqq = cfq_select_queue(cfqd);
+ cfqq = cfq_select_queue(cfqd, force);
if (cfqq) {
int max_dispatch;
@@ -1154,9 +1115,12 @@ cfq_dispatch_requests(request_queue_t *q, int force)
cfq_clear_cfqq_wait_request(cfqq);
del_timer(&cfqd->idle_slice_timer);
- max_dispatch = cfqd->cfq_quantum;
- if (cfq_class_idle(cfqq))
- max_dispatch = 1;
+ if (!force) {
+ max_dispatch = cfqd->cfq_quantum;
+ if (cfq_class_idle(cfqq))
+ max_dispatch = 1;
+ } else
+ max_dispatch = INT_MAX;
return __cfq_dispatch_requests(cfqd, cfqq, max_dispatch);
}
diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c
index e4c58827bb46..d4a49a3df829 100644
--- a/trunk/block/elevator.c
+++ b/trunk/block/elevator.c
@@ -155,10 +155,9 @@ static void elevator_setup_default(void)
/*
* If the given scheduler is not available, fall back to no-op.
*/
- if ((e = elevator_find(chosen_elevator)))
- elevator_put(e);
- else
+ if (!(e = elevator_find(chosen_elevator)))
strcpy(chosen_elevator, "noop");
+ elevator_put(e);
}
static int __init elevator_setup(char *str)
@@ -191,14 +190,14 @@ int elevator_init(request_queue_t *q, char *name)
eq = kmalloc(sizeof(struct elevator_queue), GFP_KERNEL);
if (!eq) {
- elevator_put(e);
+ elevator_put(e->elevator_type);
return -ENOMEM;
}
ret = elevator_attach(q, e, eq);
if (ret) {
kfree(eq);
- elevator_put(e);
+ elevator_put(e->elevator_type);
}
return ret;
@@ -226,7 +225,6 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq)
if (q->last_merge == rq)
q->last_merge = NULL;
- q->nr_sorted--;
boundary = q->end_sector;
@@ -285,7 +283,6 @@ void elv_merge_requests(request_queue_t *q, struct request *rq,
if (e->ops->elevator_merge_req_fn)
e->ops->elevator_merge_req_fn(q, rq, next);
- q->nr_sorted--;
q->last_merge = rq;
}
@@ -317,20 +314,6 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
__elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
}
-static void elv_drain_elevator(request_queue_t *q)
-{
- static int printed;
- while (q->elevator->ops->elevator_dispatch_fn(q, 1))
- ;
- if (q->nr_sorted == 0)
- return;
- if (printed++ < 10) {
- printk(KERN_ERR "%s: forced dispatching is broken "
- "(nr_sorted=%u), please report this\n",
- q->elevator->elevator_type->elevator_name, q->nr_sorted);
- }
-}
-
void __elv_add_request(request_queue_t *q, struct request *rq, int where,
int plug)
{
@@ -365,7 +348,9 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
case ELEVATOR_INSERT_BACK:
rq->flags |= REQ_SOFTBARRIER;
- elv_drain_elevator(q);
+
+ while (q->elevator->ops->elevator_dispatch_fn(q, 1))
+ ;
list_add_tail(&rq->queuelist, &q->queue_head);
/*
* We kick the queue here for the following reasons.
@@ -384,7 +369,6 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
case ELEVATOR_INSERT_SORT:
BUG_ON(!blk_fs_request(rq));
rq->flags |= REQ_SORTED;
- q->nr_sorted++;
if (q->last_merge == NULL && rq_mergeable(rq))
q->last_merge = rq;
/*
@@ -541,19 +525,33 @@ int elv_queue_empty(request_queue_t *q)
struct request *elv_latter_request(request_queue_t *q, struct request *rq)
{
+ struct list_head *next;
+
elevator_t *e = q->elevator;
if (e->ops->elevator_latter_req_fn)
return e->ops->elevator_latter_req_fn(q, rq);
+
+ next = rq->queuelist.next;
+ if (next != &q->queue_head && next != &rq->queuelist)
+ return list_entry_rq(next);
+
return NULL;
}
struct request *elv_former_request(request_queue_t *q, struct request *rq)
{
+ struct list_head *prev;
+
elevator_t *e = q->elevator;
if (e->ops->elevator_former_req_fn)
return e->ops->elevator_former_req_fn(q, rq);
+
+ prev = rq->queuelist.prev;
+ if (prev != &q->queue_head && prev != &rq->queuelist)
+ return list_entry_rq(prev);
+
return NULL;
}
@@ -693,15 +691,13 @@ static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
set_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
- elv_drain_elevator(q);
+ while (q->elevator->ops->elevator_dispatch_fn(q, 1))
+ ;
while (q->rq.elvpriv) {
- blk_remove_plug(q);
- q->request_fn(q);
spin_unlock_irq(q->queue_lock);
msleep(10);
spin_lock_irq(q->queue_lock);
- elv_drain_elevator(q);
}
spin_unlock_irq(q->queue_lock);
@@ -748,15 +744,13 @@ static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
ssize_t elv_iosched_store(request_queue_t *q, const char *name, size_t count)
{
char elevator_name[ELV_NAME_MAX];
- size_t len;
struct elevator_type *e;
- elevator_name[sizeof(elevator_name) - 1] = '\0';
- strncpy(elevator_name, name, sizeof(elevator_name) - 1);
- len = strlen(elevator_name);
+ memset(elevator_name, 0, sizeof(elevator_name));
+ strncpy(elevator_name, name, sizeof(elevator_name));
- if (len && elevator_name[len - 1] == '\n')
- elevator_name[len - 1] = '\0';
+ if (elevator_name[strlen(elevator_name) - 1] == '\n')
+ elevator_name[strlen(elevator_name) - 1] = '\0';
e = elevator_get(elevator_name);
if (!e) {
diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c
index f04609d553b8..54aec4a1ae13 100644
--- a/trunk/block/genhd.c
+++ b/trunk/block/genhd.c
@@ -391,14 +391,12 @@ static ssize_t disk_stats_read(struct gendisk * disk, char *page)
"%8u %8u %8llu %8u "
"%8u %8u %8u"
"\n",
- disk_stat_read(disk, ios[READ]),
- disk_stat_read(disk, merges[READ]),
- (unsigned long long)disk_stat_read(disk, sectors[READ]),
- jiffies_to_msecs(disk_stat_read(disk, ticks[READ])),
- disk_stat_read(disk, ios[WRITE]),
- disk_stat_read(disk, merges[WRITE]),
- (unsigned long long)disk_stat_read(disk, sectors[WRITE]),
- jiffies_to_msecs(disk_stat_read(disk, ticks[WRITE])),
+ disk_stat_read(disk, ios[0]), disk_stat_read(disk, merges[0]),
+ (unsigned long long)disk_stat_read(disk, sectors[0]),
+ jiffies_to_msecs(disk_stat_read(disk, ticks[0])),
+ disk_stat_read(disk, ios[1]), disk_stat_read(disk, merges[1]),
+ (unsigned long long)disk_stat_read(disk, sectors[1]),
+ jiffies_to_msecs(disk_stat_read(disk, ticks[1])),
disk->in_flight,
jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
diff --git a/trunk/block/noop-iosched.c b/trunk/block/noop-iosched.c
index f370e4a7fe6d..e54f006e7e60 100644
--- a/trunk/block/noop-iosched.c
+++ b/trunk/block/noop-iosched.c
@@ -7,94 +7,21 @@
#include
#include
-struct noop_data {
- struct list_head queue;
-};
-
-static void noop_merged_requests(request_queue_t *q, struct request *rq,
- struct request *next)
-{
- list_del_init(&next->queuelist);
-}
-
-static int noop_dispatch(request_queue_t *q, int force)
-{
- struct noop_data *nd = q->elevator->elevator_data;
-
- if (!list_empty(&nd->queue)) {
- struct request *rq;
- rq = list_entry(nd->queue.next, struct request, queuelist);
- list_del_init(&rq->queuelist);
- elv_dispatch_sort(q, rq);
- return 1;
- }
- return 0;
-}
-
-static void noop_add_request(request_queue_t *q, struct request *rq)
-{
- struct noop_data *nd = q->elevator->elevator_data;
-
- list_add_tail(&rq->queuelist, &nd->queue);
-}
-
-static int noop_queue_empty(request_queue_t *q)
+static void elevator_noop_add_request(request_queue_t *q, struct request *rq)
{
- struct noop_data *nd = q->elevator->elevator_data;
-
- return list_empty(&nd->queue);
-}
-
-static struct request *
-noop_former_request(request_queue_t *q, struct request *rq)
-{
- struct noop_data *nd = q->elevator->elevator_data;
-
- if (rq->queuelist.prev == &nd->queue)
- return NULL;
- return list_entry(rq->queuelist.prev, struct request, queuelist);
-}
-
-static struct request *
-noop_latter_request(request_queue_t *q, struct request *rq)
-{
- struct noop_data *nd = q->elevator->elevator_data;
-
- if (rq->queuelist.next == &nd->queue)
- return NULL;
- return list_entry(rq->queuelist.next, struct request, queuelist);
+ rq->flags |= REQ_NOMERGE;
+ elv_dispatch_add_tail(q, rq);
}
-static int noop_init_queue(request_queue_t *q, elevator_t *e)
+static int elevator_noop_dispatch(request_queue_t *q, int force)
{
- struct noop_data *nd;
-
- nd = kmalloc(sizeof(*nd), GFP_KERNEL);
- if (!nd)
- return -ENOMEM;
- INIT_LIST_HEAD(&nd->queue);
- e->elevator_data = nd;
return 0;
}
-static void noop_exit_queue(elevator_t *e)
-{
- struct noop_data *nd = e->elevator_data;
-
- BUG_ON(!list_empty(&nd->queue));
- kfree(nd);
-}
-
static struct elevator_type elevator_noop = {
.ops = {
- .elevator_merge_req_fn = noop_merged_requests,
- .elevator_dispatch_fn = noop_dispatch,
- .elevator_add_req_fn = noop_add_request,
- .elevator_queue_empty_fn = noop_queue_empty,
- .elevator_former_req_fn = noop_former_request,
- .elevator_latter_req_fn = noop_latter_request,
- .elevator_init_fn = noop_init_queue,
- .elevator_exit_fn = noop_exit_queue,
+ .elevator_dispatch_fn = elevator_noop_dispatch,
+ .elevator_add_req_fn = elevator_noop_add_request,
},
.elevator_name = "noop",
.elevator_owner = THIS_MODULE,
diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c
index 606f8733a776..6a4da417c16b 100644
--- a/trunk/drivers/acpi/bus.c
+++ b/trunk/drivers/acpi/bus.c
@@ -28,7 +28,6 @@
#include
#include
#include
-#include
#include
#include
#ifdef CONFIG_X86
@@ -755,7 +754,7 @@ static int __init acpi_init(void)
result = acpi_bus_init();
if (!result) {
-#ifdef CONFIG_PM_LEGACY
+#ifdef CONFIG_PM
if (!PM_IS_ACTIVE())
pm_active = 1;
else {
diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c
index 59dacb6552c0..98f6c02d6790 100644
--- a/trunk/drivers/base/firmware_class.c
+++ b/trunk/drivers/base/firmware_class.c
@@ -526,23 +526,18 @@ request_firmware_work_func(void *arg)
{
struct firmware_work *fw_work = arg;
const struct firmware *fw;
- int ret;
if (!arg) {
WARN_ON(1);
return 0;
}
daemonize("%s/%s", "firmware", fw_work->name);
- ret = _request_firmware(&fw, fw_work->name, fw_work->device,
+ _request_firmware(&fw, fw_work->name, fw_work->device,
fw_work->hotplug);
- if (ret < 0)
- fw_work->cont(NULL, fw_work->context);
- else {
- fw_work->cont(fw, fw_work->context);
- release_firmware(fw);
- }
+ fw_work->cont(fw, fw_work->context);
+ release_firmware(fw);
module_put(fw_work->module);
kfree(fw_work);
- return ret;
+ return 0;
}
/**
@@ -591,8 +586,6 @@ request_firmware_nowait(
if (ret < 0) {
fw_work->cont(NULL, fw_work->context);
- module_put(fw_work->module);
- kfree(fw_work);
return ret;
}
return 0;
diff --git a/trunk/drivers/block/pktcdvd.c b/trunk/drivers/block/pktcdvd.c
index c0233efabeba..59e5982a5db3 100644
--- a/trunk/drivers/block/pktcdvd.c
+++ b/trunk/drivers/block/pktcdvd.c
@@ -1188,7 +1188,7 @@ static void pkt_count_states(struct pktcdvd_device *pd, int *states)
struct packet_data *pkt;
int i;
- for (i = 0; i < PACKET_NUM_STATES; i++)
+ for (i = 0; i <= PACKET_NUM_STATES; i++)
states[i] = 0;
spin_lock(&pd->cdrw.active_list_lock);
diff --git a/trunk/drivers/char/agp/uninorth-agp.c b/trunk/drivers/char/agp/uninorth-agp.c
index 50947e38501a..c8255312b8c1 100644
--- a/trunk/drivers/char/agp/uninorth-agp.c
+++ b/trunk/drivers/char/agp/uninorth-agp.c
@@ -557,10 +557,6 @@ static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = {
.device_id = PCI_DEVICE_ID_APPLE_U3H_AGP,
.chipset_name = "U3H",
},
- {
- .device_id = PCI_DEVICE_ID_APPLE_IPID2_AGP,
- .chipset_name = "UniNorth/Intrepid2",
- },
};
static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
diff --git a/trunk/drivers/char/i8k.c b/trunk/drivers/char/i8k.c
index f3c3aaf4560e..6c4b3f986d0c 100644
--- a/trunk/drivers/char/i8k.c
+++ b/trunk/drivers/char/i8k.c
@@ -99,9 +99,7 @@ struct smm_regs {
static inline char *i8k_get_dmi_data(int field)
{
- char *dmi_data = dmi_get_system_info(field);
-
- return dmi_data && *dmi_data ? dmi_data : "?";
+ return dmi_get_system_info(field) ? : "N/A";
}
/*
@@ -398,7 +396,7 @@ static int i8k_proc_show(struct seq_file *seq, void *offset)
return seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
I8K_PROC_FMT,
bios_version,
- i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
+ dmi_get_system_info(DMI_PRODUCT_SERIAL) ? : "N/A",
cpu_temp,
left_fan, right_fan, left_speed, right_speed,
ac_power, fn_key);
diff --git a/trunk/drivers/char/pcmcia/Kconfig b/trunk/drivers/char/pcmcia/Kconfig
index 27c1179ee527..d22bfdc13563 100644
--- a/trunk/drivers/char/pcmcia/Kconfig
+++ b/trunk/drivers/char/pcmcia/Kconfig
@@ -18,29 +18,5 @@ config SYNCLINK_CS
The module will be called synclinkmp. If you want to do that, say M
here.
-config CARDMAN_4000
- tristate "Omnikey Cardman 4000 support"
- depends on PCMCIA
- help
- Enable support for the Omnikey Cardman 4000 PCMCIA Smartcard
- reader.
-
- This kernel driver requires additional userspace support, either
- by the vendor-provided PC/SC ifd_handler (http://www.omnikey.com/),
- or via the cm4000 backend of OpenCT (http://www.opensc.com/).
-
-config CARDMAN_4040
- tristate "Omnikey CardMan 4040 support"
- depends on PCMCIA
- help
- Enable support for the Omnikey CardMan 4040 PCMCIA Smartcard
- reader.
-
- This card is basically a USB CCID device connected to a FIFO
- in I/O space. To use the kernel driver, you will need either the
- PC/SC ifdhandler provided from the Omnikey homepage
- (http://www.omnikey.com/), or a current development version of OpenCT
- (http://www.opensc.org/).
-
endmenu
diff --git a/trunk/drivers/char/pcmcia/Makefile b/trunk/drivers/char/pcmcia/Makefile
index 0aae20985d57..1fcd4c591958 100644
--- a/trunk/drivers/char/pcmcia/Makefile
+++ b/trunk/drivers/char/pcmcia/Makefile
@@ -5,5 +5,3 @@
#
obj-$(CONFIG_SYNCLINK_CS) += synclink_cs.o
-obj-$(CONFIG_CARDMAN_4000) += cm4000_cs.o
-obj-$(CONFIG_CARDMAN_4040) += cm4040_cs.o
diff --git a/trunk/drivers/char/pcmcia/cm4000_cs.c b/trunk/drivers/char/pcmcia/cm4000_cs.c
deleted file mode 100644
index ef011ef5dc46..000000000000
--- a/trunk/drivers/char/pcmcia/cm4000_cs.c
+++ /dev/null
@@ -1,2078 +0,0 @@
- /*
- * A driver for the PCMCIA Smartcard Reader "Omnikey CardMan Mobile 4000"
- *
- * cm4000_cs.c support.linux@omnikey.com
- *
- * Tue Oct 23 11:32:43 GMT 2001 herp - cleaned up header files
- * Sun Jan 20 10:11:15 MET 2002 herp - added modversion header files
- * Thu Nov 14 16:34:11 GMT 2002 mh - added PPS functionality
- * Tue Nov 19 16:36:27 GMT 2002 mh - added SUSPEND/RESUME functionailty
- * Wed Jul 28 12:55:01 CEST 2004 mh - kernel 2.6 adjustments
- *
- * current version: 2.4.0gm4
- *
- * (C) 2000,2001,2002,2003,2004 Omnikey AG
- *
- * (C) 2005 Harald Welte
- * - Adhere to Kernel CodingStyle
- * - Port to 2.6.13 "new" style PCMCIA
- * - Check for copy_{from,to}_user return values
- * - Use nonseekable_open()
- *
- * All rights reserved. Licensed under dual BSD/GPL license.
- */
-
-/* #define PCMCIA_DEBUG 6 */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-/* #define ATR_CSUM */
-
-#ifdef PCMCIA_DEBUG
-#define reader_to_dev(x) (&handle_to_dev(x->link.handle))
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0600);
-#define DEBUGP(n, rdr, x, args...) do { \
- if (pc_debug >= (n)) \
- dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
- __FUNCTION__ , ## args); \
- } while (0)
-#else
-#define DEBUGP(n, rdr, x, args...)
-#endif
-static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte";
-
-#define T_1SEC (HZ)
-#define T_10MSEC msecs_to_jiffies(10)
-#define T_20MSEC msecs_to_jiffies(20)
-#define T_40MSEC msecs_to_jiffies(40)
-#define T_50MSEC msecs_to_jiffies(50)
-#define T_100MSEC msecs_to_jiffies(100)
-#define T_500MSEC msecs_to_jiffies(500)
-
-static void cm4000_detach(dev_link_t *link);
-static void cm4000_release(dev_link_t *link);
-
-static int major; /* major number we get from the kernel */
-
-/* note: the first state has to have number 0 always */
-
-#define M_FETCH_ATR 0
-#define M_TIMEOUT_WAIT 1
-#define M_READ_ATR_LEN 2
-#define M_READ_ATR 3
-#define M_ATR_PRESENT 4
-#define M_BAD_CARD 5
-#define M_CARDOFF 6
-
-#define LOCK_IO 0
-#define LOCK_MONITOR 1
-
-#define IS_AUTOPPS_ACT 6
-#define IS_PROCBYTE_PRESENT 7
-#define IS_INVREV 8
-#define IS_ANY_T0 9
-#define IS_ANY_T1 10
-#define IS_ATR_PRESENT 11
-#define IS_ATR_VALID 12
-#define IS_CMM_ABSENT 13
-#define IS_BAD_LENGTH 14
-#define IS_BAD_CSUM 15
-#define IS_BAD_CARD 16
-
-#define REG_FLAGS0(x) (x + 0)
-#define REG_FLAGS1(x) (x + 1)
-#define REG_NUM_BYTES(x) (x + 2)
-#define REG_BUF_ADDR(x) (x + 3)
-#define REG_BUF_DATA(x) (x + 4)
-#define REG_NUM_SEND(x) (x + 5)
-#define REG_BAUDRATE(x) (x + 6)
-#define REG_STOPBITS(x) (x + 7)
-
-struct cm4000_dev {
- dev_link_t link; /* pcmcia link */
- dev_node_t node; /* OS node (major,minor) */
-
- unsigned char atr[MAX_ATR];
- unsigned char rbuf[512];
- unsigned char sbuf[512];
-
- wait_queue_head_t devq; /* when removing cardman must not be
- zeroed! */
-
- wait_queue_head_t ioq; /* if IO is locked, wait on this Q */
- wait_queue_head_t atrq; /* wait for ATR valid */
- wait_queue_head_t readq; /* used by write to wake blk.read */
-
- /* warning: do not move this fields.
- * initialising to zero depends on it - see ZERO_DEV below. */
- unsigned char atr_csum;
- unsigned char atr_len_retry;
- unsigned short atr_len;
- unsigned short rlen; /* bytes avail. after write */
- unsigned short rpos; /* latest read pos. write zeroes */
- unsigned char procbyte; /* T=0 procedure byte */
- unsigned char mstate; /* state of card monitor */
- unsigned char cwarn; /* slow down warning */
- unsigned char flags0; /* cardman IO-flags 0 */
- unsigned char flags1; /* cardman IO-flags 1 */
- unsigned int mdelay; /* variable monitor speeds, in jiffies */
-
- unsigned int baudv; /* baud value for speed */
- unsigned char ta1;
- unsigned char proto; /* T=0, T=1, ... */
- unsigned long flags; /* lock+flags (MONITOR,IO,ATR) * for concurrent
- access */
-
- unsigned char pts[4];
-
- struct timer_list timer; /* used to keep monitor running */
- int monitor_running;
-};
-
-#define ZERO_DEV(dev) \
- memset(&dev->atr_csum,0, \
- sizeof(struct cm4000_dev) - \
- /*link*/ sizeof(dev_link_t) - \
- /*node*/ sizeof(dev_node_t) - \
- /*atr*/ MAX_ATR*sizeof(char) - \
- /*rbuf*/ 512*sizeof(char) - \
- /*sbuf*/ 512*sizeof(char) - \
- /*queue*/ 4*sizeof(wait_queue_head_t))
-
-static dev_info_t dev_info = MODULE_NAME;
-static dev_link_t *dev_table[CM4000_MAX_DEV];
-
-/* This table doesn't use spaces after the comma between fields and thus
- * violates CodingStyle. However, I don't really think wrapping it around will
- * make it any clearer to read -HW */
-static unsigned char fi_di_table[10][14] = {
-/*FI 00 01 02 03 04 05 06 07 08 09 10 11 12 13 */
-/*DI */
-/* 0 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
-/* 1 */ {0x01,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x91,0x11,0x11,0x11,0x11},
-/* 2 */ {0x02,0x12,0x22,0x32,0x11,0x11,0x11,0x11,0x11,0x92,0xA2,0xB2,0x11,0x11},
-/* 3 */ {0x03,0x13,0x23,0x33,0x43,0x53,0x63,0x11,0x11,0x93,0xA3,0xB3,0xC3,0xD3},
-/* 4 */ {0x04,0x14,0x24,0x34,0x44,0x54,0x64,0x11,0x11,0x94,0xA4,0xB4,0xC4,0xD4},
-/* 5 */ {0x00,0x15,0x25,0x35,0x45,0x55,0x65,0x11,0x11,0x95,0xA5,0xB5,0xC5,0xD5},
-/* 6 */ {0x06,0x16,0x26,0x36,0x46,0x56,0x66,0x11,0x11,0x96,0xA6,0xB6,0xC6,0xD6},
-/* 7 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
-/* 8 */ {0x08,0x11,0x28,0x38,0x48,0x58,0x68,0x11,0x11,0x98,0xA8,0xB8,0xC8,0xD8},
-/* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9}
-};
-
-#ifndef PCMCIA_DEBUG
-#define xoutb outb
-#define xinb inb
-#else
-static inline void xoutb(unsigned char val, unsigned short port)
-{
- if (pc_debug >= 7)
- printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
- outb(val, port);
-}
-static inline unsigned char xinb(unsigned short port)
-{
- unsigned char val;
-
- val = inb(port);
- if (pc_debug >= 7)
- printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
-
- return val;
-}
-#endif
-
-#define b_0000 15
-#define b_0001 14
-#define b_0010 13
-#define b_0011 12
-#define b_0100 11
-#define b_0101 10
-#define b_0110 9
-#define b_0111 8
-#define b_1000 7
-#define b_1001 6
-#define b_1010 5
-#define b_1011 4
-#define b_1100 3
-#define b_1101 2
-#define b_1110 1
-#define b_1111 0
-
-static unsigned char irtab[16] = {
- b_0000, b_1000, b_0100, b_1100,
- b_0010, b_1010, b_0110, b_1110,
- b_0001, b_1001, b_0101, b_1101,
- b_0011, b_1011, b_0111, b_1111
-};
-
-static void str_invert_revert(unsigned char *b, int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- b[i] = (irtab[b[i] & 0x0f] << 4) | irtab[b[i] >> 4];
-}
-
-static unsigned char invert_revert(unsigned char ch)
-{
- return (irtab[ch & 0x0f] << 4) | irtab[ch >> 4];
-}
-
-#define ATRLENCK(dev,pos) \
- if (pos>=dev->atr_len || pos>=MAX_ATR) \
- goto return_0;
-
-static unsigned int calc_baudv(unsigned char fidi)
-{
- unsigned int wcrcf, wbrcf, fi_rfu, di_rfu;
-
- fi_rfu = 372;
- di_rfu = 1;
-
- /* FI */
- switch ((fidi >> 4) & 0x0F) {
- case 0x00:
- wcrcf = 372;
- break;
- case 0x01:
- wcrcf = 372;
- break;
- case 0x02:
- wcrcf = 558;
- break;
- case 0x03:
- wcrcf = 744;
- break;
- case 0x04:
- wcrcf = 1116;
- break;
- case 0x05:
- wcrcf = 1488;
- break;
- case 0x06:
- wcrcf = 1860;
- break;
- case 0x07:
- wcrcf = fi_rfu;
- break;
- case 0x08:
- wcrcf = fi_rfu;
- break;
- case 0x09:
- wcrcf = 512;
- break;
- case 0x0A:
- wcrcf = 768;
- break;
- case 0x0B:
- wcrcf = 1024;
- break;
- case 0x0C:
- wcrcf = 1536;
- break;
- case 0x0D:
- wcrcf = 2048;
- break;
- default:
- wcrcf = fi_rfu;
- break;
- }
-
- /* DI */
- switch (fidi & 0x0F) {
- case 0x00:
- wbrcf = di_rfu;
- break;
- case 0x01:
- wbrcf = 1;
- break;
- case 0x02:
- wbrcf = 2;
- break;
- case 0x03:
- wbrcf = 4;
- break;
- case 0x04:
- wbrcf = 8;
- break;
- case 0x05:
- wbrcf = 16;
- break;
- case 0x06:
- wbrcf = 32;
- break;
- case 0x07:
- wbrcf = di_rfu;
- break;
- case 0x08:
- wbrcf = 12;
- break;
- case 0x09:
- wbrcf = 20;
- break;
- default:
- wbrcf = di_rfu;
- break;
- }
-
- return (wcrcf / wbrcf);
-}
-
-static unsigned short io_read_num_rec_bytes(ioaddr_t iobase, unsigned short *s)
-{
- unsigned short tmp;
-
- tmp = *s = 0;
- do {
- *s = tmp;
- tmp = inb(REG_NUM_BYTES(iobase)) |
- (inb(REG_FLAGS0(iobase)) & 4 ? 0x100 : 0);
- } while (tmp != *s);
-
- return *s;
-}
-
-static int parse_atr(struct cm4000_dev *dev)
-{
- unsigned char any_t1, any_t0;
- unsigned char ch, ifno;
- int ix, done;
-
- DEBUGP(3, dev, "-> parse_atr: dev->atr_len = %i\n", dev->atr_len);
-
- if (dev->atr_len < 3) {
- DEBUGP(5, dev, "parse_atr: atr_len < 3\n");
- return 0;
- }
-
- if (dev->atr[0] == 0x3f)
- set_bit(IS_INVREV, &dev->flags);
- else
- clear_bit(IS_INVREV, &dev->flags);
- ix = 1;
- ifno = 1;
- ch = dev->atr[1];
- dev->proto = 0; /* XXX PROTO */
- any_t1 = any_t0 = done = 0;
- dev->ta1 = 0x11; /* defaults to 9600 baud */
- do {
- if (ifno == 1 && (ch & 0x10)) {
- /* read first interface byte and TA1 is present */
- dev->ta1 = dev->atr[2];
- DEBUGP(5, dev, "Card says FiDi is 0x%.2x\n", dev->ta1);
- ifno++;
- } else if ((ifno == 2) && (ch & 0x10)) { /* TA(2) */
- dev->ta1 = 0x11;
- ifno++;
- }
-
- DEBUGP(5, dev, "Yi=%.2x\n", ch & 0xf0);
- ix += ((ch & 0x10) >> 4) /* no of int.face chars */
- +((ch & 0x20) >> 5)
- + ((ch & 0x40) >> 6)
- + ((ch & 0x80) >> 7);
- /* ATRLENCK(dev,ix); */
- if (ch & 0x80) { /* TDi */
- ch = dev->atr[ix];
- if ((ch & 0x0f)) {
- any_t1 = 1;
- DEBUGP(5, dev, "card is capable of T=1\n");
- } else {
- any_t0 = 1;
- DEBUGP(5, dev, "card is capable of T=0\n");
- }
- } else
- done = 1;
- } while (!done);
-
- DEBUGP(5, dev, "ix=%d noHist=%d any_t1=%d\n",
- ix, dev->atr[1] & 15, any_t1);
- if (ix + 1 + (dev->atr[1] & 0x0f) + any_t1 != dev->atr_len) {
- DEBUGP(5, dev, "length error\n");
- return 0;
- }
- if (any_t0)
- set_bit(IS_ANY_T0, &dev->flags);
-
- if (any_t1) { /* compute csum */
- dev->atr_csum = 0;
-#ifdef ATR_CSUM
- for (i = 1; i < dev->atr_len; i++)
- dev->atr_csum ^= dev->atr[i];
- if (dev->atr_csum) {
- set_bit(IS_BAD_CSUM, &dev->flags);
- DEBUGP(5, dev, "bad checksum\n");
- goto return_0;
- }
-#endif
- if (any_t0 == 0)
- dev->proto = 1; /* XXX PROTO */
- set_bit(IS_ANY_T1, &dev->flags);
- }
-
- return 1;
-}
-
-struct card_fixup {
- char atr[12];
- u_int8_t atr_len;
- u_int8_t stopbits;
-};
-
-static struct card_fixup card_fixups[] = {
- { /* ACOS */
- .atr = { 0x3b, 0xb3, 0x11, 0x00, 0x00, 0x41, 0x01 },
- .atr_len = 7,
- .stopbits = 0x03,
- },
- { /* Motorola */
- .atr = {0x3b, 0x76, 0x13, 0x00, 0x00, 0x80, 0x62, 0x07,
- 0x41, 0x81, 0x81 },
- .atr_len = 11,
- .stopbits = 0x04,
- },
-};
-
-static void set_cardparameter(struct cm4000_dev *dev)
-{
- int i;
- ioaddr_t iobase = dev->link.io.BasePort1;
- u_int8_t stopbits = 0x02; /* ISO default */
-
- DEBUGP(3, dev, "-> set_cardparameter\n");
-
- dev->flags1 = dev->flags1 | (((dev->baudv - 1) & 0x0100) >> 8);
- xoutb(dev->flags1, REG_FLAGS1(iobase));
- DEBUGP(5, dev, "flags1 = 0x%02x\n", dev->flags1);
-
- /* set baudrate */
- xoutb((unsigned char)((dev->baudv - 1) & 0xFF), REG_BAUDRATE(iobase));
-
- DEBUGP(5, dev, "baudv = %i -> write 0x%02x\n", dev->baudv,
- ((dev->baudv - 1) & 0xFF));
-
- /* set stopbits */
- for (i = 0; i < ARRAY_SIZE(card_fixups); i++) {
- if (!memcmp(dev->atr, card_fixups[i].atr,
- card_fixups[i].atr_len))
- stopbits = card_fixups[i].stopbits;
- }
- xoutb(stopbits, REG_STOPBITS(iobase));
-
- DEBUGP(3, dev, "<- set_cardparameter\n");
-}
-
-static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
-{
-
- unsigned long tmp, i;
- unsigned short num_bytes_read;
- unsigned char pts_reply[4];
- ssize_t rc;
- ioaddr_t iobase = dev->link.io.BasePort1;
-
- rc = 0;
-
- DEBUGP(3, dev, "-> set_protocol\n");
- DEBUGP(5, dev, "ptsreq->Protocol = 0x%.8x, ptsreq->Flags=0x%.8x, "
- "ptsreq->pts1=0x%.2x, ptsreq->pts2=0x%.2x, "
- "ptsreq->pts3=0x%.2x\n", (unsigned int)ptsreq->protocol,
- (unsigned int)ptsreq->flags, ptsreq->pts1, ptsreq->pts2,
- ptsreq->pts3);
-
- /* Fill PTS structure */
- dev->pts[0] = 0xff;
- dev->pts[1] = 0x00;
- tmp = ptsreq->protocol;
- while ((tmp = (tmp >> 1)) > 0)
- dev->pts[1]++;
- dev->proto = dev->pts[1]; /* Set new protocol */
- dev->pts[1] = (0x01 << 4) | (dev->pts[1]);
-
- /* Correct Fi/Di according to CM4000 Fi/Di table */
- DEBUGP(5, dev, "Ta(1) from ATR is 0x%.2x\n", dev->ta1);
- /* set Fi/Di according to ATR TA(1) */
- dev->pts[2] = fi_di_table[dev->ta1 & 0x0F][(dev->ta1 >> 4) & 0x0F];
-
- /* Calculate PCK character */
- dev->pts[3] = dev->pts[0] ^ dev->pts[1] ^ dev->pts[2];
-
- DEBUGP(5, dev, "pts0=%.2x, pts1=%.2x, pts2=%.2x, pts3=%.2x\n",
- dev->pts[0], dev->pts[1], dev->pts[2], dev->pts[3]);
-
- /* check card convention */
- if (test_bit(IS_INVREV, &dev->flags))
- str_invert_revert(dev->pts, 4);
-
- /* reset SM */
- xoutb(0x80, REG_FLAGS0(iobase));
-
- /* Enable access to the message buffer */
- DEBUGP(5, dev, "Enable access to the messages buffer\n");
- dev->flags1 = 0x20 /* T_Active */
- | (test_bit(IS_INVREV, &dev->flags) ? 0x02 : 0x00) /* inv parity */
- | ((dev->baudv >> 8) & 0x01); /* MSB-baud */
- xoutb(dev->flags1, REG_FLAGS1(iobase));
-
- DEBUGP(5, dev, "Enable message buffer -> flags1 = 0x%.2x\n",
- dev->flags1);
-
- /* write challenge to the buffer */
- DEBUGP(5, dev, "Write challenge to buffer: ");
- for (i = 0; i < 4; i++) {
- xoutb(i, REG_BUF_ADDR(iobase));
- xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */
-#ifdef PCMCIA_DEBUG
- if (pc_debug >= 5)
- printk("0x%.2x ", dev->pts[i]);
- }
- if (pc_debug >= 5)
- printk("\n");
-#else
- }
-#endif
-
- /* set number of bytes to write */
- DEBUGP(5, dev, "Set number of bytes to write\n");
- xoutb(0x04, REG_NUM_SEND(iobase));
-
- /* Trigger CARDMAN CONTROLLER */
- xoutb(0x50, REG_FLAGS0(iobase));
-
- /* Monitor progress */
- /* wait for xmit done */
- DEBUGP(5, dev, "Waiting for NumRecBytes getting valid\n");
-
- for (i = 0; i < 100; i++) {
- if (inb(REG_FLAGS0(iobase)) & 0x08) {
- DEBUGP(5, dev, "NumRecBytes is valid\n");
- break;
- }
- mdelay(10);
- }
- if (i == 100) {
- DEBUGP(5, dev, "Timeout waiting for NumRecBytes getting "
- "valid\n");
- rc = -EIO;
- goto exit_setprotocol;
- }
-
- DEBUGP(5, dev, "Reading NumRecBytes\n");
- for (i = 0; i < 100; i++) {
- io_read_num_rec_bytes(iobase, &num_bytes_read);
- if (num_bytes_read >= 4) {
- DEBUGP(2, dev, "NumRecBytes = %i\n", num_bytes_read);
- break;
- }
- mdelay(10);
- }
-
- /* check whether it is a short PTS reply? */
- if (num_bytes_read == 3)
- i = 0;
-
- if (i == 100) {
- DEBUGP(5, dev, "Timeout reading num_bytes_read\n");
- rc = -EIO;
- goto exit_setprotocol;
- }
-
- DEBUGP(5, dev, "Reset the CARDMAN CONTROLLER\n");
- xoutb(0x80, REG_FLAGS0(iobase));
-
- /* Read PPS reply */
- DEBUGP(5, dev, "Read PPS reply\n");
- for (i = 0; i < num_bytes_read; i++) {
- xoutb(i, REG_BUF_ADDR(iobase));
- pts_reply[i] = inb(REG_BUF_DATA(iobase));
- }
-
-#ifdef PCMCIA_DEBUG
- DEBUGP(2, dev, "PTSreply: ");
- for (i = 0; i < num_bytes_read; i++) {
- if (pc_debug >= 5)
- printk("0x%.2x ", pts_reply[i]);
- }
- printk("\n");
-#endif /* PCMCIA_DEBUG */
-
- DEBUGP(5, dev, "Clear Tactive in Flags1\n");
- xoutb(0x20, REG_FLAGS1(iobase));
-
- /* Compare ptsreq and ptsreply */
- if ((dev->pts[0] == pts_reply[0]) &&
- (dev->pts[1] == pts_reply[1]) &&
- (dev->pts[2] == pts_reply[2]) && (dev->pts[3] == pts_reply[3])) {
- /* setcardparameter according to PPS */
- dev->baudv = calc_baudv(dev->pts[2]);
- set_cardparameter(dev);
- } else if ((dev->pts[0] == pts_reply[0]) &&
- ((dev->pts[1] & 0xef) == pts_reply[1]) &&
- ((pts_reply[0] ^ pts_reply[1]) == pts_reply[2])) {
- /* short PTS reply, set card parameter to default values */
- dev->baudv = calc_baudv(0x11);
- set_cardparameter(dev);
- } else
- rc = -EIO;
-
-exit_setprotocol:
- DEBUGP(3, dev, "<- set_protocol\n");
- return rc;
-}
-
-static int io_detect_cm4000(ioaddr_t iobase, struct cm4000_dev *dev)
-{
-
- /* note: statemachine is assumed to be reset */
- if (inb(REG_FLAGS0(iobase)) & 8) {
- clear_bit(IS_ATR_VALID, &dev->flags);
- set_bit(IS_CMM_ABSENT, &dev->flags);
- return 0; /* detect CMM = 1 -> failure */
- }
- /* xoutb(0x40, REG_FLAGS1(iobase)); detectCMM */
- xoutb(dev->flags1 | 0x40, REG_FLAGS1(iobase));
- if ((inb(REG_FLAGS0(iobase)) & 8) == 0) {
- clear_bit(IS_ATR_VALID, &dev->flags);
- set_bit(IS_CMM_ABSENT, &dev->flags);
- return 0; /* detect CMM=0 -> failure */
- }
- /* clear detectCMM again by restoring original flags1 */
- xoutb(dev->flags1, REG_FLAGS1(iobase));
- return 1;
-}
-
-static void terminate_monitor(struct cm4000_dev *dev)
-{
-
- /* tell the monitor to stop and wait until
- * it terminates.
- */
- DEBUGP(3, dev, "-> terminate_monitor\n");
- wait_event_interruptible(dev->devq,
- test_and_set_bit(LOCK_MONITOR,
- (void *)&dev->flags));
-
- /* now, LOCK_MONITOR has been set.
- * allow a last cycle in the monitor.
- * the monitor will indicate that it has
- * finished by clearing this bit.
- */
- DEBUGP(5, dev, "Now allow last cycle of monitor!\n");
- while (test_bit(LOCK_MONITOR, (void *)&dev->flags))
- msleep(25);
-
- DEBUGP(5, dev, "Delete timer\n");
- del_timer_sync(&dev->timer);
-#ifdef PCMCIA_DEBUG
- dev->monitor_running = 0;
-#endif
-
- DEBUGP(3, dev, "<- terminate_monitor\n");
-}
-
-/*
- * monitor the card every 50msec. as a side-effect, retrieve the
- * atr once a card is inserted. another side-effect of retrieving the
- * atr is that the card will be powered on, so there is no need to
- * power on the card explictely from the application: the driver
- * is already doing that for you.
- */
-
-static void monitor_card(unsigned long p)
-{
- struct cm4000_dev *dev = (struct cm4000_dev *) p;
- ioaddr_t iobase = dev->link.io.BasePort1;
- unsigned short s;
- struct ptsreq ptsreq;
- int i, atrc;
-
- DEBUGP(7, dev, "-> monitor_card\n");
-
- /* if someone has set the lock for us: we're done! */
- if (test_and_set_bit(LOCK_MONITOR, &dev->flags)) {
- DEBUGP(4, dev, "About to stop monitor\n");
- /* no */
- dev->rlen =
- dev->rpos =
- dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0;
- dev->mstate = M_FETCH_ATR;
- clear_bit(LOCK_MONITOR, &dev->flags);
- /* close et al. are sleeping on devq, so wake it */
- wake_up_interruptible(&dev->devq);
- DEBUGP(2, dev, "<- monitor_card (we are done now)\n");
- return;
- }
-
- /* try to lock io: if it is already locked, just add another timer */
- if (test_and_set_bit(LOCK_IO, (void *)&dev->flags)) {
- DEBUGP(4, dev, "Couldn't get IO lock\n");
- goto return_with_timer;
- }
-
- /* is a card/a reader inserted at all ? */
- dev->flags0 = xinb(REG_FLAGS0(iobase));
- DEBUGP(7, dev, "dev->flags0 = 0x%2x\n", dev->flags0);
- DEBUGP(7, dev, "smartcard present: %s\n",
- dev->flags0 & 1 ? "yes" : "no");
- DEBUGP(7, dev, "cardman present: %s\n",
- dev->flags0 == 0xff ? "no" : "yes");
-
- if ((dev->flags0 & 1) == 0 /* no smartcard inserted */
- || dev->flags0 == 0xff) { /* no cardman inserted */
- /* no */
- dev->rlen =
- dev->rpos =
- dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0;
- dev->mstate = M_FETCH_ATR;
-
- dev->flags &= 0x000000ff; /* only keep IO and MONITOR locks */
-
- if (dev->flags0 == 0xff) {
- DEBUGP(4, dev, "set IS_CMM_ABSENT bit\n");
- set_bit(IS_CMM_ABSENT, &dev->flags);
- } else if (test_bit(IS_CMM_ABSENT, &dev->flags)) {
- DEBUGP(4, dev, "clear IS_CMM_ABSENT bit "
- "(card is removed)\n");
- clear_bit(IS_CMM_ABSENT, &dev->flags);
- }
-
- goto release_io;
- } else if ((dev->flags0 & 1) && test_bit(IS_CMM_ABSENT, &dev->flags)) {
- /* cardman and card present but cardman was absent before
- * (after suspend with inserted card) */
- DEBUGP(4, dev, "clear IS_CMM_ABSENT bit (card is inserted)\n");
- clear_bit(IS_CMM_ABSENT, &dev->flags);
- }
-
- if (test_bit(IS_ATR_VALID, &dev->flags) == 1) {
- DEBUGP(7, dev, "believe ATR is already valid (do nothing)\n");
- goto release_io;
- }
-
- switch (dev->mstate) {
- unsigned char flags0;
- case M_CARDOFF:
- DEBUGP(4, dev, "M_CARDOFF\n");
- flags0 = inb(REG_FLAGS0(iobase));
- if (flags0 & 0x02) {
- /* wait until Flags0 indicate power is off */
- dev->mdelay = T_10MSEC;
- } else {
- /* Flags0 indicate power off and no card inserted now;
- * Reset CARDMAN CONTROLLER */
- xoutb(0x80, REG_FLAGS0(iobase));
-
- /* prepare for fetching ATR again: after card off ATR
- * is read again automatically */
- dev->rlen =
- dev->rpos =
- dev->atr_csum =
- dev->atr_len_retry = dev->cwarn = 0;
- dev->mstate = M_FETCH_ATR;
-
- /* minimal gap between CARDOFF and read ATR is 50msec */
- dev->mdelay = T_50MSEC;
- }
- break;
- case M_FETCH_ATR:
- DEBUGP(4, dev, "M_FETCH_ATR\n");
- xoutb(0x80, REG_FLAGS0(iobase));
- DEBUGP(4, dev, "Reset BAUDV to 9600\n");
- dev->baudv = 0x173; /* 9600 */
- xoutb(0x02, REG_STOPBITS(iobase)); /* stopbits=2 */
- xoutb(0x73, REG_BAUDRATE(iobase)); /* baud value */
- xoutb(0x21, REG_FLAGS1(iobase)); /* T_Active=1, baud
- value */
- /* warm start vs. power on: */
- xoutb(dev->flags0 & 2 ? 0x46 : 0x44, REG_FLAGS0(iobase));
- dev->mdelay = T_40MSEC;
- dev->mstate = M_TIMEOUT_WAIT;
- break;
- case M_TIMEOUT_WAIT:
- DEBUGP(4, dev, "M_TIMEOUT_WAIT\n");
- /* numRecBytes */
- io_read_num_rec_bytes(iobase, &dev->atr_len);
- dev->mdelay = T_10MSEC;
- dev->mstate = M_READ_ATR_LEN;
- break;
- case M_READ_ATR_LEN:
- DEBUGP(4, dev, "M_READ_ATR_LEN\n");
- /* infinite loop possible, since there is no timeout */
-
-#define MAX_ATR_LEN_RETRY 100
-
- if (dev->atr_len == io_read_num_rec_bytes(iobase, &s)) {
- if (dev->atr_len_retry++ >= MAX_ATR_LEN_RETRY) { /* + XX msec */
- dev->mdelay = T_10MSEC;
- dev->mstate = M_READ_ATR;
- }
- } else {
- dev->atr_len = s;
- dev->atr_len_retry = 0; /* set new timeout */
- }
-
- DEBUGP(4, dev, "Current ATR_LEN = %i\n", dev->atr_len);
- break;
- case M_READ_ATR:
- DEBUGP(4, dev, "M_READ_ATR\n");
- xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */
- for (i = 0; i < dev->atr_len; i++) {
- xoutb(i, REG_BUF_ADDR(iobase));
- dev->atr[i] = inb(REG_BUF_DATA(iobase));
- }
- /* Deactivate T_Active flags */
- DEBUGP(4, dev, "Deactivate T_Active flags\n");
- dev->flags1 = 0x01;
- xoutb(dev->flags1, REG_FLAGS1(iobase));
-
- /* atr is present (which doesnt mean it's valid) */
- set_bit(IS_ATR_PRESENT, &dev->flags);
- if (dev->atr[0] == 0x03)
- str_invert_revert(dev->atr, dev->atr_len);
- atrc = parse_atr(dev);
- if (atrc == 0) { /* atr invalid */
- dev->mdelay = 0;
- dev->mstate = M_BAD_CARD;
- } else {
- dev->mdelay = T_50MSEC;
- dev->mstate = M_ATR_PRESENT;
- set_bit(IS_ATR_VALID, &dev->flags);
- }
-
- if (test_bit(IS_ATR_VALID, &dev->flags) == 1) {
- DEBUGP(4, dev, "monitor_card: ATR valid\n");
- /* if ta1 == 0x11, no PPS necessary (default values) */
- /* do not do PPS with multi protocol cards */
- if ((test_bit(IS_AUTOPPS_ACT, &dev->flags) == 0) &&
- (dev->ta1 != 0x11) &&
- !(test_bit(IS_ANY_T0, &dev->flags) &&
- test_bit(IS_ANY_T1, &dev->flags))) {
- DEBUGP(4, dev, "Perform AUTOPPS\n");
- set_bit(IS_AUTOPPS_ACT, &dev->flags);
- ptsreq.protocol = ptsreq.protocol =
- (0x01 << dev->proto);
- ptsreq.flags = 0x01;
- ptsreq.pts1 = 0x00;
- ptsreq.pts2 = 0x00;
- ptsreq.pts3 = 0x00;
- if (set_protocol(dev, &ptsreq) == 0) {
- DEBUGP(4, dev, "AUTOPPS ret SUCC\n");
- clear_bit(IS_AUTOPPS_ACT, &dev->flags);
- wake_up_interruptible(&dev->atrq);
- } else {
- DEBUGP(4, dev, "AUTOPPS failed: "
- "repower using defaults\n");
- /* prepare for repowering */
- clear_bit(IS_ATR_PRESENT, &dev->flags);
- clear_bit(IS_ATR_VALID, &dev->flags);
- dev->rlen =
- dev->rpos =
- dev->atr_csum =
- dev->atr_len_retry = dev->cwarn = 0;
- dev->mstate = M_FETCH_ATR;
-
- dev->mdelay = T_50MSEC;
- }
- } else {
- /* for cards which use slightly different
- * params (extra guard time) */
- set_cardparameter(dev);
- if (test_bit(IS_AUTOPPS_ACT, &dev->flags) == 1)
- DEBUGP(4, dev, "AUTOPPS already active "
- "2nd try:use default values\n");
- if (dev->ta1 == 0x11)
- DEBUGP(4, dev, "No AUTOPPS necessary "
- "TA(1)==0x11\n");
- if (test_bit(IS_ANY_T0, &dev->flags)
- && test_bit(IS_ANY_T1, &dev->flags))
- DEBUGP(4, dev, "Do NOT perform AUTOPPS "
- "with multiprotocol cards\n");
- clear_bit(IS_AUTOPPS_ACT, &dev->flags);
- wake_up_interruptible(&dev->atrq);
- }
- } else {
- DEBUGP(4, dev, "ATR invalid\n");
- wake_up_interruptible(&dev->atrq);
- }
- break;
- case M_BAD_CARD:
- DEBUGP(4, dev, "M_BAD_CARD\n");
- /* slow down warning, but prompt immediately after insertion */
- if (dev->cwarn == 0 || dev->cwarn == 10) {
- set_bit(IS_BAD_CARD, &dev->flags);
- printk(KERN_WARNING MODULE_NAME ": device %s: ",
- dev->node.dev_name);
- if (test_bit(IS_BAD_CSUM, &dev->flags)) {
- DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
- "be zero) failed\n", dev->atr_csum);
- }
-#ifdef PCMCIA_DEBUG
- else if (test_bit(IS_BAD_LENGTH, &dev->flags)) {
- DEBUGP(4, dev, "ATR length error\n");
- } else {
- DEBUGP(4, dev, "card damaged or wrong way "
- "inserted\n");
- }
-#endif
- dev->cwarn = 0;
- wake_up_interruptible(&dev->atrq); /* wake open */
- }
- dev->cwarn++;
- dev->mdelay = T_100MSEC;
- dev->mstate = M_FETCH_ATR;
- break;
- default:
- DEBUGP(7, dev, "Unknown action\n");
- break; /* nothing */
- }
-
-release_io:
- DEBUGP(7, dev, "release_io\n");
- clear_bit(LOCK_IO, &dev->flags);
- wake_up_interruptible(&dev->ioq); /* whoever needs IO */
-
-return_with_timer:
- DEBUGP(7, dev, "<- monitor_card (returns with timer)\n");
- dev->timer.expires = jiffies + dev->mdelay;
- add_timer(&dev->timer);
- clear_bit(LOCK_MONITOR, &dev->flags);
-}
-
-/* Interface to userland (file_operations) */
-
-static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
- loff_t *ppos)
-{
- struct cm4000_dev *dev = filp->private_data;
- ioaddr_t iobase = dev->link.io.BasePort1;
- ssize_t rc;
- int i, j, k;
-
- DEBUGP(2, dev, "-> cmm_read(%s,%d)\n", current->comm, current->pid);
-
- if (count == 0) /* according to manpage */
- return 0;
-
- if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */
- test_bit(IS_CMM_ABSENT, &dev->flags))
- return -ENODEV;
-
- if (test_bit(IS_BAD_CSUM, &dev->flags))
- return -EIO;
-
- /* also see the note about this in cmm_write */
- if (wait_event_interruptible
- (dev->atrq,
- ((filp->f_flags & O_NONBLOCK)
- || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) {
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- return -ERESTARTSYS;
- }
-
- if (test_bit(IS_ATR_VALID, &dev->flags) == 0)
- return -EIO;
-
- /* this one implements blocking IO */
- if (wait_event_interruptible
- (dev->readq,
- ((filp->f_flags & O_NONBLOCK) || (dev->rpos < dev->rlen)))) {
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- return -ERESTARTSYS;
- }
-
- /* lock io */
- if (wait_event_interruptible
- (dev->ioq,
- ((filp->f_flags & O_NONBLOCK)
- || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) {
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- return -ERESTARTSYS;
- }
-
- rc = 0;
- dev->flags0 = inb(REG_FLAGS0(iobase));
- if ((dev->flags0 & 1) == 0 /* no smartcard inserted */
- || dev->flags0 == 0xff) { /* no cardman inserted */
- clear_bit(IS_ATR_VALID, &dev->flags);
- if (dev->flags0 & 1) {
- set_bit(IS_CMM_ABSENT, &dev->flags);
- rc = -ENODEV;
- }
- rc = -EIO;
- goto release_io;
- }
-
- DEBUGP(4, dev, "begin read answer\n");
- j = min(count, (size_t)(dev->rlen - dev->rpos));
- k = dev->rpos;
- if (k + j > 255)
- j = 256 - k;
- DEBUGP(4, dev, "read1 j=%d\n", j);
- for (i = 0; i < j; i++) {
- xoutb(k++, REG_BUF_ADDR(iobase));
- dev->rbuf[i] = xinb(REG_BUF_DATA(iobase));
- }
- j = min(count, (size_t)(dev->rlen - dev->rpos));
- if (k + j > 255) {
- DEBUGP(4, dev, "read2 j=%d\n", j);
- dev->flags1 |= 0x10; /* MSB buf addr set */
- xoutb(dev->flags1, REG_FLAGS1(iobase));
- for (; i < j; i++) {
- xoutb(k++, REG_BUF_ADDR(iobase));
- dev->rbuf[i] = xinb(REG_BUF_DATA(iobase));
- }
- }
-
- if (dev->proto == 0 && count > dev->rlen - dev->rpos) {
- DEBUGP(4, dev, "T=0 and count > buffer\n");
- dev->rbuf[i] = dev->rbuf[i - 1];
- dev->rbuf[i - 1] = dev->procbyte;
- j++;
- }
- count = j;
-
- dev->rpos = dev->rlen + 1;
-
- /* Clear T1Active */
- DEBUGP(4, dev, "Clear T1Active\n");
- dev->flags1 &= 0xdf;
- xoutb(dev->flags1, REG_FLAGS1(iobase));
-
- xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */
- /* last check before exit */
- if (!io_detect_cm4000(iobase, dev))
- count = -ENODEV;
-
- if (test_bit(IS_INVREV, &dev->flags) && count > 0)
- str_invert_revert(dev->rbuf, count);
-
- if (copy_to_user(buf, dev->rbuf, count))
- return -EFAULT;
-
-release_io:
- clear_bit(LOCK_IO, &dev->flags);
- wake_up_interruptible(&dev->ioq);
-
- DEBUGP(2, dev, "<- cmm_read returns: rc = %Zi\n",
- (rc < 0 ? rc : count));
- return rc < 0 ? rc : count;
-}
-
-static ssize_t cmm_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data;
- ioaddr_t iobase = dev->link.io.BasePort1;
- unsigned short s;
- unsigned char tmp;
- unsigned char infolen;
- unsigned char sendT0;
- unsigned short nsend;
- unsigned short nr;
- ssize_t rc;
- int i;
-
- DEBUGP(2, dev, "-> cmm_write(%s,%d)\n", current->comm, current->pid);
-
- if (count == 0) /* according to manpage */
- return 0;
-
- if (dev->proto == 0 && count < 4) {
- /* T0 must have at least 4 bytes */
- DEBUGP(4, dev, "T0 short write\n");
- return -EIO;
- }
-
- nr = count & 0x1ff; /* max bytes to write */
-
- sendT0 = dev->proto ? 0 : nr > 5 ? 0x08 : 0;
-
- if ((dev->link.state & DEV_PRESENT) == 0 || /* socket removed */
- test_bit(IS_CMM_ABSENT, &dev->flags))
- return -ENODEV;
-
- if (test_bit(IS_BAD_CSUM, &dev->flags)) {
- DEBUGP(4, dev, "bad csum\n");
- return -EIO;
- }
-
- /*
- * wait for atr to become valid.
- * note: it is important to lock this code. if we dont, the monitor
- * could be run between test_bit and the the call the sleep on the
- * atr-queue. if *then* the monitor detects atr valid, it will wake up
- * any process on the atr-queue, *but* since we have been interrupted,
- * we do not yet sleep on this queue. this would result in a missed
- * wake_up and the calling process would sleep forever (until
- * interrupted). also, do *not* restore_flags before sleep_on, because
- * this could result in the same situation!
- */
- if (wait_event_interruptible
- (dev->atrq,
- ((filp->f_flags & O_NONBLOCK)
- || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) {
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- return -ERESTARTSYS;
- }
-
- if (test_bit(IS_ATR_VALID, &dev->flags) == 0) { /* invalid atr */
- DEBUGP(4, dev, "invalid ATR\n");
- return -EIO;
- }
-
- /* lock io */
- if (wait_event_interruptible
- (dev->ioq,
- ((filp->f_flags & O_NONBLOCK)
- || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) {
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- return -ERESTARTSYS;
- }
-
- if (copy_from_user(dev->sbuf, buf, ((count > 512) ? 512 : count)))
- return -EFAULT;
-
- rc = 0;
- dev->flags0 = inb(REG_FLAGS0(iobase));
- if ((dev->flags0 & 1) == 0 /* no smartcard inserted */
- || dev->flags0 == 0xff) { /* no cardman inserted */
- clear_bit(IS_ATR_VALID, &dev->flags);
- if (dev->flags0 & 1) {
- set_bit(IS_CMM_ABSENT, &dev->flags);
- rc = -ENODEV;
- } else {
- DEBUGP(4, dev, "IO error\n");
- rc = -EIO;
- }
- goto release_io;
- }
-
- xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */
-
- if (!io_detect_cm4000(iobase, dev)) {
- rc = -ENODEV;
- goto release_io;
- }
-
- /* reflect T=0 send/read mode in flags1 */
- dev->flags1 |= (sendT0);
-
- set_cardparameter(dev);
-
- /* dummy read, reset flag procedure received */
- tmp = inb(REG_FLAGS1(iobase));
-
- dev->flags1 = 0x20 /* T_Active */
- | (sendT0)
- | (test_bit(IS_INVREV, &dev->flags) ? 2 : 0)/* inverse parity */
- | (((dev->baudv - 1) & 0x0100) >> 8); /* MSB-Baud */
- DEBUGP(1, dev, "set dev->flags1 = 0x%.2x\n", dev->flags1);
- xoutb(dev->flags1, REG_FLAGS1(iobase));
-
- /* xmit data */
- DEBUGP(4, dev, "Xmit data\n");
- for (i = 0; i < nr; i++) {
- if (i >= 256) {
- dev->flags1 = 0x20 /* T_Active */
- | (sendT0) /* SendT0 */
- /* inverse parity: */
- | (test_bit(IS_INVREV, &dev->flags) ? 2 : 0)
- | (((dev->baudv - 1) & 0x0100) >> 8) /* MSB-Baud */
- | 0x10; /* set address high */
- DEBUGP(4, dev, "dev->flags = 0x%.2x - set address "
- "high\n", dev->flags1);
- xoutb(dev->flags1, REG_FLAGS1(iobase));
- }
- if (test_bit(IS_INVREV, &dev->flags)) {
- DEBUGP(4, dev, "Apply inverse convention for 0x%.2x "
- "-> 0x%.2x\n", (unsigned char)dev->sbuf[i],
- invert_revert(dev->sbuf[i]));
- xoutb(i, REG_BUF_ADDR(iobase));
- xoutb(invert_revert(dev->sbuf[i]),
- REG_BUF_DATA(iobase));
- } else {
- xoutb(i, REG_BUF_ADDR(iobase));
- xoutb(dev->sbuf[i], REG_BUF_DATA(iobase));
- }
- }
- DEBUGP(4, dev, "Xmit done\n");
-
- if (dev->proto == 0) {
- /* T=0 proto: 0 byte reply */
- if (nr == 4) {
- DEBUGP(4, dev, "T=0 assumes 0 byte reply\n");
- xoutb(i, REG_BUF_ADDR(iobase));
- if (test_bit(IS_INVREV, &dev->flags))
- xoutb(0xff, REG_BUF_DATA(iobase));
- else
- xoutb(0x00, REG_BUF_DATA(iobase));
- }
-
- /* numSendBytes */
- if (sendT0)
- nsend = nr;
- else {
- if (nr == 4)
- nsend = 5;
- else {
- nsend = 5 + (unsigned char)dev->sbuf[4];
- if (dev->sbuf[4] == 0)
- nsend += 0x100;
- }
- }
- } else
- nsend = nr;
-
- /* T0: output procedure byte */
- if (test_bit(IS_INVREV, &dev->flags)) {
- DEBUGP(4, dev, "T=0 set Procedure byte (inverse-reverse) "
- "0x%.2x\n", invert_revert(dev->sbuf[1]));
- xoutb(invert_revert(dev->sbuf[1]), REG_NUM_BYTES(iobase));
- } else {
- DEBUGP(4, dev, "T=0 set Procedure byte 0x%.2x\n", dev->sbuf[1]);
- xoutb(dev->sbuf[1], REG_NUM_BYTES(iobase));
- }
-
- DEBUGP(1, dev, "set NumSendBytes = 0x%.2x\n",
- (unsigned char)(nsend & 0xff));
- xoutb((unsigned char)(nsend & 0xff), REG_NUM_SEND(iobase));
-
- DEBUGP(1, dev, "Trigger CARDMAN CONTROLLER (0x%.2x)\n",
- 0x40 /* SM_Active */
- | (dev->flags0 & 2 ? 0 : 4) /* power on if needed */
- |(dev->proto ? 0x10 : 0x08) /* T=1/T=0 */
- |(nsend & 0x100) >> 8 /* MSB numSendBytes */ );
- xoutb(0x40 /* SM_Active */
- | (dev->flags0 & 2 ? 0 : 4) /* power on if needed */
- |(dev->proto ? 0x10 : 0x08) /* T=1/T=0 */
- |(nsend & 0x100) >> 8, /* MSB numSendBytes */
- REG_FLAGS0(iobase));
-
- /* wait for xmit done */
- if (dev->proto == 1) {
- DEBUGP(4, dev, "Wait for xmit done\n");
- for (i = 0; i < 1000; i++) {
- if (inb(REG_FLAGS0(iobase)) & 0x08)
- break;
- msleep_interruptible(10);
- }
- if (i == 1000) {
- DEBUGP(4, dev, "timeout waiting for xmit done\n");
- rc = -EIO;
- goto release_io;
- }
- }
-
- /* T=1: wait for infoLen */
-
- infolen = 0;
- if (dev->proto) {
- /* wait until infoLen is valid */
- for (i = 0; i < 6000; i++) { /* max waiting time of 1 min */
- io_read_num_rec_bytes(iobase, &s);
- if (s >= 3) {
- infolen = inb(REG_FLAGS1(iobase));
- DEBUGP(4, dev, "infolen=%d\n", infolen);
- break;
- }
- msleep_interruptible(10);
- }
- if (i == 6000) {
- DEBUGP(4, dev, "timeout waiting for infoLen\n");
- rc = -EIO;
- goto release_io;
- }
- } else
- clear_bit(IS_PROCBYTE_PRESENT, &dev->flags);
-
- /* numRecBytes | bit9 of numRecytes */
- io_read_num_rec_bytes(iobase, &dev->rlen);
- for (i = 0; i < 600; i++) { /* max waiting time of 2 sec */
- if (dev->proto) {
- if (dev->rlen >= infolen + 4)
- break;
- }
- msleep_interruptible(10);
- /* numRecBytes | bit9 of numRecytes */
- io_read_num_rec_bytes(iobase, &s);
- if (s > dev->rlen) {
- DEBUGP(1, dev, "NumRecBytes inc (reset timeout)\n");
- i = 0; /* reset timeout */
- dev->rlen = s;
- }
- /* T=0: we are done when numRecBytes doesn't
- * increment any more and NoProcedureByte
- * is set and numRecBytes == bytes sent + 6
- * (header bytes + data + 1 for sw2)
- * except when the card replies an error
- * which means, no data will be sent back.
- */
- else if (dev->proto == 0) {
- if ((inb(REG_BUF_ADDR(iobase)) & 0x80)) {
- /* no procedure byte received since last read */
- DEBUGP(1, dev, "NoProcedure byte set\n");
- /* i=0; */
- } else {
- /* procedure byte received since last read */
- DEBUGP(1, dev, "NoProcedure byte unset "
- "(reset timeout)\n");
- dev->procbyte = inb(REG_FLAGS1(iobase));
- DEBUGP(1, dev, "Read procedure byte 0x%.2x\n",
- dev->procbyte);
- i = 0; /* resettimeout */
- }
- if (inb(REG_FLAGS0(iobase)) & 0x08) {
- DEBUGP(1, dev, "T0Done flag (read reply)\n");
- break;
- }
- }
- if (dev->proto)
- infolen = inb(REG_FLAGS1(iobase));
- }
- if (i == 600) {
- DEBUGP(1, dev, "timeout waiting for numRecBytes\n");
- rc = -EIO;
- goto release_io;
- } else {
- if (dev->proto == 0) {
- DEBUGP(1, dev, "Wait for T0Done bit to be set\n");
- for (i = 0; i < 1000; i++) {
- if (inb(REG_FLAGS0(iobase)) & 0x08)
- break;
- msleep_interruptible(10);
- }
- if (i == 1000) {
- DEBUGP(1, dev, "timeout waiting for T0Done\n");
- rc = -EIO;
- goto release_io;
- }
-
- dev->procbyte = inb(REG_FLAGS1(iobase));
- DEBUGP(4, dev, "Read procedure byte 0x%.2x\n",
- dev->procbyte);
-
- io_read_num_rec_bytes(iobase, &dev->rlen);
- DEBUGP(4, dev, "Read NumRecBytes = %i\n", dev->rlen);
-
- }
- }
- /* T=1: read offset=zero, T=0: read offset=after challenge */
- dev->rpos = dev->proto ? 0 : nr == 4 ? 5 : nr > dev->rlen ? 5 : nr;
- DEBUGP(4, dev, "dev->rlen = %i, dev->rpos = %i, nr = %i\n",
- dev->rlen, dev->rpos, nr);
-
-release_io:
- DEBUGP(4, dev, "Reset SM\n");
- xoutb(0x80, REG_FLAGS0(iobase)); /* reset SM */
-
- if (rc < 0) {
- DEBUGP(4, dev, "Write failed but clear T_Active\n");
- dev->flags1 &= 0xdf;
- xoutb(dev->flags1, REG_FLAGS1(iobase));
- }
-
- clear_bit(LOCK_IO, &dev->flags);
- wake_up_interruptible(&dev->ioq);
- wake_up_interruptible(&dev->readq); /* tell read we have data */
-
- /* ITSEC E2: clear write buffer */
- memset((char *)dev->sbuf, 0, 512);
-
- /* return error or actually written bytes */
- DEBUGP(2, dev, "<- cmm_write\n");
- return rc < 0 ? rc : nr;
-}
-
-static void start_monitor(struct cm4000_dev *dev)
-{
- DEBUGP(3, dev, "-> start_monitor\n");
- if (!dev->monitor_running) {
- DEBUGP(5, dev, "create, init and add timer\n");
- init_timer(&dev->timer);
- dev->monitor_running = 1;
- dev->timer.expires = jiffies;
- dev->timer.data = (unsigned long) dev;
- dev->timer.function = monitor_card;
- add_timer(&dev->timer);
- } else
- DEBUGP(5, dev, "monitor already running\n");
- DEBUGP(3, dev, "<- start_monitor\n");
-}
-
-static void stop_monitor(struct cm4000_dev *dev)
-{
- DEBUGP(3, dev, "-> stop_monitor\n");
- if (dev->monitor_running) {
- DEBUGP(5, dev, "stopping monitor\n");
- terminate_monitor(dev);
- /* reset monitor SM */
- clear_bit(IS_ATR_VALID, &dev->flags);
- clear_bit(IS_ATR_PRESENT, &dev->flags);
- } else
- DEBUGP(5, dev, "monitor already stopped\n");
- DEBUGP(3, dev, "<- stop_monitor\n");
-}
-
-static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- struct cm4000_dev *dev = filp->private_data;
- ioaddr_t iobase = dev->link.io.BasePort1;
- dev_link_t *link;
- int size;
- int rc;
-#ifdef PCMCIA_DEBUG
- char *ioctl_names[CM_IOC_MAXNR + 1] = {
- [_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
- [_IOC_NR(CM_IOCGATR)] "CM_IOCGATR",
- [_IOC_NR(CM_IOCARDOFF)] "CM_IOCARDOFF",
- [_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS",
- [_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL",
- };
-#endif
- DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
- iminor(inode), ioctl_names[_IOC_NR(cmd)]);
-
- link = dev_table[iminor(inode)];
- if (!(DEV_OK(link))) {
- DEBUGP(4, dev, "DEV_OK false\n");
- return -ENODEV;
- }
-
- if (test_bit(IS_CMM_ABSENT, &dev->flags)) {
- DEBUGP(4, dev, "CMM_ABSENT flag set\n");
- return -ENODEV;
- }
-
- if (_IOC_TYPE(cmd) != CM_IOC_MAGIC) {
- DEBUGP(4, dev, "ioctype mismatch\n");
- return -EINVAL;
- }
- if (_IOC_NR(cmd) > CM_IOC_MAXNR) {
- DEBUGP(4, dev, "iocnr mismatch\n");
- return -EINVAL;
- }
- size = _IOC_SIZE(cmd);
- rc = 0;
- DEBUGP(4, dev, "iocdir=%.4x iocr=%.4x iocw=%.4x iocsize=%d cmd=%.4x\n",
- _IOC_DIR(cmd), _IOC_READ, _IOC_WRITE, size, cmd);
-
- if (_IOC_DIR(cmd) & _IOC_READ) {
- if (!access_ok(VERIFY_WRITE, (void *)arg, size))
- return -EFAULT;
- }
- if (_IOC_DIR(cmd) & _IOC_WRITE) {
- if (!access_ok(VERIFY_READ, (void *)arg, size))
- return -EFAULT;
- }
-
- switch (cmd) {
- case CM_IOCGSTATUS:
- DEBUGP(4, dev, " ... in CM_IOCGSTATUS\n");
- {
- int status;
-
- /* clear other bits, but leave inserted & powered as
- * they are */
- status = dev->flags0 & 3;
- if (test_bit(IS_ATR_PRESENT, &dev->flags))
- status |= CM_ATR_PRESENT;
- if (test_bit(IS_ATR_VALID, &dev->flags))
- status |= CM_ATR_VALID;
- if (test_bit(IS_CMM_ABSENT, &dev->flags))
- status |= CM_NO_READER;
- if (test_bit(IS_BAD_CARD, &dev->flags))
- status |= CM_BAD_CARD;
- if (copy_to_user((int *)arg, &status, sizeof(int)))
- return -EFAULT;
- }
- return 0;
- case CM_IOCGATR:
- DEBUGP(4, dev, "... in CM_IOCGATR\n");
- {
- struct atreq *atreq = (struct atreq *) arg;
- int tmp;
- /* allow nonblocking io and being interrupted */
- if (wait_event_interruptible
- (dev->atrq,
- ((filp->f_flags & O_NONBLOCK)
- || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
- != 0)))) {
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- return -ERESTARTSYS;
- }
-
- if (test_bit(IS_ATR_VALID, &dev->flags) == 0) {
- tmp = -1;
- if (copy_to_user(&(atreq->atr_len), &tmp,
- sizeof(int)))
- return -EFAULT;
- } else {
- if (copy_to_user(atreq->atr, dev->atr,
- dev->atr_len))
- return -EFAULT;
-
- tmp = dev->atr_len;
- if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int)))
- return -EFAULT;
- }
- return 0;
- }
- case CM_IOCARDOFF:
-
-#ifdef PCMCIA_DEBUG
- DEBUGP(4, dev, "... in CM_IOCARDOFF\n");
- if (dev->flags0 & 0x01) {
- DEBUGP(4, dev, " Card inserted\n");
- } else {
- DEBUGP(2, dev, " No card inserted\n");
- }
- if (dev->flags0 & 0x02) {
- DEBUGP(4, dev, " Card powered\n");
- } else {
- DEBUGP(2, dev, " Card not powered\n");
- }
-#endif
-
- /* is a card inserted and powered? */
- if ((dev->flags0 & 0x01) && (dev->flags0 & 0x02)) {
-
- /* get IO lock */
- if (wait_event_interruptible
- (dev->ioq,
- ((filp->f_flags & O_NONBLOCK)
- || (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
- == 0)))) {
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- return -ERESTARTSYS;
- }
- /* Set Flags0 = 0x42 */
- DEBUGP(4, dev, "Set Flags0=0x42 \n");
- xoutb(0x42, REG_FLAGS0(iobase));
- clear_bit(IS_ATR_PRESENT, &dev->flags);
- clear_bit(IS_ATR_VALID, &dev->flags);
- dev->mstate = M_CARDOFF;
- clear_bit(LOCK_IO, &dev->flags);
- if (wait_event_interruptible
- (dev->atrq,
- ((filp->f_flags & O_NONBLOCK)
- || (test_bit(IS_ATR_VALID, (void *)&dev->flags) !=
- 0)))) {
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- return -ERESTARTSYS;
- }
- }
- /* release lock */
- clear_bit(LOCK_IO, &dev->flags);
- wake_up_interruptible(&dev->ioq);
-
- return 0;
- case CM_IOCSPTS:
- {
- struct ptsreq krnptsreq;
-
- if (copy_from_user(&krnptsreq, (struct ptsreq *) arg,
- sizeof(struct ptsreq)))
- return -EFAULT;
-
- rc = 0;
- DEBUGP(4, dev, "... in CM_IOCSPTS\n");
- /* wait for ATR to get valid */
- if (wait_event_interruptible
- (dev->atrq,
- ((filp->f_flags & O_NONBLOCK)
- || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
- != 0)))) {
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- return -ERESTARTSYS;
- }
- /* get IO lock */
- if (wait_event_interruptible
- (dev->ioq,
- ((filp->f_flags & O_NONBLOCK)
- || (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
- == 0)))) {
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- return -ERESTARTSYS;
- }
-
- if ((rc = set_protocol(dev, &krnptsreq)) != 0) {
- /* auto power_on again */
- dev->mstate = M_FETCH_ATR;
- clear_bit(IS_ATR_VALID, &dev->flags);
- }
- /* release lock */
- clear_bit(LOCK_IO, &dev->flags);
- wake_up_interruptible(&dev->ioq);
-
- }
- return rc;
-#ifdef PCMCIA_DEBUG
- case CM_IOSDBGLVL: /* set debug log level */
- {
- int old_pc_debug = 0;
-
- old_pc_debug = pc_debug;
- if (copy_from_user(&pc_debug, (int *)arg, sizeof(int)))
- return -EFAULT;
-
- if (old_pc_debug != pc_debug)
- DEBUGP(0, dev, "Changed debug log level "
- "to %i\n", pc_debug);
- }
- return rc;
-#endif
- default:
- DEBUGP(4, dev, "... in default (unknown IOCTL code)\n");
- return -EINVAL;
- }
-}
-
-static int cmm_open(struct inode *inode, struct file *filp)
-{
- struct cm4000_dev *dev;
- dev_link_t *link;
- int rc, minor = iminor(inode);
-
- if (minor >= CM4000_MAX_DEV)
- return -ENODEV;
-
- link = dev_table[minor];
- if (link == NULL || !(DEV_OK(link)))
- return -ENODEV;
-
- if (link->open)
- return -EBUSY;
-
- dev = link->priv;
- filp->private_data = dev;
-
- DEBUGP(2, dev, "-> cmm_open(device=%d.%d process=%s,%d)\n",
- imajor(inode), minor, current->comm, current->pid);
-
- /* init device variables, they may be "polluted" after close
- * or, the device may never have been closed (i.e. open failed)
- */
-
- ZERO_DEV(dev);
-
- /* opening will always block since the
- * monitor will be started by open, which
- * means we have to wait for ATR becoming
- * vaild = block until valid (or card
- * inserted)
- */
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
-
- dev->mdelay = T_50MSEC;
-
- /* start monitoring the cardstatus */
- start_monitor(dev);
-
- link->open = 1; /* only one open per device */
- rc = 0;
-
- DEBUGP(2, dev, "<- cmm_open\n");
- return nonseekable_open(inode, filp);
-}
-
-static int cmm_close(struct inode *inode, struct file *filp)
-{
- struct cm4000_dev *dev;
- dev_link_t *link;
- int minor = iminor(inode);
-
- if (minor >= CM4000_MAX_DEV)
- return -ENODEV;
-
- link = dev_table[minor];
- if (link == NULL)
- return -ENODEV;
-
- dev = link->priv;
-
- DEBUGP(2, dev, "-> cmm_close(maj/min=%d.%d)\n",
- imajor(inode), minor);
-
- stop_monitor(dev);
-
- ZERO_DEV(dev);
-
- link->open = 0; /* only one open per device */
- wake_up(&dev->devq); /* socket removed? */
-
- DEBUGP(2, dev, "cmm_close\n");
- return 0;
-}
-
-static void cmm_cm4000_release(dev_link_t * link)
-{
- struct cm4000_dev *dev = link->priv;
-
- /* dont terminate the monitor, rather rely on
- * close doing that for us.
- */
- DEBUGP(3, dev, "-> cmm_cm4000_release\n");
- while (link->open) {
- printk(KERN_INFO MODULE_NAME ": delaying release until "
- "process has terminated\n");
- /* note: don't interrupt us:
- * close the applications which own
- * the devices _first_ !
- */
- wait_event(dev->devq, (link->open == 0));
- }
- /* dev->devq=NULL; this cannot be zeroed earlier */
- DEBUGP(3, dev, "<- cmm_cm4000_release\n");
- return;
-}
-
-/*==== Interface to PCMCIA Layer =======================================*/
-
-static void cm4000_config(dev_link_t * link, int devno)
-{
- client_handle_t handle = link->handle;
- struct cm4000_dev *dev;
- tuple_t tuple;
- cisparse_t parse;
- config_info_t conf;
- u_char buf[64];
- int fail_fn, fail_rc;
- int rc;
-
- /* read the config-tuples */
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) {
- fail_fn = GetFirstTuple;
- goto cs_failed;
- }
- if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) {
- fail_fn = GetTupleData;
- goto cs_failed;
- }
- if ((fail_rc =
- pcmcia_parse_tuple(handle, &tuple, &parse)) != CS_SUCCESS) {
- fail_fn = ParseTuple;
- goto cs_failed;
- }
- if ((fail_rc =
- pcmcia_get_configuration_info(handle, &conf)) != CS_SUCCESS) {
- fail_fn = GetConfigurationInfo;
- goto cs_failed;
- }
-
- link->state |= DEV_CONFIG;
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
- link->conf.Vcc = conf.Vcc;
-
- link->io.BasePort2 = 0;
- link->io.NumPorts2 = 0;
- link->io.Attributes2 = 0;
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- for (rc = pcmcia_get_first_tuple(handle, &tuple);
- rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(handle, &tuple)) {
-
- rc = pcmcia_get_tuple_data(handle, &tuple);
- if (rc != CS_SUCCESS)
- continue;
- rc = pcmcia_parse_tuple(handle, &tuple, &parse);
- if (rc != CS_SUCCESS)
- continue;
-
- link->conf.ConfigIndex = parse.cftable_entry.index;
-
- if (!parse.cftable_entry.io.nwin)
- continue;
-
- /* Get the IOaddr */
- link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
- link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = parse.cftable_entry.io.flags
- & CISTPL_IO_LINES_MASK;
-
- rc = pcmcia_request_io(handle, &link->io);
- if (rc == CS_SUCCESS)
- break; /* we are done */
- }
- if (rc != CS_SUCCESS)
- goto cs_release;
-
- link->conf.IntType = 00000002;
-
- if ((fail_rc =
- pcmcia_request_configuration(handle, &link->conf)) != CS_SUCCESS) {
- fail_fn = RequestConfiguration;
- goto cs_release;
- }
-
- dev = link->priv;
- sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
- dev->node.major = major;
- dev->node.minor = devno;
- dev->node.next = NULL;
- link->dev = &dev->node;
- link->state &= ~DEV_CONFIG_PENDING;
-
- return;
-
-cs_failed:
- cs_error(handle, fail_fn, fail_rc);
-cs_release:
- cm4000_release(link);
-
- link->state &= ~DEV_CONFIG_PENDING;
-}
-
-static int cm4000_event(event_t event, int priority,
- event_callback_args_t *args)
-{
- dev_link_t *link;
- struct cm4000_dev *dev;
- int devno;
-
- link = args->client_data;
- dev = link->priv;
-
- DEBUGP(3, dev, "-> cm4000_event\n");
- for (devno = 0; devno < CM4000_MAX_DEV; devno++)
- if (dev_table[devno] == link)
- break;
-
- if (devno == CM4000_MAX_DEV)
- return CS_BAD_ADAPTER;
-
- switch (event) {
- case CS_EVENT_CARD_INSERTION:
- DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- cm4000_config(link, devno);
- break;
- case CS_EVENT_CARD_REMOVAL:
- DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
- link->state &= ~DEV_PRESENT;
- stop_monitor(dev);
- break;
- case CS_EVENT_PM_SUSPEND:
- DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
- "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
- link->state |= DEV_SUSPEND;
- /* fall-through */
- case CS_EVENT_RESET_PHYSICAL:
- DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
- if (link->state & DEV_CONFIG) {
- DEBUGP(5, dev, "ReleaseConfiguration\n");
- pcmcia_release_configuration(link->handle);
- }
- stop_monitor(dev);
- break;
- case CS_EVENT_PM_RESUME:
- DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
- "(fall-through to CS_EVENT_CARD_RESET)\n");
- link->state &= ~DEV_SUSPEND;
- /* fall-through */
- case CS_EVENT_CARD_RESET:
- DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
- if ((link->state & DEV_CONFIG)) {
- DEBUGP(5, dev, "RequestConfiguration\n");
- pcmcia_request_configuration(link->handle, &link->conf);
- }
- if (link->open)
- start_monitor(dev);
- break;
- default:
- DEBUGP(5, dev, "unknown event %.2x\n", event);
- break;
- }
- DEBUGP(3, dev, "<- cm4000_event\n");
- return CS_SUCCESS;
-}
-
-static void cm4000_release(dev_link_t *link)
-{
- cmm_cm4000_release(link->priv); /* delay release until device closed */
- pcmcia_release_configuration(link->handle);
- pcmcia_release_io(link->handle, &link->io);
-}
-
-static dev_link_t *cm4000_attach(void)
-{
- struct cm4000_dev *dev;
- dev_link_t *link;
- client_reg_t client_reg;
- int i;
-
- for (i = 0; i < CM4000_MAX_DEV; i++)
- if (dev_table[i] == NULL)
- break;
-
- if (i == CM4000_MAX_DEV) {
- printk(KERN_NOTICE MODULE_NAME ": all devices in use\n");
- return NULL;
- }
-
- /* create a new cm4000_cs device */
- dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL);
- if (dev == NULL)
- return NULL;
-
- link = &dev->link;
- link->priv = dev;
- link->conf.IntType = INT_MEMORY_AND_IO;
- dev_table[i] = link;
-
- /* register with card services */
- client_reg.dev_info = &dev_info;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
-
- i = pcmcia_register_client(&link->handle, &client_reg);
- if (i) {
- cs_error(link->handle, RegisterClient, i);
- cm4000_detach(link);
- return NULL;
- }
-
- init_waitqueue_head(&dev->devq);
- init_waitqueue_head(&dev->ioq);
- init_waitqueue_head(&dev->atrq);
- init_waitqueue_head(&dev->readq);
-
- return link;
-}
-
-static void cm4000_detach_by_devno(int devno, dev_link_t * link)
-{
- struct cm4000_dev *dev = link->priv;
-
- DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno);
-
- if (link->state & DEV_CONFIG) {
- DEBUGP(5, dev, "device still configured (try to release it)\n");
- cm4000_release(link);
- }
-
- if (link->handle) {
- pcmcia_deregister_client(link->handle);
- }
-
- dev_table[devno] = NULL;
- kfree(dev);
- return;
-}
-
-static void cm4000_detach(dev_link_t * link)
-{
- int i;
-
- /* find device */
- for (i = 0; i < CM4000_MAX_DEV; i++)
- if (dev_table[i] == link)
- break;
-
- if (i == CM4000_MAX_DEV)
- return;
-
- cm4000_detach_by_devno(i, link);
- return;
-}
-
-static struct file_operations cm4000_fops = {
- .owner = THIS_MODULE,
- .read = cmm_read,
- .write = cmm_write,
- .ioctl = cmm_ioctl,
- .open = cmm_open,
- .release= cmm_close,
-};
-
-static struct pcmcia_device_id cm4000_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0002),
- PCMCIA_DEVICE_PROD_ID12("CardMan", "4000", 0x2FB368CA, 0xA2BD8C39),
- PCMCIA_DEVICE_NULL,
-};
-MODULE_DEVICE_TABLE(pcmcia, cm4000_ids);
-
-static struct pcmcia_driver cm4000_driver = {
- .owner = THIS_MODULE,
- .drv = {
- .name = "cm4000_cs",
- },
- .attach = cm4000_attach,
- .detach = cm4000_detach,
- .event = cm4000_event,
- .id_table = cm4000_ids,
-};
-
-static int __init cmm_init(void)
-{
- printk(KERN_INFO "%s\n", version);
- pcmcia_register_driver(&cm4000_driver);
- major = register_chrdev(0, DEVICE_NAME, &cm4000_fops);
- if (major < 0) {
- printk(KERN_WARNING MODULE_NAME
- ": could not get major number\n");
- return -1;
- }
-
- return 0;
-}
-
-static void __exit cmm_exit(void)
-{
- int i;
-
- printk(KERN_INFO MODULE_NAME ": unloading\n");
- pcmcia_unregister_driver(&cm4000_driver);
- for (i = 0; i < CM4000_MAX_DEV; i++)
- if (dev_table[i])
- cm4000_detach_by_devno(i, dev_table[i]);
- unregister_chrdev(major, DEVICE_NAME);
-};
-
-module_init(cmm_init);
-module_exit(cmm_exit);
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/trunk/drivers/char/pcmcia/cm4040_cs.c b/trunk/drivers/char/pcmcia/cm4040_cs.c
deleted file mode 100644
index 4c698d908ffa..000000000000
--- a/trunk/drivers/char/pcmcia/cm4040_cs.c
+++ /dev/null
@@ -1,841 +0,0 @@
-/*
- * A driver for the Omnikey PCMCIA smartcard reader CardMan 4040
- *
- * (c) 2000-2004 Omnikey AG (http://www.omnikey.com/)
- *
- * (C) 2005 Harald Welte
- * - add support for poll()
- * - driver cleanup
- * - add waitqueues
- * - adhere to linux kernel coding style and policies
- * - support 2.6.13 "new style" pcmcia interface
- *
- * The device basically is a USB CCID compliant device that has been
- * attached to an I/O-Mapped FIFO.
- *
- * All rights reserved, Dual BSD/GPL Licensed.
- */
-
-/* #define PCMCIA_DEBUG 6 */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "cm4040_cs.h"
-
-
-#ifdef PCMCIA_DEBUG
-#define reader_to_dev(x) (&handle_to_dev(x->link.handle))
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0600);
-#define DEBUGP(n, rdr, x, args...) do { \
- if (pc_debug >= (n)) \
- dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
- __FUNCTION__ , ##args); \
- } while (0)
-#else
-#define DEBUGP(n, rdr, x, args...)
-#endif
-
-static char *version =
-"OMNIKEY CardMan 4040 v1.1.0gm4 - All bugs added by Harald Welte";
-
-#define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ)
-#define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ)
-#define CCID_DRIVER_MINIMUM_TIMEOUT (3*HZ)
-#define READ_WRITE_BUFFER_SIZE 512
-#define POLL_LOOP_COUNT 1000
-
-/* how often to poll for fifo status change */
-#define POLL_PERIOD msecs_to_jiffies(10)
-
-static void reader_release(dev_link_t *link);
-static void reader_detach(dev_link_t *link);
-
-static int major;
-
-#define BS_READABLE 0x01
-#define BS_WRITABLE 0x02
-
-struct reader_dev {
- dev_link_t link;
- dev_node_t node;
- wait_queue_head_t devq;
- wait_queue_head_t poll_wait;
- wait_queue_head_t read_wait;
- wait_queue_head_t write_wait;
- unsigned long buffer_status;
- unsigned long timeout;
- unsigned char s_buf[READ_WRITE_BUFFER_SIZE];
- unsigned char r_buf[READ_WRITE_BUFFER_SIZE];
- struct timer_list poll_timer;
-};
-
-static dev_info_t dev_info = MODULE_NAME;
-static dev_link_t *dev_table[CM_MAX_DEV];
-
-#ifndef PCMCIA_DEBUG
-#define xoutb outb
-#define xinb inb
-#else
-static inline void xoutb(unsigned char val, unsigned short port)
-{
- if (pc_debug >= 7)
- printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
- outb(val, port);
-}
-
-static inline unsigned char xinb(unsigned short port)
-{
- unsigned char val;
-
- val = inb(port);
- if (pc_debug >= 7)
- printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
- return val;
-}
-#endif
-
-/* poll the device fifo status register. not to be confused with
- * the poll syscall. */
-static void cm4040_do_poll(unsigned long dummy)
-{
- struct reader_dev *dev = (struct reader_dev *) dummy;
- unsigned int obs = xinb(dev->link.io.BasePort1
- + REG_OFFSET_BUFFER_STATUS);
-
- if ((obs & BSR_BULK_IN_FULL)) {
- set_bit(BS_READABLE, &dev->buffer_status);
- DEBUGP(4, dev, "waking up read_wait\n");
- wake_up_interruptible(&dev->read_wait);
- } else
- clear_bit(BS_READABLE, &dev->buffer_status);
-
- if (!(obs & BSR_BULK_OUT_FULL)) {
- set_bit(BS_WRITABLE, &dev->buffer_status);
- DEBUGP(4, dev, "waking up write_wait\n");
- wake_up_interruptible(&dev->write_wait);
- } else
- clear_bit(BS_WRITABLE, &dev->buffer_status);
-
- if (dev->buffer_status)
- wake_up_interruptible(&dev->poll_wait);
-
- mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD);
-}
-
-static void cm4040_stop_poll(struct reader_dev *dev)
-{
- del_timer_sync(&dev->poll_timer);
-}
-
-static int wait_for_bulk_out_ready(struct reader_dev *dev)
-{
- int i, rc;
- int iobase = dev->link.io.BasePort1;
-
- for (i = 0; i < POLL_LOOP_COUNT; i++) {
- if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
- & BSR_BULK_OUT_FULL) == 0) {
- DEBUGP(4, dev, "BulkOut empty (i=%d)\n", i);
- return 1;
- }
- }
-
- DEBUGP(4, dev, "wait_event_interruptible_timeout(timeout=%ld\n",
- dev->timeout);
- rc = wait_event_interruptible_timeout(dev->write_wait,
- test_and_clear_bit(BS_WRITABLE,
- &dev->buffer_status),
- dev->timeout);
-
- if (rc > 0)
- DEBUGP(4, dev, "woke up: BulkOut empty\n");
- else if (rc == 0)
- DEBUGP(4, dev, "woke up: BulkOut full, returning 0 :(\n");
- else if (rc < 0)
- DEBUGP(4, dev, "woke up: signal arrived\n");
-
- return rc;
-}
-
-/* Write to Sync Control Register */
-static int write_sync_reg(unsigned char val, struct reader_dev *dev)
-{
- int iobase = dev->link.io.BasePort1;
- int rc;
-
- rc = wait_for_bulk_out_ready(dev);
- if (rc <= 0)
- return rc;
-
- xoutb(val, iobase + REG_OFFSET_SYNC_CONTROL);
- rc = wait_for_bulk_out_ready(dev);
- if (rc <= 0)
- return rc;
-
- return 1;
-}
-
-static int wait_for_bulk_in_ready(struct reader_dev *dev)
-{
- int i, rc;
- int iobase = dev->link.io.BasePort1;
-
- for (i = 0; i < POLL_LOOP_COUNT; i++) {
- if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
- & BSR_BULK_IN_FULL) == BSR_BULK_IN_FULL) {
- DEBUGP(3, dev, "BulkIn full (i=%d)\n", i);
- return 1;
- }
- }
-
- DEBUGP(4, dev, "wait_event_interruptible_timeout(timeout=%ld\n",
- dev->timeout);
- rc = wait_event_interruptible_timeout(dev->read_wait,
- test_and_clear_bit(BS_READABLE,
- &dev->buffer_status),
- dev->timeout);
- if (rc > 0)
- DEBUGP(4, dev, "woke up: BulkIn full\n");
- else if (rc == 0)
- DEBUGP(4, dev, "woke up: BulkIn not full, returning 0 :(\n");
- else if (rc < 0)
- DEBUGP(4, dev, "woke up: signal arrived\n");
-
- return rc;
-}
-
-static ssize_t cm4040_read(struct file *filp, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct reader_dev *dev = filp->private_data;
- int iobase = dev->link.io.BasePort1;
- size_t bytes_to_read;
- unsigned long i;
- size_t min_bytes_to_read;
- int rc;
- unsigned char uc;
-
- DEBUGP(2, dev, "-> cm4040_read(%s,%d)\n", current->comm, current->pid);
-
- if (count == 0)
- return 0;
-
- if (count < 10)
- return -EFAULT;
-
- if (filp->f_flags & O_NONBLOCK) {
- DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n");
- DEBUGP(2, dev, "<- cm4040_read (failure)\n");
- return -EAGAIN;
- }
-
- if ((dev->link.state & DEV_PRESENT)==0)
- return -ENODEV;
-
- for (i = 0; i < 5; i++) {
- rc = wait_for_bulk_in_ready(dev);
- if (rc <= 0) {
- DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc);
- DEBUGP(2, dev, "<- cm4040_read (failed)\n");
- if (rc == -ERESTARTSYS)
- return rc;
- return -EIO;
- }
- dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN);
-#ifdef PCMCIA_DEBUG
- if (pc_debug >= 6)
- printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
- }
- printk("\n");
-#else
- }
-#endif
-
- bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]);
-
- DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read);
-
- min_bytes_to_read = min(count, bytes_to_read + 5);
-
- DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read);
-
- for (i = 0; i < (min_bytes_to_read-5); i++) {
- rc = wait_for_bulk_in_ready(dev);
- if (rc <= 0) {
- DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc);
- DEBUGP(2, dev, "<- cm4040_read (failed)\n");
- if (rc == -ERESTARTSYS)
- return rc;
- return -EIO;
- }
- dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN);
-#ifdef PCMCIA_DEBUG
- if (pc_debug >= 6)
- printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
- }
- printk("\n");
-#else
- }
-#endif
-
- *ppos = min_bytes_to_read;
- if (copy_to_user(buf, dev->r_buf, min_bytes_to_read))
- return -EFAULT;
-
- rc = wait_for_bulk_in_ready(dev);
- if (rc <= 0) {
- DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc);
- DEBUGP(2, dev, "<- cm4040_read (failed)\n");
- if (rc == -ERESTARTSYS)
- return rc;
- return -EIO;
- }
-
- rc = write_sync_reg(SCR_READER_TO_HOST_DONE, dev);
- if (rc <= 0) {
- DEBUGP(5, dev, "write_sync_reg c=%.2x\n", rc);
- DEBUGP(2, dev, "<- cm4040_read (failed)\n");
- if (rc == -ERESTARTSYS)
- return rc;
- else
- return -EIO;
- }
-
- uc = xinb(iobase + REG_OFFSET_BULK_IN);
-
- DEBUGP(2, dev, "<- cm4040_read (successfully)\n");
- return min_bytes_to_read;
-}
-
-static ssize_t cm4040_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct reader_dev *dev = filp->private_data;
- int iobase = dev->link.io.BasePort1;
- ssize_t rc;
- int i;
- unsigned int bytes_to_write;
-
- DEBUGP(2, dev, "-> cm4040_write(%s,%d)\n", current->comm, current->pid);
-
- if (count == 0) {
- DEBUGP(2, dev, "<- cm4040_write empty read (successfully)\n");
- return 0;
- }
-
- if (count < 5) {
- DEBUGP(2, dev, "<- cm4040_write buffersize=%Zd < 5\n", count);
- return -EIO;
- }
-
- if (filp->f_flags & O_NONBLOCK) {
- DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n");
- DEBUGP(4, dev, "<- cm4040_write (failure)\n");
- return -EAGAIN;
- }
-
- if ((dev->link.state & DEV_PRESENT) == 0)
- return -ENODEV;
-
- bytes_to_write = count;
- if (copy_from_user(dev->s_buf, buf, bytes_to_write))
- return -EFAULT;
-
- switch (dev->s_buf[0]) {
- case CMD_PC_TO_RDR_XFRBLOCK:
- case CMD_PC_TO_RDR_SECURE:
- case CMD_PC_TO_RDR_TEST_SECURE:
- case CMD_PC_TO_RDR_OK_SECURE:
- dev->timeout = CCID_DRIVER_BULK_DEFAULT_TIMEOUT;
- break;
-
- case CMD_PC_TO_RDR_ICCPOWERON:
- dev->timeout = CCID_DRIVER_ASYNC_POWERUP_TIMEOUT;
- break;
-
- case CMD_PC_TO_RDR_GETSLOTSTATUS:
- case CMD_PC_TO_RDR_ICCPOWEROFF:
- case CMD_PC_TO_RDR_GETPARAMETERS:
- case CMD_PC_TO_RDR_RESETPARAMETERS:
- case CMD_PC_TO_RDR_SETPARAMETERS:
- case CMD_PC_TO_RDR_ESCAPE:
- case CMD_PC_TO_RDR_ICCCLOCK:
- default:
- dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
- break;
- }
-
- rc = write_sync_reg(SCR_HOST_TO_READER_START, dev);
- if (rc <= 0) {
- DEBUGP(5, dev, "write_sync_reg c=%.2Zx\n", rc);
- DEBUGP(2, dev, "<- cm4040_write (failed)\n");
- if (rc == -ERESTARTSYS)
- return rc;
- else
- return -EIO;
- }
-
- DEBUGP(4, dev, "start \n");
-
- for (i = 0; i < bytes_to_write; i++) {
- rc = wait_for_bulk_out_ready(dev);
- if (rc <= 0) {
- DEBUGP(5, dev, "wait_for_bulk_out_ready rc=%.2Zx\n",
- rc);
- DEBUGP(2, dev, "<- cm4040_write (failed)\n");
- if (rc == -ERESTARTSYS)
- return rc;
- else
- return -EIO;
- }
-
- xoutb(dev->s_buf[i],iobase + REG_OFFSET_BULK_OUT);
- }
- DEBUGP(4, dev, "end\n");
-
- rc = write_sync_reg(SCR_HOST_TO_READER_DONE, dev);
-
- if (rc <= 0) {
- DEBUGP(5, dev, "write_sync_reg c=%.2Zx\n", rc);
- DEBUGP(2, dev, "<- cm4040_write (failed)\n");
- if (rc == -ERESTARTSYS)
- return rc;
- else
- return -EIO;
- }
-
- DEBUGP(2, dev, "<- cm4040_write (successfully)\n");
- return count;
-}
-
-static unsigned int cm4040_poll(struct file *filp, poll_table *wait)
-{
- struct reader_dev *dev = filp->private_data;
- unsigned int mask = 0;
-
- poll_wait(filp, &dev->poll_wait, wait);
-
- if (test_and_clear_bit(BS_READABLE, &dev->buffer_status))
- mask |= POLLIN | POLLRDNORM;
- if (test_and_clear_bit(BS_WRITABLE, &dev->buffer_status))
- mask |= POLLOUT | POLLWRNORM;
-
- DEBUGP(2, dev, "<- cm4040_poll(%u)\n", mask);
-
- return mask;
-}
-
-static int cm4040_open(struct inode *inode, struct file *filp)
-{
- struct reader_dev *dev;
- dev_link_t *link;
- int minor = iminor(inode);
-
- if (minor >= CM_MAX_DEV)
- return -ENODEV;
-
- link = dev_table[minor];
- if (link == NULL || !(DEV_OK(link)))
- return -ENODEV;
-
- if (link->open)
- return -EBUSY;
-
- dev = link->priv;
- filp->private_data = dev;
-
- if (filp->f_flags & O_NONBLOCK) {
- DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n");
- return -EAGAIN;
- }
-
- link->open = 1;
-
- dev->poll_timer.data = (unsigned long) dev;
- mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD);
-
- DEBUGP(2, dev, "<- cm4040_open (successfully)\n");
- return nonseekable_open(inode, filp);
-}
-
-static int cm4040_close(struct inode *inode, struct file *filp)
-{
- struct reader_dev *dev = filp->private_data;
- dev_link_t *link;
- int minor = iminor(inode);
-
- DEBUGP(2, dev, "-> cm4040_close(maj/min=%d.%d)\n", imajor(inode),
- iminor(inode));
-
- if (minor >= CM_MAX_DEV)
- return -ENODEV;
-
- link = dev_table[minor];
- if (link == NULL)
- return -ENODEV;
-
- cm4040_stop_poll(dev);
-
- link->open = 0;
- wake_up(&dev->devq);
-
- DEBUGP(2, dev, "<- cm4040_close\n");
- return 0;
-}
-
-static void cm4040_reader_release(dev_link_t *link)
-{
- struct reader_dev *dev = link->priv;
-
- DEBUGP(3, dev, "-> cm4040_reader_release\n");
- while (link->open) {
- DEBUGP(3, dev, KERN_INFO MODULE_NAME ": delaying release "
- "until process has terminated\n");
- wait_event(dev->devq, (link->open == 0));
- }
- DEBUGP(3, dev, "<- cm4040_reader_release\n");
- return;
-}
-
-static void reader_config(dev_link_t *link, int devno)
-{
- client_handle_t handle;
- struct reader_dev *dev;
- tuple_t tuple;
- cisparse_t parse;
- config_info_t conf;
- u_char buf[64];
- int fail_fn, fail_rc;
- int rc;
-
- handle = link->handle;
-
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) {
- fail_fn = GetFirstTuple;
- goto cs_failed;
- }
- if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) {
- fail_fn = GetTupleData;
- goto cs_failed;
- }
- if ((fail_rc = pcmcia_parse_tuple(handle, &tuple, &parse))
- != CS_SUCCESS) {
- fail_fn = ParseTuple;
- goto cs_failed;
- }
- if ((fail_rc = pcmcia_get_configuration_info(handle, &conf))
- != CS_SUCCESS) {
- fail_fn = GetConfigurationInfo;
- goto cs_failed;
- }
-
- link->state |= DEV_CONFIG;
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
- link->conf.Vcc = conf.Vcc;
-
- link->io.BasePort2 = 0;
- link->io.NumPorts2 = 0;
- link->io.Attributes2 = 0;
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- for (rc = pcmcia_get_first_tuple(handle, &tuple);
- rc == CS_SUCCESS;
- rc = pcmcia_get_next_tuple(handle, &tuple)) {
- rc = pcmcia_get_tuple_data(handle, &tuple);
- if (rc != CS_SUCCESS)
- continue;
- rc = pcmcia_parse_tuple(handle, &tuple, &parse);
- if (rc != CS_SUCCESS)
- continue;
-
- link->conf.ConfigIndex = parse.cftable_entry.index;
-
- if (!parse.cftable_entry.io.nwin)
- continue;
-
- link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
- link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = parse.cftable_entry.io.flags
- & CISTPL_IO_LINES_MASK;
- rc = pcmcia_request_io(handle, &link->io);
-
- dev_printk(KERN_INFO, &handle_to_dev(handle), "foo");
- if (rc == CS_SUCCESS)
- break;
- else
- dev_printk(KERN_INFO, &handle_to_dev(handle),
- "pcmcia_request_io failed 0x%x\n", rc);
- }
- if (rc != CS_SUCCESS)
- goto cs_release;
-
- link->conf.IntType = 00000002;
-
- if ((fail_rc = pcmcia_request_configuration(handle,&link->conf))
- !=CS_SUCCESS) {
- fail_fn = RequestConfiguration;
- dev_printk(KERN_INFO, &handle_to_dev(handle),
- "pcmcia_request_configuration failed 0x%x\n",
- fail_rc);
- goto cs_release;
- }
-
- dev = link->priv;
- sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
- dev->node.major = major;
- dev->node.minor = devno;
- dev->node.next = NULL;
- link->dev = &dev->node;
- link->state &= ~DEV_CONFIG_PENDING;
-
- DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno,
- link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1);
- DEBUGP(2, dev, "<- reader_config (succ)\n");
-
- return;
-
-cs_failed:
- cs_error(handle, fail_fn, fail_rc);
-cs_release:
- reader_release(link);
- link->state &= ~DEV_CONFIG_PENDING;
-}
-
-static int reader_event(event_t event, int priority,
- event_callback_args_t *args)
-{
- dev_link_t *link;
- struct reader_dev *dev;
- int devno;
-
- link = args->client_data;
- dev = link->priv;
- DEBUGP(3, dev, "-> reader_event\n");
- for (devno = 0; devno < CM_MAX_DEV; devno++) {
- if (dev_table[devno] == link)
- break;
- }
- if (devno == CM_MAX_DEV)
- return CS_BAD_ADAPTER;
-
- switch (event) {
- case CS_EVENT_CARD_INSERTION:
- DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- reader_config(link, devno);
- break;
- case CS_EVENT_CARD_REMOVAL:
- DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
- link->state &= ~DEV_PRESENT;
- break;
- case CS_EVENT_PM_SUSPEND:
- DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
- "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
- link->state |= DEV_SUSPEND;
-
- case CS_EVENT_RESET_PHYSICAL:
- DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
- if (link->state & DEV_CONFIG) {
- DEBUGP(5, dev, "ReleaseConfiguration\n");
- pcmcia_release_configuration(link->handle);
- }
- break;
- case CS_EVENT_PM_RESUME:
- DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
- "(fall-through to CS_EVENT_CARD_RESET)\n");
- link->state &= ~DEV_SUSPEND;
-
- case CS_EVENT_CARD_RESET:
- DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
- if ((link->state & DEV_CONFIG)) {
- DEBUGP(5, dev, "RequestConfiguration\n");
- pcmcia_request_configuration(link->handle,
- &link->conf);
- }
- break;
- default:
- DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
- event);
- break;
- }
- DEBUGP(3, dev, "<- reader_event\n");
- return CS_SUCCESS;
-}
-
-static void reader_release(dev_link_t *link)
-{
- cm4040_reader_release(link->priv);
- pcmcia_release_configuration(link->handle);
- pcmcia_release_io(link->handle, &link->io);
-}
-
-static dev_link_t *reader_attach(void)
-{
- struct reader_dev *dev;
- dev_link_t *link;
- client_reg_t client_reg;
- int i;
-
- for (i = 0; i < CM_MAX_DEV; i++) {
- if (dev_table[i] == NULL)
- break;
- }
-
- if (i == CM_MAX_DEV)
- return NULL;
-
- dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL);
- if (dev == NULL)
- return NULL;
-
- dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
- dev->buffer_status = 0;
-
- link = &dev->link;
- link->priv = dev;
-
- link->conf.IntType = INT_MEMORY_AND_IO;
- dev_table[i] = link;
-
- client_reg.dev_info = &dev_info;
- client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
- client_reg.EventMask=
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- i = pcmcia_register_client(&link->handle, &client_reg);
- if (i) {
- cs_error(link->handle, RegisterClient, i);
- reader_detach(link);
- return NULL;
- }
- init_waitqueue_head(&dev->devq);
- init_waitqueue_head(&dev->poll_wait);
- init_waitqueue_head(&dev->read_wait);
- init_waitqueue_head(&dev->write_wait);
- init_timer(&dev->poll_timer);
- dev->poll_timer.function = &cm4040_do_poll;
-
- return link;
-}
-
-static void reader_detach_by_devno(int devno, dev_link_t *link)
-{
- struct reader_dev *dev = link->priv;
-
- if (link->state & DEV_CONFIG) {
- DEBUGP(5, dev, "device still configured (try to release it)\n");
- reader_release(link);
- }
-
- pcmcia_deregister_client(link->handle);
- dev_table[devno] = NULL;
- DEBUGP(5, dev, "freeing dev=%p\n", dev);
- cm4040_stop_poll(dev);
- kfree(dev);
- return;
-}
-
-static void reader_detach(dev_link_t *link)
-{
- int i;
-
- /* find device */
- for (i = 0; i < CM_MAX_DEV; i++) {
- if (dev_table[i] == link)
- break;
- }
- if (i == CM_MAX_DEV)
- return;
-
- reader_detach_by_devno(i, link);
- return;
-}
-
-static struct file_operations reader_fops = {
- .owner = THIS_MODULE,
- .read = cm4040_read,
- .write = cm4040_write,
- .open = cm4040_open,
- .release = cm4040_close,
- .poll = cm4040_poll,
-};
-
-static struct pcmcia_device_id cm4040_ids[] = {
- PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0200),
- PCMCIA_DEVICE_PROD_ID12("OMNIKEY", "CardMan 4040",
- 0xE32CDD8C, 0x8F23318B),
- PCMCIA_DEVICE_NULL,
-};
-MODULE_DEVICE_TABLE(pcmcia, cm4040_ids);
-
-static struct pcmcia_driver reader_driver = {
- .owner = THIS_MODULE,
- .drv = {
- .name = "cm4040_cs",
- },
- .attach = reader_attach,
- .detach = reader_detach,
- .event = reader_event,
- .id_table = cm4040_ids,
-};
-
-static int __init cm4040_init(void)
-{
- printk(KERN_INFO "%s\n", version);
- pcmcia_register_driver(&reader_driver);
- major = register_chrdev(0, DEVICE_NAME, &reader_fops);
- if (major < 0) {
- printk(KERN_WARNING MODULE_NAME
- ": could not get major number\n");
- return -1;
- }
- return 0;
-}
-
-static void __exit cm4040_exit(void)
-{
- int i;
-
- printk(KERN_INFO MODULE_NAME ": unloading\n");
- pcmcia_unregister_driver(&reader_driver);
- for (i = 0; i < CM_MAX_DEV; i++) {
- if (dev_table[i])
- reader_detach_by_devno(i, dev_table[i]);
- }
- unregister_chrdev(major, DEVICE_NAME);
-}
-
-module_init(cm4040_init);
-module_exit(cm4040_exit);
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/trunk/drivers/char/pcmcia/cm4040_cs.h b/trunk/drivers/char/pcmcia/cm4040_cs.h
deleted file mode 100644
index 9a8b805c5095..000000000000
--- a/trunk/drivers/char/pcmcia/cm4040_cs.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef _CM4040_H_
-#define _CM4040_H_
-
-#define CM_MAX_DEV 4
-
-#define DEVICE_NAME "cmx"
-#define MODULE_NAME "cm4040_cs"
-
-#define REG_OFFSET_BULK_OUT 0
-#define REG_OFFSET_BULK_IN 0
-#define REG_OFFSET_BUFFER_STATUS 1
-#define REG_OFFSET_SYNC_CONTROL 2
-
-#define BSR_BULK_IN_FULL 0x02
-#define BSR_BULK_OUT_FULL 0x01
-
-#define SCR_HOST_TO_READER_START 0x80
-#define SCR_ABORT 0x40
-#define SCR_EN_NOTIFY 0x20
-#define SCR_ACK_NOTIFY 0x10
-#define SCR_READER_TO_HOST_DONE 0x08
-#define SCR_HOST_TO_READER_DONE 0x04
-#define SCR_PULSE_INTERRUPT 0x02
-#define SCR_POWER_DOWN 0x01
-
-
-#define CMD_PC_TO_RDR_ICCPOWERON 0x62
-#define CMD_PC_TO_RDR_GETSLOTSTATUS 0x65
-#define CMD_PC_TO_RDR_ICCPOWEROFF 0x63
-#define CMD_PC_TO_RDR_SECURE 0x69
-#define CMD_PC_TO_RDR_GETPARAMETERS 0x6C
-#define CMD_PC_TO_RDR_RESETPARAMETERS 0x6D
-#define CMD_PC_TO_RDR_SETPARAMETERS 0x61
-#define CMD_PC_TO_RDR_XFRBLOCK 0x6F
-#define CMD_PC_TO_RDR_ESCAPE 0x6B
-#define CMD_PC_TO_RDR_ICCCLOCK 0x6E
-#define CMD_PC_TO_RDR_TEST_SECURE 0x74
-#define CMD_PC_TO_RDR_OK_SECURE 0x89
-
-
-#define CMD_RDR_TO_PC_SLOTSTATUS 0x81
-#define CMD_RDR_TO_PC_DATABLOCK 0x80
-#define CMD_RDR_TO_PC_PARAMETERS 0x82
-#define CMD_RDR_TO_PC_ESCAPE 0x83
-#define CMD_RDR_TO_PC_OK_SECURE 0x89
-
-#endif /* _CM4040_H_ */
diff --git a/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c
index 62aa0e534a6d..82c6abde68df 100644
--- a/trunk/drivers/char/synclink.c
+++ b/trunk/drivers/char/synclink.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/char/synclink.c
*
- * $Id: synclink.c,v 4.38 2005/11/07 16:30:34 paulkf Exp $
+ * $Id: synclink.c,v 4.37 2005/09/07 13:13:19 paulkf Exp $
*
* Device driver for Microgate SyncLink ISA and PCI
* high speed multiprotocol serial adapters.
@@ -101,7 +101,6 @@
#include
#include
#include
-#include
#ifdef CONFIG_HDLC_MODULE
#define CONFIG_HDLC 1
@@ -149,7 +148,6 @@ typedef struct _DMABUFFERENTRY
u32 link; /* 32-bit flat link to next buffer entry */
char *virt_addr; /* virtual address of data buffer */
u32 phys_entry; /* physical address of this buffer entry */
- dma_addr_t dma_addr;
} DMABUFFERENTRY, *DMAPBUFFERENTRY;
/* The queue of BH actions to be performed */
@@ -235,8 +233,7 @@ struct mgsl_struct {
int ri_chkcount;
char *buffer_list; /* virtual address of Rx & Tx buffer lists */
- u32 buffer_list_phys;
- dma_addr_t buffer_list_dma_addr;
+ unsigned long buffer_list_phys;
unsigned int rx_buffer_count; /* count of total allocated Rx buffers */
DMABUFFERENTRY *rx_buffer_list; /* list of receive buffer entries */
@@ -899,7 +896,7 @@ module_param_array(txdmabufs, int, NULL, 0);
module_param_array(txholdbufs, int, NULL, 0);
static char *driver_name = "SyncLink serial driver";
-static char *driver_version = "$Revision: 4.38 $";
+static char *driver_version = "$Revision: 4.37 $";
static int synclink_init_one (struct pci_dev *dev,
const struct pci_device_id *ent);
@@ -3814,10 +3811,11 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info )
/* inspect portions of the buffer while other portions are being */
/* updated by the adapter using Bus Master DMA. */
- info->buffer_list = dma_alloc_coherent(NULL, BUFFERLISTSIZE, &info->buffer_list_dma_addr, GFP_KERNEL);
- if (info->buffer_list == NULL)
+ info->buffer_list = kmalloc(BUFFERLISTSIZE, GFP_KERNEL | GFP_DMA);
+ if ( info->buffer_list == NULL )
return -ENOMEM;
- info->buffer_list_phys = (u32)(info->buffer_list_dma_addr);
+
+ info->buffer_list_phys = isa_virt_to_bus(info->buffer_list);
}
/* We got the memory for the buffer entry lists. */
@@ -3884,8 +3882,8 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info )
*/
static void mgsl_free_buffer_list_memory( struct mgsl_struct *info )
{
- if (info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI)
- dma_free_coherent(NULL, BUFFERLISTSIZE, info->buffer_list, info->buffer_list_dma_addr);
+ if ( info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI )
+ kfree(info->buffer_list);
info->buffer_list = NULL;
info->rx_buffer_list = NULL;
@@ -3912,7 +3910,7 @@ static void mgsl_free_buffer_list_memory( struct mgsl_struct *info )
static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount)
{
int i;
- u32 phys_addr;
+ unsigned long phys_addr;
/* Allocate page sized buffers for the receive buffer list */
@@ -3924,10 +3922,11 @@ static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *Buff
info->last_mem_alloc += DMABUFFERSIZE;
} else {
/* ISA adapter uses system memory. */
- BufferList[i].virt_addr = dma_alloc_coherent(NULL, DMABUFFERSIZE, &BufferList[i].dma_addr, GFP_KERNEL);
- if (BufferList[i].virt_addr == NULL)
+ BufferList[i].virt_addr =
+ kmalloc(DMABUFFERSIZE, GFP_KERNEL | GFP_DMA);
+ if ( BufferList[i].virt_addr == NULL )
return -ENOMEM;
- phys_addr = (u32)(BufferList[i].dma_addr);
+ phys_addr = isa_virt_to_bus(BufferList[i].virt_addr);
}
BufferList[i].phys_addr = phys_addr;
}
@@ -3958,7 +3957,7 @@ static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *Buf
for ( i = 0 ; i < Buffercount ; i++ ) {
if ( BufferList[i].virt_addr ) {
if ( info->bus_type != MGSL_BUS_TYPE_PCI )
- dma_free_coherent(NULL, DMABUFFERSIZE, BufferList[i].virt_addr, BufferList[i].dma_addr);
+ kfree(BufferList[i].virt_addr);
BufferList[i].virt_addr = NULL;
}
}
diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c
index 0b283d246730..303f15880466 100644
--- a/trunk/drivers/char/tpm/tpm.c
+++ b/trunk/drivers/char/tpm/tpm.c
@@ -43,13 +43,6 @@ static void user_reader_timeout(unsigned long ptr)
{
struct tpm_chip *chip = (struct tpm_chip *) ptr;
- schedule_work(&chip->work);
-}
-
-static void timeout_work(void * ptr)
-{
- struct tpm_chip *chip = ptr;
-
down(&chip->buffer_mutex);
atomic_set(&chip->data_pending, 0);
memset(chip->data_buffer, 0, TPM_BUFSIZE);
@@ -435,7 +428,8 @@ ssize_t tpm_read(struct file * file, char __user *buf,
ret_size = size;
down(&chip->buffer_mutex);
- if (copy_to_user(buf, chip->data_buffer, ret_size))
+ if (copy_to_user
+ ((void __user *) buf, chip->data_buffer, ret_size))
ret_size = -EFAULT;
up(&chip->buffer_mutex);
}
@@ -466,7 +460,7 @@ void tpm_remove_hardware(struct device *dev)
sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
- ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+ !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
kfree(chip);
@@ -534,8 +528,6 @@ int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
init_MUTEX(&chip->tpm_mutex);
INIT_LIST_HEAD(&chip->list);
- INIT_WORK(&chip->work, timeout_work, chip);
-
init_timer(&chip->user_read_timer);
chip->user_read_timer.function = user_reader_timeout;
chip->user_read_timer.data = (unsigned long) chip;
diff --git a/trunk/drivers/char/tpm/tpm.h b/trunk/drivers/char/tpm/tpm.h
index 159882ca69dd..9293bcc4dc62 100644
--- a/trunk/drivers/char/tpm/tpm.h
+++ b/trunk/drivers/char/tpm/tpm.h
@@ -50,11 +50,7 @@ struct tpm_vendor_specific {
u8 req_complete_mask;
u8 req_complete_val;
u8 req_canceled;
- void __iomem *iobase; /* ioremapped address */
- unsigned long base; /* TPM base address */
-
- int region_size;
- int have_region;
+ u16 base; /* TPM base address */
int (*recv) (struct tpm_chip *, u8 *, size_t);
int (*send) (struct tpm_chip *, u8 *, size_t);
@@ -77,7 +73,6 @@ struct tpm_chip {
struct semaphore buffer_mutex;
struct timer_list user_read_timer; /* user needs to claim result */
- struct work_struct work;
struct semaphore tpm_mutex; /* tpm is processing */
struct tpm_vendor_specific *vendor;
diff --git a/trunk/drivers/char/tpm/tpm_atmel.c b/trunk/drivers/char/tpm/tpm_atmel.c
index deb4b5c80914..32e01450c425 100644
--- a/trunk/drivers/char/tpm/tpm_atmel.c
+++ b/trunk/drivers/char/tpm/tpm_atmel.c
@@ -19,8 +19,14 @@
*
*/
+#include
#include "tpm.h"
-#include "tpm_atmel.h"
+
+/* Atmel definitions */
+enum tpm_atmel_addr {
+ TPM_ATMEL_BASE_ADDR_LO = 0x08,
+ TPM_ATMEL_BASE_ADDR_HI = 0x09
+};
/* write status bits */
enum tpm_atmel_write_status {
@@ -47,13 +53,13 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
return -EIO;
for (i = 0; i < 6; i++) {
- status = atmel_getb(chip, 1);
+ status = inb(chip->vendor->base + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
dev_err(chip->dev,
"error reading header\n");
return -EIO;
}
- *buf++ = atmel_getb(chip, 0);
+ *buf++ = inb(chip->vendor->base);
}
/* size of the data received */
@@ -64,7 +70,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
dev_err(chip->dev,
"Recv size(%d) less than available space\n", size);
for (; i < size; i++) { /* clear the waiting data anyway */
- status = atmel_getb(chip, 1);
+ status = inb(chip->vendor->base + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
dev_err(chip->dev,
"error reading data\n");
@@ -76,17 +82,17 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
/* read all the data available */
for (; i < size; i++) {
- status = atmel_getb(chip, 1);
+ status = inb(chip->vendor->base + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
dev_err(chip->dev,
"error reading data\n");
return -EIO;
}
- *buf++ = atmel_getb(chip, 0);
+ *buf++ = inb(chip->vendor->base);
}
/* make sure data available is gone */
- status = atmel_getb(chip, 1);
+ status = inb(chip->vendor->base + 1);
if (status & ATML_STATUS_DATA_AVAIL) {
dev_err(chip->dev, "data available is stuck\n");
return -EIO;
@@ -102,7 +108,7 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
dev_dbg(chip->dev, "tpm_atml_send:\n");
for (i = 0; i < count; i++) {
dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]);
- atmel_putb(buf[i], chip, 0);
+ outb(buf[i], chip->vendor->base);
}
return count;
@@ -110,12 +116,12 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
static void tpm_atml_cancel(struct tpm_chip *chip)
{
- atmel_putb(ATML_STATUS_ABORT, chip, 1);
+ outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
}
static u8 tpm_atml_status(struct tpm_chip *chip)
{
- return atmel_getb(chip, 1);
+ return inb(chip->vendor->base + 1);
}
static struct file_operations atmel_ops = {
@@ -156,16 +162,12 @@ static struct tpm_vendor_specific tpm_atmel = {
static struct platform_device *pdev;
-static void atml_plat_remove(void)
+static void __devexit tpm_atml_remove(struct device *dev)
{
- struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
-
+ struct tpm_chip *chip = dev_get_drvdata(dev);
if (chip) {
- if (chip->vendor->have_region)
- atmel_release_region(chip->vendor->base, chip->vendor->region_size);
- atmel_put_base_addr(chip->vendor);
+ release_region(chip->vendor->base, 2);
tpm_remove_hardware(chip->dev);
- platform_device_unregister(pdev);
}
}
@@ -180,40 +182,72 @@ static struct device_driver atml_drv = {
static int __init init_atmel(void)
{
int rc = 0;
+ int lo, hi;
driver_register(&atml_drv);
- if (atmel_get_base_addr(&tpm_atmel) != 0) {
- rc = -ENODEV;
- goto err_unreg_drv;
+ lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
+ hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
+
+ tpm_atmel.base = (hi<<8)|lo;
+
+ /* verify that it is an Atmel part */
+ if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
+ || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
+ return -ENODEV;
+ }
+
+ /* verify chip version number is 1.1 */
+ if ( (tpm_read_index(TPM_ADDR, 0x00) != 0x01) ||
+ (tpm_read_index(TPM_ADDR, 0x01) != 0x01 ))
+ return -ENODEV;
+
+ pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
+ if ( !pdev )
+ return -ENOMEM;
+
+ pdev->name = "tpm_atmel0";
+ pdev->id = -1;
+ pdev->num_resources = 0;
+ pdev->dev.release = tpm_atml_remove;
+ pdev->dev.driver = &atml_drv;
+
+ if ((rc = platform_device_register(pdev)) < 0) {
+ kfree(pdev);
+ pdev = NULL;
+ return rc;
}
- tpm_atmel.have_region = (atmel_request_region( tpm_atmel.base, tpm_atmel.region_size, "tpm_atmel0") == NULL) ? 0 : 1;
+ if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) {
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ return -EBUSY;
+ }
- if (IS_ERR(pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0 ))) {
- rc = PTR_ERR(pdev);
- goto err_rel_reg;
+ if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) {
+ release_region(tpm_atmel.base, 2);
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ return rc;
}
- if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
- goto err_unreg_dev;
+ dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n",
+ tpm_atmel.base);
return 0;
-
-err_unreg_dev:
- platform_device_unregister(pdev);
-err_rel_reg:
- if (tpm_atmel.have_region)
- atmel_release_region(tpm_atmel.base, tpm_atmel.region_size);
- atmel_put_base_addr(&tpm_atmel);
-err_unreg_drv:
- driver_unregister(&atml_drv);
- return rc;
}
static void __exit cleanup_atmel(void)
{
+ if (pdev) {
+ tpm_atml_remove(&pdev->dev);
+ platform_device_unregister(pdev);
+ kfree(pdev);
+ pdev = NULL;
+ }
+
driver_unregister(&atml_drv);
- atml_plat_remove();
}
module_init(init_atmel);
diff --git a/trunk/drivers/char/tpm/tpm_atmel.h b/trunk/drivers/char/tpm/tpm_atmel.h
deleted file mode 100644
index 3c5b9a8d1c49..000000000000
--- a/trunk/drivers/char/tpm/tpm_atmel.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2005 IBM Corporation
- *
- * Authors:
- * Kylene Hall
- *
- * Maintained by:
- *
- * Device driver for TCG/TCPA TPM (trusted platform module).
- * Specifications at www.trustedcomputinggroup.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, version 2 of the
- * License.
- *
- * These difference are required on power because the device must be
- * discovered through the device tree and iomap must be used to get
- * around the need for holes in the io_page_mask. This does not happen
- * automatically because the tpm is not a normal pci device and lives
- * under the root node.
- *
- */
-
-#ifdef CONFIG_PPC64
-#define atmel_getb(chip, offset) readb(chip->vendor->iobase + offset);
-#define atmel_putb(val, chip, offset) writeb(val, chip->vendor->iobase + offset)
-#define atmel_request_region request_mem_region
-#define atmel_release_region release_mem_region
-static inline void atmel_put_base_addr(struct tpm_vendor_specific *vendor)
-{
- iounmap(vendor->iobase);
-}
-
-static int atmel_get_base_addr(struct tpm_vendor_specific *vendor)
-{
- struct device_node *dn;
- unsigned long address, size;
- unsigned int *reg;
- int reglen;
- int naddrc;
- int nsizec;
-
- dn = of_find_node_by_name(NULL, "tpm");
-
- if (!dn)
- return 1;
-
- if (!device_is_compatible(dn, "AT97SC3201")) {
- of_node_put(dn);
- return 1;
- }
-
- reg = (unsigned int *) get_property(dn, "reg", ®len);
- naddrc = prom_n_addr_cells(dn);
- nsizec = prom_n_size_cells(dn);
-
- of_node_put(dn);
-
-
- if (naddrc == 2)
- address = ((unsigned long) reg[0] << 32) | reg[1];
- else
- address = reg[0];
-
- if (nsizec == 2)
- size =
- ((unsigned long) reg[naddrc] << 32) | reg[naddrc + 1];
- else
- size = reg[naddrc];
-
- vendor->base = address;
- vendor->region_size = size;
- vendor->iobase = ioremap(address, size);
- return 0;
-}
-#else
-#define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
-#define atmel_putb(val, chip, offset) outb(val, chip->vendor->base + offset)
-#define atmel_request_region request_region
-#define atmel_release_region release_region
-/* Atmel definitions */
-enum tpm_atmel_addr {
- TPM_ATMEL_BASE_ADDR_LO = 0x08,
- TPM_ATMEL_BASE_ADDR_HI = 0x09
-};
-
-/* Verify this is a 1.1 Atmel TPM */
-static int atmel_verify_tpm11(void)
-{
-
- /* verify that it is an Atmel part */
- if (tpm_read_index(TPM_ADDR, 4) != 'A' ||
- tpm_read_index(TPM_ADDR, 5) != 'T' ||
- tpm_read_index(TPM_ADDR, 6) != 'M' ||
- tpm_read_index(TPM_ADDR, 7) != 'L')
- return 1;
-
- /* query chip for its version number */
- if (tpm_read_index(TPM_ADDR, 0x00) != 1 ||
- tpm_read_index(TPM_ADDR, 0x01) != 1)
- return 1;
-
- /* This is an atmel supported part */
- return 0;
-}
-
-static inline void atmel_put_base_addr(struct tpm_vendor_specific *vendor)
-{
-}
-
-/* Determine where to talk to device */
-static unsigned long atmel_get_base_addr(struct tpm_vendor_specific
- *vendor)
-{
- int lo, hi;
-
- if (atmel_verify_tpm11() != 0)
- return 1;
-
- lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
- hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
-
- vendor->base = (hi << 8) | lo;
- vendor->region_size = 2;
-
- return 0;
-}
-#endif
diff --git a/trunk/drivers/char/watchdog/booke_wdt.c b/trunk/drivers/char/watchdog/booke_wdt.c
index 65830ec71042..abc30cca6645 100644
--- a/trunk/drivers/char/watchdog/booke_wdt.c
+++ b/trunk/drivers/char/watchdog/booke_wdt.c
@@ -4,7 +4,7 @@
* Watchdog timer for PowerPC Book-E systems
*
* Author: Matthew McClintock
- * Maintainer: Kumar Gala
+ * Maintainer: Kumar Gala
*
* Copyright 2005 Freescale Semiconductor Inc.
*
diff --git a/trunk/drivers/ide/ppc/pmac.c b/trunk/drivers/ide/ppc/pmac.c
index 136911a86e84..b3e65a65d202 100644
--- a/trunk/drivers/ide/ppc/pmac.c
+++ b/trunk/drivers/ide/ppc/pmac.c
@@ -1667,16 +1667,11 @@ static struct macio_driver pmac_ide_macio_driver =
};
static struct pci_device_id pmac_ide_pci_match[] = {
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
};
static struct pci_driver pmac_ide_pci_driver = {
diff --git a/trunk/drivers/media/common/ir-common.c b/trunk/drivers/media/common/ir-common.c
index 7972c73bc14e..4b71fd6f7aed 100644
--- a/trunk/drivers/media/common/ir-common.c
+++ b/trunk/drivers/media/common/ir-common.c
@@ -126,66 +126,6 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_winfast);
-IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
- [ 0x59 ] = KEY_MUTE,
- [ 0x4a ] = KEY_POWER,
-
- [ 0x18 ] = KEY_TEXT,
- [ 0x26 ] = KEY_TV,
- [ 0x3d ] = KEY_PRINT,
-
- [ 0x48 ] = KEY_RED,
- [ 0x04 ] = KEY_GREEN,
- [ 0x11 ] = KEY_YELLOW,
- [ 0x00 ] = KEY_BLUE,
-
- [ 0x2d ] = KEY_VOLUMEUP,
- [ 0x1e ] = KEY_VOLUMEDOWN,
-
- [ 0x49 ] = KEY_MENU,
-
- [ 0x16 ] = KEY_CHANNELUP,
- [ 0x17 ] = KEY_CHANNELDOWN,
-
- [ 0x20 ] = KEY_UP,
- [ 0x21 ] = KEY_DOWN,
- [ 0x22 ] = KEY_LEFT,
- [ 0x23 ] = KEY_RIGHT,
- [ 0x0d ] = KEY_SELECT,
-
-
-
- [ 0x08 ] = KEY_BACK,
- [ 0x07 ] = KEY_REFRESH,
-
- [ 0x2f ] = KEY_ZOOM,
- [ 0x29 ] = KEY_RECORD,
-
- [ 0x4b ] = KEY_PAUSE,
- [ 0x4d ] = KEY_REWIND,
- [ 0x2e ] = KEY_PLAY,
- [ 0x4e ] = KEY_FORWARD,
- [ 0x53 ] = KEY_PREVIOUS,
- [ 0x4c ] = KEY_STOP,
- [ 0x54 ] = KEY_NEXT,
-
- [ 0x69 ] = KEY_KP0,
- [ 0x6a ] = KEY_KP1,
- [ 0x6b ] = KEY_KP2,
- [ 0x6c ] = KEY_KP3,
- [ 0x6d ] = KEY_KP4,
- [ 0x6e ] = KEY_KP5,
- [ 0x6f ] = KEY_KP6,
- [ 0x70 ] = KEY_KP7,
- [ 0x71 ] = KEY_KP8,
- [ 0x72 ] = KEY_KP9,
-
- [ 0x74 ] = KEY_CHANNEL,
- [ 0x0a ] = KEY_BACKSPACE,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_pinnacle);
-
/* empty keytable, can be used as placeholder for not-yet created keytables */
IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
[ 42 ] = KEY_COFFEE,
diff --git a/trunk/drivers/media/dvb/b2c2/Kconfig b/trunk/drivers/media/dvb/b2c2/Kconfig
index 2583a865a58e..d7417eac2aba 100644
--- a/trunk/drivers/media/dvb/b2c2/Kconfig
+++ b/trunk/drivers/media/dvb/b2c2/Kconfig
@@ -7,7 +7,6 @@ config DVB_B2C2_FLEXCOP
select DVB_NXT2002
select DVB_STV0297
select DVB_BCM3510
- select DVB_LGDT330X
help
Support for the digital TV receiver chip made by B2C2 Inc. included in
Technisats PCI cards and USB boxes.
diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig
index 1a3b3c7e5e99..199b01188858 100644
--- a/trunk/drivers/media/video/Kconfig
+++ b/trunk/drivers/media/video/Kconfig
@@ -333,18 +333,4 @@ config VIDEO_M32R_AR_M64278
Say Y here to use the Renesas M64278E-800 camera module,
which supports VGA(640x480 pixcels) size of images.
-config VIDEO_AUDIO_DECODER
- tristate "Add support for additional audio chipsets"
- depends on VIDEO_DEV && I2C && EXPERIMENTAL
- ---help---
- Say Y here to compile drivers for WM8775 and CS53L32A audio
- decoders.
-
-config VIDEO_DECODER
- tristate "Add support for additional video chipsets"
- depends on VIDEO_DEV && I2C && EXPERIMENTAL
- ---help---
- Say Y here to compile drivers for SAA7115, SAA7127 and CX25840
- video decoders.
-
endmenu
diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile
index 82060f9909d8..3ac465992400 100644
--- a/trunk/drivers/media/video/Makefile
+++ b/trunk/drivers/media/video/Makefile
@@ -36,11 +36,10 @@ obj-$(CONFIG_VIDEO_CPIA) += cpia.o
obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
obj-$(CONFIG_VIDEO_MEYE) += meye.o
-obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/
+obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o
-obj-$(CONFIG_VIDEO_AUDIO_DECODER) += wm8775.o cs53l32a.o
obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
@@ -56,6 +55,4 @@ obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
-obj-$(CONFIG_VIDEO_DECODER) += saa7115.o cx25840/ saa7127.o
-
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
diff --git a/trunk/drivers/media/video/bttv-cards.c b/trunk/drivers/media/video/bttv-cards.c
index e31ebb11c468..3413bace443a 100644
--- a/trunk/drivers/media/video/bttv-cards.c
+++ b/trunk/drivers/media/video/bttv-cards.c
@@ -2133,10 +2133,7 @@ struct tvcard bttv_tvcards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.has_dvb = 1,
- .has_remote = 1,
- .gpiomask = 0x1b,
.no_gpioirq = 1,
- .any_irq = 1,
},
[BTTV_BOARD_PV143] = {
/* Jorge Boncompte - DTI2 */
@@ -2799,24 +2796,7 @@ struct tvcard bttv_tvcards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
},
- /* ---- card 0x8e ---------------------------------- */
- [BTTV_BOARD_SABRENT_TVFM] = {
- .name = "Sabrent TV-FM (bttv version)",
- .video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 2,
- .gpiomask = 0x108007,
- .muxsel = { 2, 3, 1, 1},
- .audiomux = { 100000, 100002, 100002, 100000},
- .no_msp34xx = 1,
- .no_tda9875 = 1,
- .no_tda7432 = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_TNF_5335MF,
- .tuner_addr = ADDR_UNSET,
- .has_radio = 1,
- },
+
};
static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3387,8 +3367,6 @@ void __devinit bttv_init_card2(struct bttv *btv)
btv->has_remote=1;
if (!bttv_tvcards[btv->c.type].no_gpioirq)
btv->gpioirq=1;
- if (bttv_tvcards[btv->c.type].any_irq)
- btv->any_irq = 1;
if (bttv_tvcards[btv->c.type].audio_hook)
btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
diff --git a/trunk/drivers/media/video/bttv-driver.c b/trunk/drivers/media/video/bttv-driver.c
index 709099f03bd2..0005741d5514 100644
--- a/trunk/drivers/media/video/bttv-driver.c
+++ b/trunk/drivers/media/video/bttv-driver.c
@@ -3667,10 +3667,6 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
int handled = 0;
btv=(struct bttv *)dev_id;
-
- if (btv->any_irq)
- handled = bttv_any_irq(&btv->c);
-
count=0;
while (1) {
/* get/clear interrupt status bits */
diff --git a/trunk/drivers/media/video/bttv-gpio.c b/trunk/drivers/media/video/bttv-gpio.c
index 616a5b7e510c..575ce8b8e714 100644
--- a/trunk/drivers/media/video/bttv-gpio.c
+++ b/trunk/drivers/media/video/bttv-gpio.c
@@ -113,24 +113,6 @@ void bttv_gpio_irq(struct bttv_core *core)
}
}
-int bttv_any_irq(struct bttv_core *core)
-{
- struct bttv_sub_driver *drv;
- struct bttv_sub_device *dev;
- struct list_head *item;
- int handled = 0;
-
- list_for_each(item,&core->subs) {
- dev = list_entry(item,struct bttv_sub_device,list);
- drv = to_bttv_sub_drv(dev->dev.driver);
- if (drv && drv->any_irq) {
- if (drv->any_irq(dev))
- handled = 1;
- }
- }
- return handled;
-}
-
/* ----------------------------------------------------------------------- */
/* external: sub-driver register/unregister */
diff --git a/trunk/drivers/media/video/bttv.h b/trunk/drivers/media/video/bttv.h
index 93298f06e019..124ea41dada4 100644
--- a/trunk/drivers/media/video/bttv.h
+++ b/trunk/drivers/media/video/bttv.h
@@ -162,7 +162,6 @@
#define BTTV_BOARD_PV_M4900 0x8b
#define BTTV_BOARD_OSPREY440 0x8c
#define BTTV_BOARD_ASOUND_SKYEYE 0x8d
-#define BTTV_BOARD_SABRENT_TVFM 0x8e
/* i2c address list */
#define I2C_TSA5522 0xc2
@@ -235,7 +234,6 @@ struct tvcard
unsigned int has_dvb:1;
unsigned int has_remote:1;
unsigned int no_gpioirq:1;
- unsigned int any_irq:1;
/* other settings */
unsigned int pll;
@@ -335,7 +333,6 @@ struct bttv_sub_driver {
struct device_driver drv;
char wanted[BUS_ID_SIZE];
void (*gpio_irq)(struct bttv_sub_device *sub);
- int (*any_irq)(struct bttv_sub_device *sub);
};
#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv)
diff --git a/trunk/drivers/media/video/bttvp.h b/trunk/drivers/media/video/bttvp.h
index 3aa9c6e4fc33..386f546f7d11 100644
--- a/trunk/drivers/media/video/bttvp.h
+++ b/trunk/drivers/media/video/bttvp.h
@@ -208,7 +208,6 @@ extern struct bus_type bttv_sub_bus_type;
int bttv_sub_add_device(struct bttv_core *core, char *name);
int bttv_sub_del_devices(struct bttv_core *core);
void bttv_gpio_irq(struct bttv_core *core);
-int bttv_any_irq(struct bttv_core *core);
/* ---------------------------------------------------------- */
@@ -274,7 +273,6 @@ struct bttv {
struct bttv_pll_info pll;
int triton1;
int gpioirq;
- int any_irq;
int use_i2c_hw;
/* old gpio interface */
diff --git a/trunk/drivers/media/video/cx25840/Makefile b/trunk/drivers/media/video/cx25840/Makefile
deleted file mode 100644
index 543ebacdc9d7..000000000000
--- a/trunk/drivers/media/video/cx25840/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-cx25840-objs := cx25840-core.o cx25840-audio.o cx25840-firmware.o \
- cx25840-vbi.o
-
-obj-$(CONFIG_VIDEO_DECODER) += cx25840.o
-
-EXTRA_CFLAGS += -I$(src)/..
diff --git a/trunk/drivers/media/video/cx25840/cx25840-audio.c b/trunk/drivers/media/video/cx25840/cx25840-audio.c
deleted file mode 100644
index 740908f8027d..000000000000
--- a/trunk/drivers/media/video/cx25840/cx25840-audio.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/* cx25840 audio functions
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-
-#include
-#include
-#include
-#include
-
-#include "cx25840.h"
-
-inline static int set_audclk_freq(struct i2c_client *client,
- enum v4l2_audio_clock_freq freq)
-{
- struct cx25840_state *state = i2c_get_clientdata(client);
-
- /* assert soft reset */
- cx25840_and_or(client, 0x810, ~0x1, 0x01);
-
- /* common for all inputs and rates */
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
- cx25840_write(client, 0x127, 0x50);
-
- switch (state->audio_input) {
- case AUDIO_TUNER:
- switch (freq) {
- case V4L2_AUDCLK_32_KHZ:
- /* VID_PLL and AUX_PLL */
- cx25840_write4(client, 0x108, 0x0f040610);
-
- /* AUX_PLL_FRAC */
- cx25840_write4(client, 0x110, 0xee39bb01);
-
- /* src3/4/6_ctl = 0x0801f77f */
- cx25840_write4(client, 0x900, 0x7ff70108);
- cx25840_write4(client, 0x904, 0x7ff70108);
- cx25840_write4(client, 0x90c, 0x7ff70108);
- break;
-
- case V4L2_AUDCLK_441_KHZ:
- /* VID_PLL and AUX_PLL */
- cx25840_write4(client, 0x108, 0x0f040910);
-
- /* AUX_PLL_FRAC */
- cx25840_write4(client, 0x110, 0xd66bec00);
-
- /* src3/4/6_ctl = 0x08016d59 */
- cx25840_write4(client, 0x900, 0x596d0108);
- cx25840_write4(client, 0x904, 0x596d0108);
- cx25840_write4(client, 0x90c, 0x596d0108);
- break;
-
- case V4L2_AUDCLK_48_KHZ:
- /* VID_PLL and AUX_PLL */
- cx25840_write4(client, 0x108, 0x0f040a10);
-
- /* AUX_PLL_FRAC */
- cx25840_write4(client, 0x110, 0xe5d69800);
-
- /* src3/4/6_ctl = 0x08014faa */
- cx25840_write4(client, 0x900, 0xaa4f0108);
- cx25840_write4(client, 0x904, 0xaa4f0108);
- cx25840_write4(client, 0x90c, 0xaa4f0108);
- break;
- }
- break;
-
- case AUDIO_EXTERN_1:
- case AUDIO_EXTERN_2:
- case AUDIO_INTERN:
- case AUDIO_RADIO:
- switch (freq) {
- case V4L2_AUDCLK_32_KHZ:
- /* VID_PLL and AUX_PLL */
- cx25840_write4(client, 0x108, 0x0f04081e);
-
- /* AUX_PLL_FRAC */
- cx25840_write4(client, 0x110, 0x69082a01);
-
- /* src1_ctl = 0x08010000 */
- cx25840_write4(client, 0x8f8, 0x00000108);
-
- /* src3/4/6_ctl = 0x08020000 */
- cx25840_write4(client, 0x900, 0x00000208);
- cx25840_write4(client, 0x904, 0x00000208);
- cx25840_write4(client, 0x90c, 0x00000208);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
- cx25840_write(client, 0x127, 0x54);
- break;
-
- case V4L2_AUDCLK_441_KHZ:
- /* VID_PLL and AUX_PLL */
- cx25840_write4(client, 0x108, 0x0f040918);
-
- /* AUX_PLL_FRAC */
- cx25840_write4(client, 0x110, 0xd66bec00);
-
- /* src1_ctl = 0x08010000 */
- cx25840_write4(client, 0x8f8, 0xcd600108);
-
- /* src3/4/6_ctl = 0x08020000 */
- cx25840_write4(client, 0x900, 0x85730108);
- cx25840_write4(client, 0x904, 0x85730108);
- cx25840_write4(client, 0x90c, 0x85730108);
- break;
-
- case V4L2_AUDCLK_48_KHZ:
- /* VID_PLL and AUX_PLL */
- cx25840_write4(client, 0x108, 0x0f040a18);
-
- /* AUX_PLL_FRAC */
- cx25840_write4(client, 0x110, 0xe5d69800);
-
- /* src1_ctl = 0x08010000 */
- cx25840_write4(client, 0x8f8, 0x00800108);
-
- /* src3/4/6_ctl = 0x08020000 */
- cx25840_write4(client, 0x900, 0x55550108);
- cx25840_write4(client, 0x904, 0x55550108);
- cx25840_write4(client, 0x90c, 0x55550108);
- break;
- }
- break;
- }
-
- /* deassert soft reset */
- cx25840_and_or(client, 0x810, ~0x1, 0x00);
-
- state->audclk_freq = freq;
-
- return 0;
-}
-
-static int set_input(struct i2c_client *client, int audio_input)
-{
- struct cx25840_state *state = i2c_get_clientdata(client);
-
- cx25840_dbg("set audio input (%d)\n", audio_input);
-
- /* stop microcontroller */
- cx25840_and_or(client, 0x803, ~0x10, 0);
-
- /* Mute everything to prevent the PFFT! */
- cx25840_write(client, 0x8d3, 0x1f);
-
- switch (audio_input) {
- case AUDIO_TUNER:
- /* Set Path1 to Analog Demod Main Channel */
- cx25840_write4(client, 0x8d0, 0x7038061f);
-
- /* When the microcontroller detects the
- * audio format, it will unmute the lines */
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
- break;
-
- case AUDIO_EXTERN_1:
- case AUDIO_EXTERN_2:
- case AUDIO_INTERN:
- case AUDIO_RADIO:
- /* Set Path1 to Serial Audio Input */
- cx25840_write4(client, 0x8d0, 0x12100101);
-
- /* The microcontroller should not be started for the
- * non-tuner inputs: autodetection is specific for
- * TV audio. */
- break;
-
- default:
- cx25840_dbg("Invalid audio input selection %d\n", audio_input);
- return -EINVAL;
- }
-
- state->audio_input = audio_input;
-
- return set_audclk_freq(client, state->audclk_freq);
-}
-
-inline static int get_volume(struct i2c_client *client)
-{
- /* 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 = (vol / 2) + 23;
- return vol << 9;
-}
-
-inline static void set_volume(struct i2c_client *client, int volume)
-{
- /* First convert the volume to msp3400 values (0-127) */
- int 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 */
- if (vol <= 23) {
- vol = 0;
- } else {
- vol -= 23;
- }
-
- /* PATH1_VOLUME */
- cx25840_write(client, 0x8d4, 228 - (vol * 2));
-}
-
-inline static int get_bass(struct i2c_client *client)
-{
- /* bass is 49 steps +12dB to -12dB */
-
- /* check PATH1_EQ_BASS_VOL */
- int bass = cx25840_read(client, 0x8d9) & 0x3f;
- bass = (((48 - bass) * 0xffff) + 47) / 48;
- return bass;
-}
-
-inline static void set_bass(struct i2c_client *client, int bass)
-{
- /* PATH1_EQ_BASS_VOL */
- cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
-}
-
-inline static int get_treble(struct i2c_client *client)
-{
- /* treble is 49 steps +12dB to -12dB */
-
- /* check PATH1_EQ_TREBLE_VOL */
- int treble = cx25840_read(client, 0x8db) & 0x3f;
- treble = (((48 - treble) * 0xffff) + 47) / 48;
- return treble;
-}
-
-inline static void set_treble(struct i2c_client *client, int treble)
-{
- /* PATH1_EQ_TREBLE_VOL */
- cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
-}
-
-inline static int get_balance(struct i2c_client *client)
-{
- /* balance is 7 bit, 0 to -96dB */
-
- /* check PATH1_BAL_LEVEL */
- int balance = cx25840_read(client, 0x8d5) & 0x7f;
- /* check PATH1_BAL_LEFT */
- if ((cx25840_read(client, 0x8d5) & 0x80) == 0)
- balance = 0x80 - balance;
- else
- balance = 0x80 + balance;
- return balance << 8;
-}
-
-inline static void set_balance(struct i2c_client *client, int balance)
-{
- int bal = balance >> 8;
- if (bal > 0x80) {
- /* PATH1_BAL_LEFT */
- cx25840_and_or(client, 0x8d5, 0x7f, 0x80);
- /* PATH1_BAL_LEVEL */
- cx25840_and_or(client, 0x8d5, ~0x7f, bal & 0x7f);
- } else {
- /* PATH1_BAL_LEFT */
- cx25840_and_or(client, 0x8d5, 0x7f, 0x00);
- /* PATH1_BAL_LEVEL */
- cx25840_and_or(client, 0x8d5, ~0x7f, 0x80 - bal);
- }
-}
-
-inline static int get_mute(struct i2c_client *client)
-{
- /* check SRC1_MUTE_EN */
- return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0;
-}
-
-inline static void set_mute(struct i2c_client *client, int mute)
-{
- struct cx25840_state *state = i2c_get_clientdata(client);
-
- if (state->audio_input == AUDIO_TUNER) {
- /* 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);
- }
-}
-
-int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- struct v4l2_control *ctrl = arg;
-
- switch (cmd) {
- case AUDC_SET_INPUT:
- return set_input(client, *(int *)arg);
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- return set_audclk_freq(client, *(enum v4l2_audio_clock_freq *)arg);
- case VIDIOC_G_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = get_volume(client);
- break;
- case V4L2_CID_AUDIO_BASS:
- ctrl->value = get_bass(client);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- ctrl->value = get_treble(client);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- ctrl->value = get_balance(client);
- break;
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value = get_mute(client);
- break;
- default:
- return -EINVAL;
- }
- break;
- case VIDIOC_S_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- set_volume(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BASS:
- set_bass(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- set_treble(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- set_balance(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_MUTE:
- set_mute(client, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
diff --git a/trunk/drivers/media/video/cx25840/cx25840-core.c b/trunk/drivers/media/video/cx25840/cx25840-core.c
deleted file mode 100644
index f6afeec499c5..000000000000
--- a/trunk/drivers/media/video/cx25840/cx25840-core.c
+++ /dev/null
@@ -1,1020 +0,0 @@
-/* cx25840 - Conexant CX25840 audio/video decoder driver
- *
- * Copyright (C) 2004 Ulf Eklund
- *
- * Based on the saa7115 driver and on the first verison of Chris Kennedy's
- * cx25840 driver.
- *
- * Changes by Tyler Trafford
- * - cleanup/rewrite for V4L2 API (2005)
- *
- * VBI support by Hans Verkuil .
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "cx25840.h"
-
-MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver");
-MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford");
-MODULE_LICENSE("GPL");
-
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-
-
-int cx25840_debug = 0;
-
-module_param(cx25840_debug, bool, 0644);
-
-MODULE_PARM_DESC(cx25840_debug, "Debugging messages [0=Off (default) 1=On]");
-
-I2C_CLIENT_INSMOD;
-
-/* ----------------------------------------------------------------------- */
-
-int cx25840_write(struct i2c_client *client, u16 addr, u8 value)
-{
- u8 buffer[3];
- buffer[0] = addr >> 8;
- buffer[1] = addr & 0xff;
- buffer[2] = value;
- return i2c_master_send(client, buffer, 3);
-}
-
-int cx25840_write4(struct i2c_client *client, u16 addr, u32 value)
-{
- u8 buffer[6];
- buffer[0] = addr >> 8;
- buffer[1] = addr & 0xff;
- buffer[2] = value >> 24;
- buffer[3] = (value >> 16) & 0xff;
- buffer[4] = (value >> 8) & 0xff;
- buffer[5] = value & 0xff;
- return i2c_master_send(client, buffer, 6);
-}
-
-u8 cx25840_read(struct i2c_client * client, u16 addr)
-{
- u8 buffer[2];
- buffer[0] = addr >> 8;
- buffer[1] = addr & 0xff;
-
- if (i2c_master_send(client, buffer, 2) < 2)
- return 0;
-
- if (i2c_master_recv(client, buffer, 1) < 1)
- return 0;
-
- return buffer[0];
-}
-
-u32 cx25840_read4(struct i2c_client * client, u16 addr)
-{
- u8 buffer[4];
- buffer[0] = addr >> 8;
- buffer[1] = addr & 0xff;
-
- if (i2c_master_send(client, buffer, 2) < 2)
- return 0;
-
- if (i2c_master_recv(client, buffer, 4) < 4)
- return 0;
-
- return (buffer[0] << 24) | (buffer[1] << 16) |
- (buffer[2] << 8) | buffer[3];
-}
-
-int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask,
- u8 or_value)
-{
- return cx25840_write(client, addr,
- (cx25840_read(client, addr) & and_mask) |
- or_value);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int set_input(struct i2c_client *, enum cx25840_input);
-static void input_change(struct i2c_client *);
-static void log_status(struct i2c_client *client);
-
-/* ----------------------------------------------------------------------- */
-
-static inline void init_dll1(struct i2c_client *client)
-{
- /* This is the Hauppauge sequence used to
- * initialize the Delay Lock Loop 1 (ADC DLL). */
- cx25840_write(client, 0x159, 0x23);
- cx25840_write(client, 0x15a, 0x87);
- cx25840_write(client, 0x15b, 0x06);
- cx25840_write(client, 0x159, 0xe1);
- cx25840_write(client, 0x15a, 0x86);
- cx25840_write(client, 0x159, 0xe0);
- cx25840_write(client, 0x159, 0xe1);
- cx25840_write(client, 0x15b, 0x10);
-}
-
-static inline void init_dll2(struct i2c_client *client)
-{
- /* This is the Hauppauge sequence used to
- * initialize the Delay Lock Loop 2 (ADC DLL). */
- cx25840_write(client, 0x15d, 0xe3);
- cx25840_write(client, 0x15e, 0x86);
- cx25840_write(client, 0x15f, 0x06);
- cx25840_write(client, 0x15d, 0xe1);
- cx25840_write(client, 0x15d, 0xe0);
- cx25840_write(client, 0x15d, 0xe1);
-}
-
-static void cx25840_initialize(struct i2c_client *client, int loadfw)
-{
- struct cx25840_state *state = i2c_get_clientdata(client);
-
- /* datasheet startup in numbered steps, refer to page 3-77 */
- /* 2. */
- cx25840_and_or(client, 0x803, ~0x10, 0x00);
- /* The default of this register should be 4, but I get 0 instead.
- * Set this register to 4 manually. */
- cx25840_write(client, 0x000, 0x04);
- /* 3. */
- init_dll1(client);
- init_dll2(client);
- cx25840_write(client, 0x136, 0x0a);
- /* 4. */
- cx25840_write(client, 0x13c, 0x01);
- cx25840_write(client, 0x13c, 0x00);
- /* 5. */
- if (loadfw)
- cx25840_loadfw(client);
- /* 6. */
- cx25840_write(client, 0x115, 0x8c);
- cx25840_write(client, 0x116, 0x07);
- cx25840_write(client, 0x118, 0x02);
- /* 7. */
- cx25840_write(client, 0x4a5, 0x80);
- cx25840_write(client, 0x4a5, 0x00);
- cx25840_write(client, 0x402, 0x00);
- /* 8. */
- cx25840_write(client, 0x401, 0x18);
- cx25840_write(client, 0x4a2, 0x10);
- cx25840_write(client, 0x402, 0x04);
- /* 10. */
- cx25840_write(client, 0x8d3, 0x1f);
- cx25840_write(client, 0x8e3, 0x03);
-
- cx25840_vbi_setup(client);
-
- /* trial and error says these are needed to get audio */
- cx25840_write(client, 0x914, 0xa0);
- cx25840_write(client, 0x918, 0xa0);
- cx25840_write(client, 0x919, 0x01);
-
- /* stereo prefered */
- cx25840_write(client, 0x809, 0x04);
- /* AC97 shift */
- cx25840_write(client, 0x8cf, 0x0f);
-
- /* (re)set video input */
- set_input(client, state->input);
- /* (re)set audio input */
- cx25840_audio(client, AUDC_SET_INPUT, &state->audio_input);
-
- /* start microcontroller */
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void input_change(struct i2c_client *client)
-{
- v4l2_std_id std = cx25840_get_v4lstd(client);
-
- if (std & V4L2_STD_PAL) {
- /* Follow tuner change procedure for PAL */
- cx25840_write(client, 0x808, 0xff);
- cx25840_write(client, 0x80b, 0x10);
- } else if (std & V4L2_STD_SECAM) {
- /* Select autodetect for SECAM */
- cx25840_write(client, 0x808, 0xff);
- cx25840_write(client, 0x80b, 0x10);
- } else if (std & V4L2_STD_NTSC) {
- /* NTSC */
- cx25840_write(client, 0x808, 0xf6);
- cx25840_write(client, 0x80b, 0x00);
- }
-
- if (cx25840_read(client, 0x803) & 0x10) {
- /* restart audio decoder microcontroller */
- cx25840_and_or(client, 0x803, ~0x10, 0x00);
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
- }
-}
-
-static int set_input(struct i2c_client *client, enum cx25840_input input)
-{
- struct cx25840_state *state = i2c_get_clientdata(client);
-
- cx25840_dbg("decoder set input (%d)\n", input);
-
- switch (input) {
- case CX25840_TUNER:
- cx25840_dbg("now setting Tuner input\n");
-
- if (state->cardtype == CARDTYPE_PVR150) {
- /* CH_SEL_ADC2=1 */
- cx25840_and_or(client, 0x102, ~0x2, 0x02);
- }
-
- /* Video Input Control */
- if (state->cardtype == CARDTYPE_PG600) {
- cx25840_write(client, 0x103, 0x11);
- } else {
- cx25840_write(client, 0x103, 0x46);
- }
-
- /* INPUT_MODE=0 */
- cx25840_and_or(client, 0x401, ~0x6, 0x00);
- break;
-
- case CX25840_COMPOSITE0:
- case CX25840_COMPOSITE1:
- cx25840_dbg("now setting Composite input\n");
-
- /* Video Input Control */
- if (state->cardtype == CARDTYPE_PG600) {
- cx25840_write(client, 0x103, 0x00);
- } else {
- cx25840_write(client, 0x103, 0x02);
- }
-
- /* INPUT_MODE=0 */
- cx25840_and_or(client, 0x401, ~0x6, 0x00);
- break;
-
- case CX25840_SVIDEO0:
- case CX25840_SVIDEO1:
- cx25840_dbg("now setting S-Video input\n");
-
- /* CH_SEL_ADC2=0 */
- cx25840_and_or(client, 0x102, ~0x2, 0x00);
-
- /* Video Input Control */
- if (state->cardtype == CARDTYPE_PG600) {
- cx25840_write(client, 0x103, 0x02);
- } else {
- cx25840_write(client, 0x103, 0x10);
- }
-
- /* INPUT_MODE=1 */
- cx25840_and_or(client, 0x401, ~0x6, 0x02);
- break;
-
- default:
- cx25840_err("%d is not a valid input!\n", input);
- return -EINVAL;
- }
-
- state->input = input;
- input_change(client);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
-{
- u8 fmt;
-
- switch (std) {
- /* zero is autodetect */
- case 0: fmt = 0x0; break;
- /* default ntsc to ntsc-m */
- case V4L2_STD_NTSC:
- case V4L2_STD_NTSC_M: fmt = 0x1; break;
- case V4L2_STD_NTSC_M_JP: fmt = 0x2; break;
- case V4L2_STD_NTSC_443: fmt = 0x3; break;
- case V4L2_STD_PAL: fmt = 0x4; break;
- case V4L2_STD_PAL_M: fmt = 0x5; break;
- case V4L2_STD_PAL_N: fmt = 0x6; break;
- case V4L2_STD_PAL_Nc: fmt = 0x7; break;
- case V4L2_STD_PAL_60: fmt = 0x8; break;
- case V4L2_STD_SECAM: fmt = 0xc; break;
- default:
- return -ERANGE;
- }
-
- cx25840_and_or(client, 0x400, ~0xf, fmt);
- cx25840_vbi_setup(client);
- return 0;
-}
-
-v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
-{
- /* check VID_FMT_SEL first */
- u8 fmt = cx25840_read(client, 0x400) & 0xf;
-
- if (!fmt) {
- /* check AFD_FMT_STAT if set to autodetect */
- fmt = cx25840_read(client, 0x40d) & 0xf;
- }
-
- switch (fmt) {
- case 0x1: return V4L2_STD_NTSC_M;
- case 0x2: return V4L2_STD_NTSC_M_JP;
- case 0x3: return V4L2_STD_NTSC_443;
- case 0x4: return V4L2_STD_PAL;
- case 0x5: return V4L2_STD_PAL_M;
- case 0x6: return V4L2_STD_PAL_N;
- case 0x7: return V4L2_STD_PAL_Nc;
- case 0x8: return V4L2_STD_PAL_60;
- case 0xc: return V4L2_STD_SECAM;
- default: return V4L2_STD_UNKNOWN;
- }
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
-{
- struct cx25840_state *state = i2c_get_clientdata(client);
-
- switch (ctrl->id) {
- case CX25840_CID_CARDTYPE:
- switch (ctrl->value) {
- case CARDTYPE_PVR150:
- case CARDTYPE_PG600:
- state->cardtype = ctrl->value;
- break;
- default:
- return -ERANGE;
- }
-
- set_input(client, state->input);
- break;
-
- case V4L2_CID_BRIGHTNESS:
- if (ctrl->value < 0 || ctrl->value > 255) {
- cx25840_err("invalid brightness setting %d\n",
- ctrl->value);
- return -ERANGE;
- }
-
- cx25840_write(client, 0x414, ctrl->value - 128);
- break;
-
- case V4L2_CID_CONTRAST:
- if (ctrl->value < 0 || ctrl->value > 127) {
- cx25840_err("invalid contrast setting %d\n",
- ctrl->value);
- return -ERANGE;
- }
-
- cx25840_write(client, 0x415, ctrl->value << 1);
- break;
-
- case V4L2_CID_SATURATION:
- if (ctrl->value < 0 || ctrl->value > 127) {
- cx25840_err("invalid saturation setting %d\n",
- ctrl->value);
- return -ERANGE;
- }
-
- cx25840_write(client, 0x420, ctrl->value << 1);
- cx25840_write(client, 0x421, ctrl->value << 1);
- break;
-
- case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
- cx25840_err("invalid hue setting %d\n", ctrl->value);
- return -ERANGE;
- }
-
- cx25840_write(client, 0x422, ctrl->value);
- break;
-
- case V4L2_CID_AUDIO_VOLUME:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_MUTE:
- return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
- }
-
- return 0;
-}
-
-static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
-{
- struct cx25840_state *state = i2c_get_clientdata(client);
-
- switch (ctrl->id) {
- case CX25840_CID_CARDTYPE:
- ctrl->value = state->cardtype;
- break;
- case V4L2_CID_BRIGHTNESS:
- ctrl->value = cx25840_read(client, 0x414) + 128;
- break;
- case V4L2_CID_CONTRAST:
- ctrl->value = cx25840_read(client, 0x415) >> 1;
- break;
- case V4L2_CID_SATURATION:
- ctrl->value = cx25840_read(client, 0x420) >> 1;
- break;
- case V4L2_CID_HUE:
- ctrl->value = cx25840_read(client, 0x422);
- break;
- case V4L2_CID_AUDIO_VOLUME:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_MUTE:
- return cx25840_audio(client, VIDIOC_G_CTRL, ctrl);
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
-{
- switch (fmt->type) {
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_G_FMT, fmt);
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
-{
- struct v4l2_pix_format *pix;
- int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
- int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
-
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- pix = &(fmt->fmt.pix);
-
- Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4;
- Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4;
-
- Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
- Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
-
- Vlines = pix->height + (is_pal ? 4 : 7);
-
- if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
- (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
- cx25840_err("%dx%d is not a valid size!\n",
- pix->width, pix->height);
- return -ERANGE;
- }
-
- HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
- VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
- VSC &= 0x1fff;
-
- if (pix->width >= 385)
- filter = 0;
- else if (pix->width > 192)
- filter = 1;
- else if (pix->width > 96)
- filter = 2;
- else
- filter = 3;
-
- cx25840_dbg("decoder set size %dx%d -> scale %ux%u\n",
- pix->width, pix->height, HSC, VSC);
-
- /* HSCALE=HSC */
- cx25840_write(client, 0x418, HSC & 0xff);
- cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
- cx25840_write(client, 0x41a, HSC >> 16);
- /* VSCALE=VSC */
- cx25840_write(client, 0x41c, VSC & 0xff);
- cx25840_write(client, 0x41d, VSC >> 8);
- /* VS_INTRLACE=1 VFILT=filter */
- cx25840_write(client, 0x41e, 0x8 | filter);
- break;
-
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
-
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int cx25840_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
-{
- struct cx25840_state *state = i2c_get_clientdata(client);
- struct v4l2_tuner *vt = arg;
- int result = 0;
-
- switch (cmd) {
- case 0:
- break;
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- /* ioctls to allow direct access to the
- * cx25840 registers for testing */
- case VIDIOC_INT_G_REGISTER:
- {
- struct v4l2_register *reg = arg;
-
- if (reg->i2c_id != I2C_DRIVERID_CX25840)
- return -EINVAL;
- reg->val = cx25840_read(client, reg->reg & 0x0fff);
- break;
- }
-
- case VIDIOC_INT_S_REGISTER:
- {
- struct v4l2_register *reg = arg;
-
- if (reg->i2c_id != I2C_DRIVERID_CX25840)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
- break;
- }
-#endif
-
- case VIDIOC_INT_DECODE_VBI_LINE:
- return cx25840_vbi(client, cmd, arg);
-
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- case AUDC_SET_INPUT:
- result = cx25840_audio(client, cmd, arg);
- break;
-
- case VIDIOC_STREAMON:
- cx25840_dbg("enable output\n");
- cx25840_write(client, 0x115, 0x8c);
- cx25840_write(client, 0x116, 0x07);
- break;
-
- case VIDIOC_STREAMOFF:
- cx25840_dbg("disable output\n");
- cx25840_write(client, 0x115, 0x00);
- cx25840_write(client, 0x116, 0x00);
- break;
-
- case VIDIOC_LOG_STATUS:
- log_status(client);
- break;
-
- case VIDIOC_G_CTRL:
- result = get_v4lctrl(client, (struct v4l2_control *)arg);
- break;
-
- case VIDIOC_S_CTRL:
- result = set_v4lctrl(client, (struct v4l2_control *)arg);
- break;
-
- case VIDIOC_G_STD:
- *(v4l2_std_id *)arg = cx25840_get_v4lstd(client);
- break;
-
- case VIDIOC_S_STD:
- result = set_v4lstd(client, *(v4l2_std_id *)arg);
- break;
-
- case VIDIOC_G_INPUT:
- *(int *)arg = state->input;
- break;
-
- case VIDIOC_S_INPUT:
- result = set_input(client, *(int *)arg);
- break;
-
- case VIDIOC_S_FREQUENCY:
- input_change(client);
- break;
-
- case VIDIOC_G_TUNER:
- {
- u8 mode = cx25840_read(client, 0x804);
- u8 pref = cx25840_read(client, 0x809) & 0xf;
- u8 vpres = cx25840_read(client, 0x80a) & 0x10;
- int val = 0;
-
- vt->capability |=
- V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
- V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-
- vt->signal = vpres ? 0xffff : 0x0;
-
- /* get rxsubchans and audmode */
- if ((mode & 0xf) == 1)
- val |= V4L2_TUNER_SUB_STEREO;
- else
- val |= V4L2_TUNER_SUB_MONO;
-
- if (mode == 2 || mode == 4)
- val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-
- if (mode & 0x10)
- val |= V4L2_TUNER_SUB_SAP;
-
- vt->rxsubchans = val;
-
- switch (pref) {
- case 0:
- vt->audmode = V4L2_TUNER_MODE_MONO;
- break;
- case 1:
- case 2:
- vt->audmode = V4L2_TUNER_MODE_LANG2;
- break;
- case 4:
- default:
- vt->audmode = V4L2_TUNER_MODE_STEREO;
- }
- break;
- }
-
- case VIDIOC_S_TUNER:
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_MONO:
- case V4L2_TUNER_MODE_LANG1:
- /* Force PREF_MODE to MONO */
- cx25840_and_or(client, 0x809, ~0xf, 0x00);
- break;
- case V4L2_TUNER_MODE_STEREO:
- /* Force PREF_MODE to STEREO */
- cx25840_and_or(client, 0x809, ~0xf, 0x04);
- break;
- case V4L2_TUNER_MODE_LANG2:
- /* Force PREF_MODE to LANG2 */
- cx25840_and_or(client, 0x809, ~0xf, 0x01);
- break;
- }
- break;
-
- case VIDIOC_G_FMT:
- result = get_v4lfmt(client, (struct v4l2_format *)arg);
- break;
-
- case VIDIOC_S_FMT:
- result = set_v4lfmt(client, (struct v4l2_format *)arg);
- break;
-
- case VIDIOC_INT_RESET:
- cx25840_initialize(client, 0);
- break;
-
- case VIDIOC_INT_G_CHIP_IDENT:
- *(enum v4l2_chip_ident *)arg =
- V4L2_IDENT_CX25840 + ((cx25840_read(client, 0x100) >> 4) & 0xf);
- break;
-
- default:
- cx25840_err("invalid ioctl %x\n", cmd);
- return -EINVAL;
- }
-
- return result;
-}
-
-/* ----------------------------------------------------------------------- */
-
-struct i2c_driver i2c_driver_cx25840;
-
-static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
- int kind)
-{
- struct i2c_client *client;
- struct cx25840_state *state;
- u16 device_id;
-
- /* Check if the adapter supports the needed features
- * Not until kernel version 2.6.11 did the bit-algo
- * correctly report that it would do an I2C-level xfer */
- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
- return 0;
-
- client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (client == 0)
- return -ENOMEM;
-
- memset(client, 0, sizeof(struct i2c_client));
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_cx25840;
- client->flags = I2C_CLIENT_ALLOW_USE;
- snprintf(client->name, sizeof(client->name) - 1, "cx25840");
-
- cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1);
-
- device_id = cx25840_read(client, 0x101) << 8;
- device_id |= cx25840_read(client, 0x100);
-
- /* The high byte of the device ID should be
- * 0x84 if chip is present */
- if ((device_id & 0xff00) != 0x8400) {
- cx25840_dbg("cx25840 not found\n");
- kfree(client);
- return 0;
- }
-
- cx25840_info("cx25%3x-2%x found @ 0x%x (%s)\n",
- (device_id & 0xfff0) >> 4,
- (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3,
- address << 1, adapter->name);
-
- state = kmalloc(sizeof(struct cx25840_state), GFP_KERNEL);
- if (state == NULL) {
- kfree(client);
- return -ENOMEM;
- }
-
- i2c_set_clientdata(client, state);
- memset(state, 0, sizeof(struct cx25840_state));
- state->input = CX25840_TUNER;
- state->audclk_freq = V4L2_AUDCLK_48_KHZ;
- state->audio_input = AUDIO_TUNER;
- state->cardtype = CARDTYPE_PVR150;
-
- cx25840_initialize(client, 1);
-
- i2c_attach_client(client);
-
- return 0;
-}
-
-static int cx25840_attach_adapter(struct i2c_adapter *adapter)
-{
-#ifdef I2C_CLASS_TV_ANALOG
- if (adapter->class & I2C_CLASS_TV_ANALOG)
-#else
- if (adapter->id == I2C_HW_B_BT848)
-#endif
- return i2c_probe(adapter, &addr_data, &cx25840_detect_client);
- return 0;
-}
-
-static int cx25840_detach_client(struct i2c_client *client)
-{
- struct cx25840_state *state = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(state);
- kfree(client);
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-struct i2c_driver i2c_driver_cx25840 = {
- .name = "cx25840",
-
- .id = I2C_DRIVERID_CX25840,
- .flags = I2C_DF_NOTIFY,
-
- .attach_adapter = cx25840_attach_adapter,
- .detach_client = cx25840_detach_client,
- .command = cx25840_command,
- .owner = THIS_MODULE,
-};
-
-
-static int __init m__init(void)
-{
- return i2c_add_driver(&i2c_driver_cx25840);
-}
-
-static void __exit m__exit(void)
-{
- i2c_del_driver(&i2c_driver_cx25840);
-}
-
-module_init(m__init);
-module_exit(m__exit);
-
-/* ----------------------------------------------------------------------- */
-
-static void log_status(struct i2c_client *client)
-{
- static const char *const fmt_strs[] = {
- "0x0",
- "NTSC-M", "NTSC-J", "NTSC-4.43",
- "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
- "0x9", "0xA", "0xB",
- "SECAM",
- "0xD", "0xE", "0xF"
- };
-
- struct cx25840_state *state = i2c_get_clientdata(client);
- u8 microctrl_vidfmt = cx25840_read(client, 0x80a);
- u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;
- u8 gen_stat1 = cx25840_read(client, 0x40d);
- u8 download_ctl = cx25840_read(client, 0x803);
- u8 mod_det_stat0 = cx25840_read(client, 0x804);
- u8 mod_det_stat1 = cx25840_read(client, 0x805);
- u8 audio_config = cx25840_read(client, 0x808);
- u8 pref_mode = cx25840_read(client, 0x809);
- u8 afc0 = cx25840_read(client, 0x80b);
- u8 mute_ctl = cx25840_read(client, 0x8d3);
- char *p;
-
- cx25840_info("Video signal: %spresent\n",
- (microctrl_vidfmt & 0x10) ? "" : "not ");
- cx25840_info("Detected format: %s\n",
- fmt_strs[gen_stat1 & 0xf]);
-
- switch (mod_det_stat0) {
- case 0x00: p = "mono"; break;
- case 0x01: p = "stereo"; break;
- case 0x02: p = "dual"; break;
- case 0x04: p = "tri"; break;
- case 0x10: p = "mono with SAP"; break;
- case 0x11: p = "stereo with SAP"; break;
- case 0x12: p = "dual with SAP"; break;
- case 0x14: p = "tri with SAP"; break;
- case 0xfe: p = "forced mode"; break;
- default: p = "not defined";
- }
- cx25840_info("Detected audio mode: %s\n", p);
-
- switch (mod_det_stat1) {
- case 0x00: p = "not defined"; break;
- case 0x01: p = "EIAJ"; break;
- case 0x02: p = "A2-M"; break;
- case 0x03: p = "A2-BG"; break;
- case 0x04: p = "A2-DK1"; break;
- case 0x05: p = "A2-DK2"; break;
- case 0x06: p = "A2-DK3"; break;
- case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
- case 0x08: p = "AM-L"; break;
- case 0x09: p = "NICAM-BG"; break;
- case 0x0a: p = "NICAM-DK"; break;
- case 0x0b: p = "NICAM-I"; break;
- case 0x0c: p = "NICAM-L"; break;
- case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
- case 0x0e: p = "IF FM Radio"; break;
- case 0x0f: p = "BTSC"; break;
- case 0x10: p = "high-deviation FM"; break;
- case 0x11: p = "very high-deviation FM"; break;
- case 0xfd: p = "unknown audio standard"; break;
- case 0xfe: p = "forced audio standard"; break;
- case 0xff: p = "no detected audio standard"; break;
- default: p = "not defined";
- }
- cx25840_info("Detected audio standard: %s\n", p);
- cx25840_info("Audio muted: %s\n",
- (mute_ctl & 0x2) ? "yes" : "no");
- cx25840_info("Audio microcontroller: %s\n",
- (download_ctl & 0x10) ? "running" : "stopped");
-
- switch (audio_config >> 4) {
- case 0x00: p = "undefined"; break;
- case 0x01: p = "BTSC"; break;
- case 0x02: p = "EIAJ"; break;
- case 0x03: p = "A2-M"; break;
- case 0x04: p = "A2-BG"; break;
- case 0x05: p = "A2-DK1"; break;
- case 0x06: p = "A2-DK2"; break;
- case 0x07: p = "A2-DK3"; break;
- case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
- case 0x09: p = "AM-L"; break;
- case 0x0a: p = "NICAM-BG"; break;
- case 0x0b: p = "NICAM-DK"; break;
- case 0x0c: p = "NICAM-I"; break;
- case 0x0d: p = "NICAM-L"; break;
- case 0x0e: p = "FM radio"; break;
- case 0x0f: p = "automatic detection"; break;
- default: p = "undefined";
- }
- cx25840_info("Configured audio standard: %s\n", p);
-
- if ((audio_config >> 4) < 0xF) {
- switch (audio_config & 0xF) {
- case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
- case 0x01: p = "MONO2 (LANGUAGE B)"; break;
- case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
- case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
- case 0x04: p = "STEREO"; break;
- case 0x05: p = "DUAL1 (AB)"; break;
- case 0x06: p = "DUAL2 (AC) (FM)"; break;
- case 0x07: p = "DUAL3 (BC) (FM)"; break;
- case 0x08: p = "DUAL4 (AC) (AM)"; break;
- case 0x09: p = "DUAL5 (BC) (AM)"; break;
- case 0x0a: p = "SAP"; break;
- default: p = "undefined";
- }
- cx25840_info("Configured audio mode: %s\n", p);
- } else {
- switch (audio_config & 0xF) {
- case 0x00: p = "BG"; break;
- case 0x01: p = "DK1"; break;
- case 0x02: p = "DK2"; break;
- case 0x03: p = "DK3"; break;
- case 0x04: p = "I"; break;
- case 0x05: p = "L"; break;
- case 0x06: p = "BTSC"; break;
- case 0x07: p = "EIAJ"; break;
- case 0x08: p = "A2-M"; break;
- case 0x09: p = "FM Radio"; break;
- case 0x0f: p = "automatic standard and mode detection"; break;
- default: p = "undefined";
- }
- cx25840_info("Configured audio system: %s\n", p);
- }
-
- cx25840_info("Specified standard: %s\n",
- vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
-
- switch (state->input) {
- case CX25840_COMPOSITE0: p = "Composite 0"; break;
- case CX25840_COMPOSITE1: p = "Composite 1"; break;
- case CX25840_SVIDEO0: p = "S-Video 0"; break;
- case CX25840_SVIDEO1: p = "S-Video 1"; break;
- case CX25840_TUNER: p = "Tuner"; break;
- }
- cx25840_info("Specified input: %s\n", p);
- cx25840_info("Specified audio input: %s\n",
- state->audio_input == 0 ? "Tuner" : "External");
-
- switch (state->audclk_freq) {
- case V4L2_AUDCLK_441_KHZ: p = "44.1 kHz"; break;
- case V4L2_AUDCLK_48_KHZ: p = "48 kHz"; break;
- case V4L2_AUDCLK_32_KHZ: p = "32 kHz"; break;
- default: p = "undefined";
- }
- cx25840_info("Specified audioclock freq: %s\n", p);
-
- switch (pref_mode & 0xf) {
- case 0: p = "mono/language A"; break;
- case 1: p = "language B"; break;
- case 2: p = "language C"; break;
- case 3: p = "analog fallback"; break;
- case 4: p = "stereo"; break;
- case 5: p = "language AC"; break;
- case 6: p = "language BC"; break;
- case 7: p = "language AB"; break;
- default: p = "undefined";
- }
- cx25840_info("Preferred audio mode: %s\n", p);
-
- if ((audio_config & 0xf) == 0xf) {
- switch ((afc0 >> 3) & 0x3) {
- case 0: p = "system DK"; break;
- case 1: p = "system L"; break;
- case 2: p = "autodetect"; break;
- default: p = "undefined";
- }
- cx25840_info("Selected 65 MHz format: %s\n", p);
-
- switch (afc0 & 0x7) {
- case 0: p = "chroma"; break;
- case 1: p = "BTSC"; break;
- case 2: p = "EIAJ"; break;
- case 3: p = "A2-M"; break;
- case 4: p = "autodetect"; break;
- default: p = "undefined";
- }
- cx25840_info("Selected 45 MHz format: %s\n", p);
- }
-}
diff --git a/trunk/drivers/media/video/cx25840/cx25840-firmware.c b/trunk/drivers/media/video/cx25840/cx25840-firmware.c
deleted file mode 100644
index df9d50a75542..000000000000
--- a/trunk/drivers/media/video/cx25840/cx25840-firmware.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* cx25840 firmware functions
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-
-#include
-#include
-#include
-#include
-#include
-
-#include "cx25840.h"
-
-#define FWFILE "v4l-cx25840.fw"
-#define FWSEND 1024
-
-#define FWDEV(x) &((x)->adapter->dev)
-
-static int fastfw = 1;
-static char *firmware = FWFILE;
-
-module_param(fastfw, bool, 0444);
-module_param(firmware, charp, 0444);
-
-MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]");
-MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]");
-
-static inline void set_i2c_delay(struct i2c_client *client, int delay)
-{
- struct i2c_algo_bit_data *algod = client->adapter->algo_data;
-
- /* We aren't guaranteed to be using algo_bit,
- * so avoid the null pointer dereference
- * and disable the 'fast firmware load' */
- if (algod) {
- algod->udelay = delay;
- } else {
- fastfw = 0;
- }
-}
-
-static inline void start_fw_load(struct i2c_client *client)
-{
- /* DL_ADDR_LB=0 DL_ADDR_HB=0 */
- cx25840_write(client, 0x800, 0x00);
- cx25840_write(client, 0x801, 0x00);
- // DL_MAP=3 DL_AUTO_INC=0 DL_ENABLE=1
- cx25840_write(client, 0x803, 0x0b);
- /* AUTO_INC_DIS=1 */
- cx25840_write(client, 0x000, 0x20);
-
- if (fastfw)
- set_i2c_delay(client, 3);
-}
-
-static inline void end_fw_load(struct i2c_client *client)
-{
- if (fastfw)
- set_i2c_delay(client, 10);
-
- /* AUTO_INC_DIS=0 */
- cx25840_write(client, 0x000, 0x00);
- /* DL_ENABLE=0 */
- cx25840_write(client, 0x803, 0x03);
-}
-
-static inline int check_fw_load(struct i2c_client *client, int size)
-{
- /* DL_ADDR_HB DL_ADDR_LB */
- int s = cx25840_read(client, 0x801) << 8;
- s |= cx25840_read(client, 0x800);
-
- if (size != s) {
- cx25840_err("firmware %s load failed\n", firmware);
- return -EINVAL;
- }
-
- cx25840_info("loaded %s firmware (%d bytes)\n", firmware, size);
- return 0;
-}
-
-static inline int fw_write(struct i2c_client *client, u8 * data, int size)
-{
- if (i2c_master_send(client, data, size) < size) {
-
- if (fastfw) {
- cx25840_err("333MHz i2c firmware load failed\n");
- fastfw = 0;
- set_i2c_delay(client, 10);
-
- if (i2c_master_send(client, data, size) < size) {
- cx25840_err
- ("100MHz i2c firmware load failed\n");
- return -ENOSYS;
- }
-
- } else {
- cx25840_err("firmware load i2c failure\n");
- return -ENOSYS;
- }
-
- }
-
- return 0;
-}
-
-int cx25840_loadfw(struct i2c_client *client)
-{
- const struct firmware *fw = NULL;
- u8 buffer[4], *ptr;
- int size, send, retval;
-
- if (request_firmware(&fw, firmware, FWDEV(client)) != 0) {
- cx25840_err("unable to open firmware %s\n", firmware);
- return -EINVAL;
- }
-
- start_fw_load(client);
-
- buffer[0] = 0x08;
- buffer[1] = 0x02;
- buffer[2] = fw->data[0];
- buffer[3] = fw->data[1];
- retval = fw_write(client, buffer, 4);
-
- if (retval < 0) {
- release_firmware(fw);
- return retval;
- }
-
- size = fw->size - 2;
- ptr = fw->data;
- while (size > 0) {
- ptr[0] = 0x08;
- ptr[1] = 0x02;
- send = size > (FWSEND - 2) ? FWSEND : size + 2;
- retval = fw_write(client, ptr, send);
-
- if (retval < 0) {
- release_firmware(fw);
- return retval;
- }
-
- size -= FWSEND - 2;
- ptr += FWSEND - 2;
- }
-
- end_fw_load(client);
-
- size = fw->size;
- release_firmware(fw);
-
- return check_fw_load(client, size);
-}
diff --git a/trunk/drivers/media/video/cx25840/cx25840-vbi.c b/trunk/drivers/media/video/cx25840/cx25840-vbi.c
deleted file mode 100644
index 13ba4e15ddea..000000000000
--- a/trunk/drivers/media/video/cx25840/cx25840-vbi.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/* cx25840 VBI functions
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-
-#include
-#include
-#include
-
-#include "cx25840.h"
-
-static inline int odd_parity(u8 c)
-{
- c ^= (c >> 4);
- c ^= (c >> 2);
- c ^= (c >> 1);
-
- return c & 1;
-}
-
-static inline int decode_vps(u8 * dst, u8 * p)
-{
- static const u8 biphase_tbl[] = {
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
- 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
- 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
- 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
- 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
- 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
- 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- };
-
- u8 c, err = 0;
- int i;
-
- for (i = 0; i < 2 * 13; i += 2) {
- err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
- c = (biphase_tbl[p[i + 1]] & 0xf) |
- ((biphase_tbl[p[i]] & 0xf) << 4);
- dst[i / 2] = c;
- }
-
- return err & 0xf0;
-}
-
-void cx25840_vbi_setup(struct i2c_client *client)
-{
- v4l2_std_id std = cx25840_get_v4lstd(client);
-
- if (std & ~V4L2_STD_NTSC) {
- /* datasheet startup, step 8d */
- cx25840_write(client, 0x49f, 0x11);
-
- cx25840_write(client, 0x470, 0x84);
- cx25840_write(client, 0x471, 0x00);
- cx25840_write(client, 0x472, 0x2d);
- cx25840_write(client, 0x473, 0x5d);
-
- cx25840_write(client, 0x474, 0x24);
- cx25840_write(client, 0x475, 0x40);
- cx25840_write(client, 0x476, 0x24);
- cx25840_write(client, 0x477, 0x28);
-
- cx25840_write(client, 0x478, 0x1f);
- cx25840_write(client, 0x479, 0x02);
-
- if (std & V4L2_STD_SECAM) {
- cx25840_write(client, 0x47a, 0x80);
- cx25840_write(client, 0x47b, 0x00);
- cx25840_write(client, 0x47c, 0x5f);
- cx25840_write(client, 0x47d, 0x42);
- } else {
- cx25840_write(client, 0x47a, 0x90);
- cx25840_write(client, 0x47b, 0x20);
- cx25840_write(client, 0x47c, 0x63);
- cx25840_write(client, 0x47d, 0x82);
- }
-
- cx25840_write(client, 0x47e, 0x0a);
- cx25840_write(client, 0x47f, 0x01);
- } else {
- /* datasheet startup, step 8d */
- cx25840_write(client, 0x49f, 0x14);
-
- cx25840_write(client, 0x470, 0x7a);
- cx25840_write(client, 0x471, 0x00);
- cx25840_write(client, 0x472, 0x2d);
- cx25840_write(client, 0x473, 0x5b);
-
- cx25840_write(client, 0x474, 0x1a);
- cx25840_write(client, 0x475, 0x70);
- cx25840_write(client, 0x476, 0x1e);
- cx25840_write(client, 0x477, 0x1e);
-
- cx25840_write(client, 0x478, 0x1f);
- cx25840_write(client, 0x479, 0x02);
- cx25840_write(client, 0x47a, 0x50);
- cx25840_write(client, 0x47b, 0x66);
-
- cx25840_write(client, 0x47c, 0x1f);
- cx25840_write(client, 0x47d, 0x7c);
- cx25840_write(client, 0x47e, 0x08);
- cx25840_write(client, 0x47f, 0x00);
- }
-}
-
-int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- struct v4l2_format *fmt;
- struct v4l2_sliced_vbi_format *svbi;
-
- switch (cmd) {
- case VIDIOC_G_FMT:
- {
- static u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_WSS_625, 0, /* 4 */
- V4L2_SLICED_CAPTION_525, /* 6 */
- 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
- 0, 0, 0, 0
- };
- int i;
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- memset(svbi, 0, sizeof(*svbi));
- /* we're done if raw VBI is active */
- if ((cx25840_read(client, 0x404) & 0x10) == 0)
- break;
-
- for (i = 7; i <= 23; i++) {
- u8 v = cx25840_read(client, 0x424 + i - 7);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |=
- svbi->service_lines[0][i] | svbi->service_lines[1][i];
- }
- break;
- }
-
- case VIDIOC_S_FMT:
- {
- int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
- int vbi_offset = is_pal ? 1 : 0;
- int i, x;
- u8 lcr[24];
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- if (svbi->service_set == 0) {
- /* raw VBI */
- memset(svbi, 0, sizeof(*svbi));
-
- /* Setup VBI */
- cx25840_vbi_setup(client);
-
- /* VBI Offset */
- cx25840_write(client, 0x47f, vbi_offset);
- cx25840_write(client, 0x404, 0x2e);
- break;
- }
-
- for (x = 0; x <= 23; x++)
- lcr[x] = 0x00;
-
- /* Setup VBI */
- cx25840_vbi_setup(client);
-
- /* Sliced VBI */
- cx25840_write(client, 0x404, 0x36); /* Ancillery data */
- cx25840_write(client, 0x406, 0x13);
- cx25840_write(client, 0x47f, vbi_offset);
-
- if (is_pal) {
- for (i = 0; i <= 6; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- } else {
- for (i = 0; i <= 9; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
-
- for (i = 22; i <= 23; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- }
-
- for (i = 7; i <= 23; i++) {
- for (x = 0; x <= 1; x++) {
- switch (svbi->service_lines[1-x][i]) {
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 6 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 9 << (4 * x);
- break;
- }
- }
- }
-
- for (x = 1, i = 0x424; i <= 0x434; i++, x++) {
- cx25840_write(client, i, lcr[6 + x]);
- }
-
- cx25840_write(client, 0x43c, 0x16);
-
- if (is_pal) {
- cx25840_write(client, 0x474, 0x2a);
- } else {
- cx25840_write(client, 0x474, 0x1a + 6);
- }
- break;
- }
-
- case VIDIOC_INT_DECODE_VBI_LINE:
- {
- struct v4l2_decode_vbi_line *vbi = arg;
- u8 *p = vbi->p;
- int id1, id2, l, err = 0;
-
- if (p[0] || p[1] != 0xff || p[2] != 0xff ||
- (p[3] != 0x55 && p[3] != 0x91)) {
- vbi->line = vbi->type = 0;
- break;
- }
-
- p += 4;
- id1 = p[-1];
- id2 = p[0] & 0xf;
- l = p[2] & 0x3f;
- l += 5;
- p += 4;
-
- switch (id2) {
- case 1:
- id2 = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- id2 = V4L2_SLICED_WSS_625;
- break;
- case 6:
- id2 = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[0]) || !odd_parity(p[1]);
- break;
- case 9:
- id2 = V4L2_SLICED_VPS;
- if (decode_vps(p, p) != 0) {
- err = 1;
- }
- break;
- default:
- id2 = 0;
- err = 1;
- break;
- }
-
- vbi->type = err ? 0 : id2;
- vbi->line = err ? 0 : l;
- vbi->is_second_field = err ? 0 : (id1 == 0x55);
- vbi->p = p;
- break;
- }
- }
-
- return 0;
-}
diff --git a/trunk/drivers/media/video/cx25840/cx25840.h b/trunk/drivers/media/video/cx25840/cx25840.h
deleted file mode 100644
index 5c3f0639fb77..000000000000
--- a/trunk/drivers/media/video/cx25840/cx25840.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* cx25840 API header
- *
- * Copyright (C) 2003-2004 Chris Kennedy
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef _CX25840_H_
-#define _CX25840_H_
-
-
-#include
-#include
-
-extern int cx25840_debug;
-
-#define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \
- printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
- i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
-#define cx25840_err(fmt, arg...) do { \
- printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
- i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
-#define cx25840_info(fmt, arg...) do { \
- printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
- i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
-#define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0)
-
-enum cx25840_cardtype {
- CARDTYPE_PVR150,
- CARDTYPE_PG600
-};
-
-enum cx25840_input {
- CX25840_TUNER,
- CX25840_COMPOSITE0,
- CX25840_COMPOSITE1,
- CX25840_SVIDEO0,
- CX25840_SVIDEO1
-};
-
-struct cx25840_state {
- enum cx25840_cardtype cardtype;
- enum cx25840_input input;
- int audio_input;
- enum v4l2_audio_clock_freq audclk_freq;
-};
-
-/* ----------------------------------------------------------------------- */
-/* cx25850-core.c */
-int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
-int cx25840_write4(struct i2c_client *client, u16 addr, u32 value);
-u8 cx25840_read(struct i2c_client *client, u16 addr);
-u32 cx25840_read4(struct i2c_client *client, u16 addr);
-int cx25840_and_or(struct i2c_client *client, u16 addr, u8 mask, u8 value);
-v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client);
-
-/* ----------------------------------------------------------------------- */
-/* cx25850-firmware.c */
-int cx25840_loadfw(struct i2c_client *client);
-
-/* ----------------------------------------------------------------------- */
-/* cx25850-audio.c */
-int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg);
-
-/* ----------------------------------------------------------------------- */
-/* cx25850-vbi.c */
-void cx25840_vbi_setup(struct i2c_client *client);
-int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg);
-
-#endif
diff --git a/trunk/drivers/media/video/cx88/cx88-dvb.c b/trunk/drivers/media/video/cx88/cx88-dvb.c
index 99ea955f5987..9cce91ec334b 100644
--- a/trunk/drivers/media/video/cx88/cx88-dvb.c
+++ b/trunk/drivers/media/video/cx88/cx88-dvb.c
@@ -439,6 +439,9 @@ static int dvb_register(struct cx8802_dev *dev)
/* Put the analog decoder in standby to keep it quiet */
cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+ /* Put the analog decoder in standby to keep it quiet */
+ cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+
/* register everything */
return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
}
diff --git a/trunk/drivers/media/video/em28xx/em28xx-input.c b/trunk/drivers/media/video/em28xx/em28xx-input.c
index 9b94f77d6fd7..32c49df58adc 100644
--- a/trunk/drivers/media/video/em28xx/em28xx-input.c
+++ b/trunk/drivers/media/video/em28xx/em28xx-input.c
@@ -120,6 +120,9 @@ static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
if (buf[1]==0xff)
return 0;
+ /* avoid fast reapeating */
+ if (buf[1]==ir->old)
+ return 0;
ir->old=buf[1];
/* Rearranges bits to the right order */
diff --git a/trunk/drivers/media/video/ir-kbd-gpio.c b/trunk/drivers/media/video/ir-kbd-gpio.c
index 5abfc0fbf6de..ed81934ef3cd 100644
--- a/trunk/drivers/media/video/ir-kbd-gpio.c
+++ b/trunk/drivers/media/video/ir-kbd-gpio.c
@@ -221,99 +221,24 @@ static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
[ 24 ] = KEY_MUTE // mute/unmute
};
-static IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = {
- [0x00] = KEY_KP0,
- [0x01] = KEY_KP1,
- [0x02] = KEY_KP2,
- [0x03] = KEY_KP3,
- [0x04] = KEY_KP4,
- [0x05] = KEY_KP5,
- [0x06] = KEY_KP6,
- [0x07] = KEY_KP7,
- [0x08] = KEY_KP8,
- [0x09] = KEY_KP9,
- [0x0a] = KEY_TV,
- [0x0b] = KEY_AUX,
- [0x0c] = KEY_DVD,
- [0x0d] = KEY_POWER,
- [0x0e] = KEY_MHP, /* labelled 'Picture' */
- [0x0f] = KEY_AUDIO,
- [0x10] = KEY_INFO,
- [0x11] = KEY_F13, /* 16:9 */
- [0x12] = KEY_F14, /* 14:9 */
- [0x13] = KEY_EPG,
- [0x14] = KEY_EXIT,
- [0x15] = KEY_MENU,
- [0x16] = KEY_UP,
- [0x17] = KEY_DOWN,
- [0x18] = KEY_LEFT,
- [0x19] = KEY_RIGHT,
- [0x1a] = KEY_ENTER,
- [0x1b] = KEY_CHANNELUP,
- [0x1c] = KEY_CHANNELDOWN,
- [0x1d] = KEY_VOLUMEUP,
- [0x1e] = KEY_VOLUMEDOWN,
- [0x1f] = KEY_RED,
- [0x20] = KEY_GREEN,
- [0x21] = KEY_YELLOW,
- [0x22] = KEY_BLUE,
- [0x23] = KEY_SUBTITLE,
- [0x24] = KEY_F15, /* AD */
- [0x25] = KEY_TEXT,
- [0x26] = KEY_MUTE,
- [0x27] = KEY_REWIND,
- [0x28] = KEY_STOP,
- [0x29] = KEY_PLAY,
- [0x2a] = KEY_FASTFORWARD,
- [0x2b] = KEY_F16, /* chapter */
- [0x2c] = KEY_PAUSE,
- [0x2d] = KEY_PLAY,
- [0x2e] = KEY_RECORD,
- [0x2f] = KEY_F17, /* picture in picture */
- [0x30] = KEY_KPPLUS, /* zoom in */
- [0x31] = KEY_KPMINUS, /* zoom out */
- [0x32] = KEY_F18, /* capture */
- [0x33] = KEY_F19, /* web */
- [0x34] = KEY_EMAIL,
- [0x35] = KEY_PHONE,
- [0x36] = KEY_PC
-};
-
struct IR {
struct bttv_sub_device *sub;
struct input_dev *input;
struct ir_input_state ir;
char name[32];
char phys[32];
-
- /* Usual gpio signalling */
-
u32 mask_keycode;
u32 mask_keydown;
u32 mask_keyup;
- u32 polling;
+
+ int polling;
u32 last_gpio;
struct work_struct work;
struct timer_list timer;
-
- /* RC5 gpio */
-
- u32 rc5_gpio;
- struct timer_list timer_end; /* timer_end for code completion */
- struct timer_list timer_keyup; /* timer_end for key release */
- u32 last_rc5; /* last good rc5 code */
- u32 last_bit; /* last raw bit seen */
- u32 code; /* raw code under construction */
- struct timeval base_time; /* time of last seen code */
- int active; /* building raw code */
};
static int debug;
module_param(debug, int, 0644); /* debug level (0,1,2) */
-static int repeat_delay = 500;
-module_param(repeat_delay, int, 0644);
-static int repeat_period = 33;
-module_param(repeat_period, int, 0644);
#define DEVNAME "ir-kbd-gpio"
#define dprintk(fmt, arg...) if (debug) \
@@ -329,7 +254,7 @@ static struct bttv_sub_driver driver = {
.probe = ir_probe,
.remove = ir_remove,
},
- .gpio_irq = ir_irq,
+ .gpio_irq = ir_irq,
};
/* ---------------------------------------------------------------------- */
@@ -402,173 +327,6 @@ static void ir_work(void *data)
mod_timer(&ir->timer, timeout);
}
-/* ---------------------------------------------------------------*/
-
-static int rc5_remote_gap = 885;
-module_param(rc5_remote_gap, int, 0644);
-static int rc5_key_timeout = 200;
-module_param(rc5_key_timeout, int, 0644);
-
-#define RC5_START(x) (((x)>>12)&3)
-#define RC5_TOGGLE(x) (((x)>>11)&1)
-#define RC5_ADDR(x) (((x)>>6)&31)
-#define RC5_INSTR(x) ((x)&63)
-
-/* decode raw bit pattern to RC5 code */
-static u32 rc5_decode(unsigned int code)
-{
- unsigned int org_code = code;
- unsigned int pair;
- unsigned int rc5 = 0;
- int i;
-
- code = (code << 1) | 1;
- for (i = 0; i < 14; ++i) {
- pair = code & 0x3;
- code >>= 2;
-
- rc5 <<= 1;
- switch (pair) {
- case 0:
- case 2:
- break;
- case 1:
- rc5 |= 1;
- break;
- case 3:
- dprintk("bad code: %x\n", org_code);
- return 0;
- }
- }
- dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
- "instr=%x\n", rc5, org_code, RC5_START(rc5),
- RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
- return rc5;
-}
-
-static int ir_rc5_irq(struct bttv_sub_device *sub)
-{
- struct IR *ir = dev_get_drvdata(&sub->dev);
- struct timeval tv;
- u32 gpio;
- u32 gap;
- unsigned long current_jiffies, timeout;
-
- /* read gpio port */
- gpio = bttv_gpio_read(ir->sub->core);
-
- /* remote IRQ? */
- if (!(gpio & 0x20))
- return 0;
-
- /* get time of bit */
- current_jiffies = jiffies;
- do_gettimeofday(&tv);
-
- /* avoid overflow with gap >1s */
- if (tv.tv_sec - ir->base_time.tv_sec > 1) {
- gap = 200000;
- } else {
- gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
- tv.tv_usec - ir->base_time.tv_usec;
- }
-
- /* active code => add bit */
- if (ir->active) {
- /* only if in the code (otherwise spurious IRQ or timer
- late) */
- if (ir->last_bit < 28) {
- ir->last_bit = (gap - rc5_remote_gap / 2) /
- rc5_remote_gap;
- ir->code |= 1 << ir->last_bit;
- }
- /* starting new code */
- } else {
- ir->active = 1;
- ir->code = 0;
- ir->base_time = tv;
- ir->last_bit = 0;
-
- timeout = current_jiffies + (500 + 30 * HZ) / 1000;
- mod_timer(&ir->timer_end, timeout);
- }
-
- /* toggle GPIO pin 4 to reset the irq */
- bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4));
- bttv_gpio_write(ir->sub->core, gpio | (1 << 4));
- return 1;
-}
-
-static void ir_rc5_timer_end(unsigned long data)
-{
- struct IR *ir = (struct IR *)data;
- struct timeval tv;
- unsigned long current_jiffies, timeout;
- u32 gap;
-
- /* get time */
- current_jiffies = jiffies;
- do_gettimeofday(&tv);
-
- /* avoid overflow with gap >1s */
- if (tv.tv_sec - ir->base_time.tv_sec > 1) {
- gap = 200000;
- } else {
- gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
- tv.tv_usec - ir->base_time.tv_usec;
- }
-
- /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
- if (gap < 28000) {
- dprintk("spurious timer_end\n");
- return;
- }
-
- ir->active = 0;
- if (ir->last_bit < 20) {
- /* ignore spurious codes (caused by light/other remotes) */
- dprintk("short code: %x\n", ir->code);
- } else {
- u32 rc5 = rc5_decode(ir->code);
-
- /* two start bits? */
- if (RC5_START(rc5) != 3) {
- dprintk("rc5 start bits invalid: %u\n", RC5_START(rc5));
-
- /* right address? */
- } else if (RC5_ADDR(rc5) == 0x0) {
- u32 toggle = RC5_TOGGLE(rc5);
- u32 instr = RC5_INSTR(rc5);
-
- /* Good code, decide if repeat/repress */
- if (toggle != RC5_TOGGLE(ir->last_rc5) ||
- instr != RC5_INSTR(ir->last_rc5)) {
- dprintk("instruction %x, toggle %x\n", instr,
- toggle);
- ir_input_nokey(ir->input, &ir->ir);
- ir_input_keydown(ir->input, &ir->ir, instr,
- instr);
- }
-
- /* Set/reset key-up timer */
- timeout = current_jiffies + (500 + rc5_key_timeout
- * HZ) / 1000;
- mod_timer(&ir->timer_keyup, timeout);
-
- /* Save code for repeat test */
- ir->last_rc5 = rc5;
- }
- }
-}
-
-static void ir_rc5_timer_keyup(unsigned long data)
-{
- struct IR *ir = (struct IR *)data;
-
- dprintk("key released\n");
- ir_input_nokey(ir->input, &ir->ir);
-}
-
/* ---------------------------------------------------------------------- */
static int ir_probe(struct device *dev)
@@ -642,12 +400,6 @@ static int ir_probe(struct device *dev)
ir->mask_keyup = 0x006000;
ir->polling = 50; // ms
break;
- case BTTV_BOARD_NEBULA_DIGITV:
- ir_codes = ir_codes_nebula;
- driver.any_irq = ir_rc5_irq;
- driver.gpio_irq = NULL;
- ir->rc5_gpio = 1;
- break;
}
if (NULL == ir_codes) {
kfree(ir);
@@ -655,17 +407,9 @@ static int ir_probe(struct device *dev)
return -ENODEV;
}
- if (ir->rc5_gpio) {
- u32 gpio;
- /* enable remote irq */
- bttv_gpio_inout(sub->core, (1 << 4), 1 << 4);
- gpio = bttv_gpio_read(sub->core);
- bttv_gpio_write(sub->core, gpio & ~(1 << 4));
- bttv_gpio_write(sub->core, gpio | (1 << 4));
- } else {
- /* init hardware-specific stuff */
- bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0);
- }
+ /* init hardware-specific stuff */
+ bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0);
+ ir->sub = sub;
/* init input device */
snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
@@ -673,7 +417,6 @@ static int ir_probe(struct device *dev)
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
pci_name(sub->core->pci));
- ir->sub = sub;
ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
input_dev->name = ir->name;
input_dev->phys = ir->phys;
@@ -694,25 +437,11 @@ static int ir_probe(struct device *dev)
ir->timer.function = ir_timer;
ir->timer.data = (unsigned long)ir;
schedule_work(&ir->work);
- } else if (ir->rc5_gpio) {
- /* set timer_end for code completion */
- init_timer(&ir->timer_end);
- ir->timer_end.function = ir_rc5_timer_end;
- ir->timer_end.data = (unsigned long)ir;
-
- init_timer(&ir->timer_keyup);
- ir->timer_keyup.function = ir_rc5_timer_keyup;
- ir->timer_keyup.data = (unsigned long)ir;
}
/* all done */
dev_set_drvdata(dev, ir);
input_register_device(ir->input);
- printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
-
- /* the remote isn't as bouncy as a keyboard */
- ir->input->rep[REP_DELAY] = repeat_delay;
- ir->input->rep[REP_PERIOD] = repeat_period;
return 0;
}
@@ -725,15 +454,6 @@ static int ir_remove(struct device *dev)
del_timer(&ir->timer);
flush_scheduled_work();
}
- if (ir->rc5_gpio) {
- u32 gpio;
-
- del_timer(&ir->timer_end);
- flush_scheduled_work();
-
- gpio = bttv_gpio_read(ir->sub->core);
- bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4));
- }
input_unregister_device(ir->input);
kfree(ir);
diff --git a/trunk/drivers/media/video/ir-kbd-i2c.c b/trunk/drivers/media/video/ir-kbd-i2c.c
index 801c736e9328..0085567a1421 100644
--- a/trunk/drivers/media/video/ir-kbd-i2c.c
+++ b/trunk/drivers/media/video/ir-kbd-i2c.c
@@ -183,58 +183,6 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
-/* The new pinnacle PCTV remote (with the colored buttons)
- *
- * Ricardo Cerqueira
- */
-
-int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
- unsigned char b[4];
- unsigned int start = 0,parity = 0,code = 0;
-
- /* poll IR chip */
- if (4 != i2c_master_recv(&ir->c,b,4)) {
- dprintk(2,"read error\n");
- return -EIO;
- }
-
- for (start = 0; start<4; start++) {
- if (b[start] == 0x80) {
- code=b[(start+3)%4];
- parity=b[(start+2)%4];
- }
- }
-
- /* Empty Request */
- if (parity==0)
- return 0;
-
- /* Repeating... */
- if (ir->old == parity)
- return 0;
-
-
- ir->old = parity;
-
- /* Reduce code value to fit inside IR_KEYTAB_SIZE
- *
- * this is the only value that results in 42 unique
- * codes < 128
- */
-
- code %= 0x88;
-
- *ir_raw = code;
- *ir_key = code;
-
- dprintk(1,"Pinnacle PCTV key %02x\n", code);
-
- return 1;
-}
-
-EXPORT_SYMBOL_GPL(get_key_pinnacle);
-
/* ----------------------------------------------------------------------- */
static void ir_key_poll(struct IR_i2c *ir)
diff --git a/trunk/drivers/media/video/saa7115.c b/trunk/drivers/media/video/saa7115.c
deleted file mode 100644
index 0235cef07b31..000000000000
--- a/trunk/drivers/media/video/saa7115.c
+++ /dev/null
@@ -1,1376 +0,0 @@
-/* saa7115 - Philips SAA7114/SAA7115 video decoder driver
- *
- * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
- * the saa7111 driver by Dave Perks.
- *
- * Copyright (C) 1998 Dave Perks
- * Copyright (C) 2002 Maxim Yevtyushkin
- *
- * Slight changes for video timing and attachment output by
- * Wolfgang Scherr
- *
- * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
- * by Ronald Bultje
- *
- * Added saa7115 support by Kevin Thayer
- * (2/17/2003)
- *
- * VBI support (2004) and cleanups (2005) by Hans Verkuil
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver");
-MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil");
-MODULE_LICENSE("GPL");
-
-static int debug = 0;
-module_param(debug, int, 0644);
-
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-#define saa7115_dbg(fmt,arg...) \
- do { \
- if (debug) \
- printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
- i2c_adapter_id(client->adapter), client->addr , ## arg); \
- } while (0)
-
-#define saa7115_err(fmt, arg...) do { \
- printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
- i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-#define saa7115_info(fmt, arg...) do { \
- printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
- i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
-static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
-
-
-I2C_CLIENT_INSMOD;
-
-struct saa7115_state {
- v4l2_std_id std;
- int input;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
- enum v4l2_chip_ident ident;
- enum v4l2_audio_clock_freq audclk_freq;
-};
-
-/* ----------------------------------------------------------------------- */
-
-static inline int saa7115_write(struct i2c_client *client, u8 reg, u8 value)
-{
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int saa7115_writeregs(struct i2c_client *client, const unsigned char *regs)
-{
- unsigned char reg, data;
-
- while (*regs != 0x00) {
- reg = *(regs++);
- data = *(regs++);
- if (saa7115_write(client, reg, data) < 0)
- return -1;
- }
- return 0;
-}
-
-static inline int saa7115_read(struct i2c_client *client, u8 reg)
-{
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-/* If a value differs from the Hauppauge driver values, then the comment starts with
- 'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
- Hauppauge driver sets. */
-
-static const unsigned char saa7115_init_auto_input[] = {
- 0x01, 0x48, /* white peak control disabled */
- 0x03, 0x20, /* was 0x30. 0x20: long vertical blanking */
- 0x04, 0x90, /* analog gain set to 0 */
- 0x05, 0x90, /* analog gain set to 0 */
- 0x06, 0xeb, /* horiz sync begin = -21 */
- 0x07, 0xe0, /* horiz sync stop = -17 */
- 0x0a, 0x80, /* was 0x88. decoder brightness, 0x80 is itu standard */
- 0x0b, 0x44, /* was 0x48. decoder contrast, 0x44 is itu standard */
- 0x0c, 0x40, /* was 0x47. decoder saturation, 0x40 is itu standard */
- 0x0d, 0x00, /* chrominance hue control */
- 0x0f, 0x00, /* chrominance gain control: use automicatic mode */
- 0x10, 0x06, /* chrominance/luminance control: active adaptive combfilter */
- 0x11, 0x00, /* delay control */
- 0x12, 0x9d, /* RTS0 output control: VGATE */
- 0x13, 0x80, /* X-port output control: ITU656 standard mode, RTCO output enable RTCE */
- 0x14, 0x00, /* analog/ADC/auto compatibility control */
- 0x18, 0x40, /* raw data gain 0x00 = nominal */
- 0x19, 0x80, /* raw data offset 0x80 = 0 LSB */
- 0x1a, 0x77, /* color killer level control 0x77 = recommended */
- 0x1b, 0x42, /* misc chroma control 0x42 = recommended */
- 0x1c, 0xa9, /* combfilter control 0xA9 = recommended */
- 0x1d, 0x01, /* combfilter control 0x01 = recommended */
- 0x88, 0xd0, /* reset device */
- 0x88, 0xf0, /* set device programmed, all in operational mode */
- 0x00, 0x00
-};
-
-static const unsigned char saa7115_cfg_reset_scaler[] = {
- 0x87, 0x00, /* disable I-port output */
- 0x88, 0xd0, /* reset scaler */
- 0x88, 0xf0, /* activate scaler */
- 0x87, 0x01, /* enable I-port output */
- 0x00, 0x00
-};
-
-/* ============== SAA7715 VIDEO templates ============= */
-
-static const unsigned char saa7115_cfg_60hz_fullres_x[] = {
- 0xcc, 0xd0, /* hsize low (output), hor. output window size = 0x2d0 = 720 */
- 0xcd, 0x02, /* hsize hi (output) */
-
- /* Why not in 60hz-Land, too? */
- 0xd0, 0x01, /* downscale = 1 */
- 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */
- 0xd9, 0x04,
- 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
- 0xdd, 0x02, /* H-scaling incr chroma */
-
- 0x00, 0x00
-};
-static const unsigned char saa7115_cfg_60hz_fullres_y[] = {
- 0xce, 0xf8, /* vsize low (output), ver. output window size = 248 (but 60hz is 240?) */
- 0xcf, 0x00, /* vsize hi (output) */
-
- /* Why not in 60hz-Land, too? */
- 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */
- 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */
-
- 0xe0, 0x00, /* V-scaling incr luma low */
- 0xe1, 0x04, /* " hi */
- 0xe2, 0x00, /* V-scaling incr chroma low */
- 0xe3, 0x04, /* " hi */
-
- 0x00, 0x00
-};
-
-static const unsigned char saa7115_cfg_60hz_video[] = {
- 0x80, 0x00, /* reset tasks */
- 0x88, 0xd0, /* reset scaler */
-
- 0x15, 0x03, /* VGATE pulse start */
- 0x16, 0x11, /* VGATE pulse stop */
- 0x17, 0x9c, /* VGATE MSB and other values */
-
- 0x08, 0x68, /* 0xBO: auto detection, 0x68 = NTSC */
- 0x0e, 0x07, /* lots of different stuff... video autodetection is on */
-
- 0x5a, 0x06, /* Vertical offset, standard 60hz value for ITU656 line counting */
-
- /* Task A */
- 0x90, 0x80, /* Task Handling Control */
- 0x91, 0x48, /* X-port formats/config */
- 0x92, 0x40, /* Input Ref. signal Def. */
- 0x93, 0x84, /* I-port config */
- 0x94, 0x01, /* hoffset low (input), 0x0002 is minimum */
- 0x95, 0x00, /* hoffset hi (input) */
- 0x96, 0xd0, /* hsize low (input), 0x02d0 = 720 */
- 0x97, 0x02, /* hsize hi (input) */
- 0x98, 0x05, /* voffset low (input) */
- 0x99, 0x00, /* voffset hi (input) */
- 0x9a, 0x0c, /* vsize low (input), 0x0c = 12 */
- 0x9b, 0x00, /* vsize hi (input) */
- 0x9c, 0xa0, /* hsize low (output), 0x05a0 = 1440 */
- 0x9d, 0x05, /* hsize hi (output) */
- 0x9e, 0x0c, /* vsize low (output), 0x0c = 12 */
- 0x9f, 0x00, /* vsize hi (output) */
-
- /* Task B */
- 0xc0, 0x00, /* Task Handling Control */
- 0xc1, 0x08, /* X-port formats/config */
- 0xc2, 0x00, /* Input Ref. signal Def. */
- 0xc3, 0x80, /* I-port config */
- 0xc4, 0x02, /* hoffset low (input), 0x0002 is minimum */
- 0xc5, 0x00, /* hoffset hi (input) */
- 0xc6, 0xd0, /* hsize low (input), 0x02d0 = 720 */
- 0xc7, 0x02, /* hsize hi (input) */
- 0xc8, 0x12, /* voffset low (input), 0x12 = 18 */
- 0xc9, 0x00, /* voffset hi (input) */
- 0xca, 0xf8, /* vsize low (input), 0xf8 = 248 */
- 0xcb, 0x00, /* vsize hi (input) */
- 0xcc, 0xd0, /* hsize low (output), 0x02d0 = 720 */
- 0xcd, 0x02, /* hsize hi (output) */
-
- 0xf0, 0xad, /* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
- 0xf1, 0x05, /* low bit with 0xF0 */
- 0xf5, 0xad, /* Set pulse generator register */
- 0xf6, 0x01,
-
- 0x87, 0x00, /* Disable I-port output */
- 0x88, 0xd0, /* reset scaler */
- 0x80, 0x20, /* Activate only task "B", continuous mode (was 0xA0) */
- 0x88, 0xf0, /* activate scaler */
- 0x87, 0x01, /* Enable I-port output */
- 0x00, 0x00
-};
-
-static const unsigned char saa7115_cfg_50hz_fullres_x[] = {
- 0xcc, 0xd0, /* hsize low (output), 720 same as 60hz */
- 0xcd, 0x02, /* hsize hi (output) */
-
- 0xd0, 0x01, /* down scale = 1 */
- 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */
- 0xd9, 0x04,
- 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
- 0xdd, 0x02, /* H-scaling incr chroma */
-
- 0x00, 0x00
-};
-static const unsigned char saa7115_cfg_50hz_fullres_y[] = {
- 0xce, 0x20, /* vsize low (output), 0x0120 = 288 */
- 0xcf, 0x01, /* vsize hi (output) */
-
- 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */
- 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */
-
- 0xe0, 0x00, /* V-scaling incr luma low */
- 0xe1, 0x04, /* " hi */
- 0xe2, 0x00, /* V-scaling incr chroma low */
- 0xe3, 0x04, /* " hi */
-
- 0x00, 0x00
-};
-
-static const unsigned char saa7115_cfg_50hz_video[] = {
- 0x80, 0x00, /* reset tasks */
- 0x88, 0xd0, /* reset scaler */
-
- 0x15, 0x37, /* VGATE start */
- 0x16, 0x16, /* VGATE stop */
- 0x17, 0x99, /* VGATE MSB and other values */
-
- 0x08, 0x28, /* 0x28 = PAL */
- 0x0e, 0x07, /* chrominance control 1 */
-
- 0x5a, 0x03, /* Vertical offset, standard 50hz value */
-
- /* Task A */
- 0x90, 0x81, /* Task Handling Control */
- 0x91, 0x48, /* X-port formats/config */
- 0x92, 0x40, /* Input Ref. signal Def. */
- 0x93, 0x84, /* I-port config */
- /* This is weird: the datasheet says that you should use 2 as the minimum value, */
- /* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
- 0x94, 0x00, /* hoffset low (input), 0x0002 is minimum */
- 0x95, 0x00, /* hoffset hi (input) */
- 0x96, 0xd0, /* hsize low (input), 0x02d0 = 720 */
- 0x97, 0x02, /* hsize hi (input) */
- 0x98, 0x03, /* voffset low (input) */
- 0x99, 0x00, /* voffset hi (input) */
- 0x9a, 0x12, /* vsize low (input), 0x12 = 18 */
- 0x9b, 0x00, /* vsize hi (input) */
- 0x9c, 0xa0, /* hsize low (output), 0x05a0 = 1440 */
- 0x9d, 0x05, /* hsize hi (output) */
- 0x9e, 0x12, /* vsize low (output), 0x12 = 18 */
- 0x9f, 0x00, /* vsize hi (output) */
-
- /* Task B */
- 0xc0, 0x00, /* Task Handling Control */
- 0xc1, 0x08, /* X-port formats/config */
- 0xc2, 0x00, /* Input Ref. signal Def. */
- 0xc3, 0x80, /* I-port config */
- 0xc4, 0x00, /* hoffset low (input), 0x0002 is minimum. See comment at 0x94 above. */
- 0xc5, 0x00, /* hoffset hi (input) */
- 0xc6, 0xd0, /* hsize low (input), 0x02d0 = 720 */
- 0xc7, 0x02, /* hsize hi (input) */
- 0xc8, 0x16, /* voffset low (input), 0x16 = 22 */
- 0xc9, 0x00, /* voffset hi (input) */
- 0xca, 0x20, /* vsize low (input), 0x0120 = 288 */
- 0xcb, 0x01, /* vsize hi (input) */
- 0xcc, 0xd0, /* hsize low (output), 0x02d0 = 720 */
- 0xcd, 0x02, /* hsize hi (output) */
- 0xce, 0x20, /* vsize low (output), 0x0120 = 288 */
- 0xcf, 0x01, /* vsize hi (output) */
-
- 0xf0, 0xb0, /* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
- 0xf1, 0x05, /* low bit with 0xF0, (was 0x05) */
- 0xf5, 0xb0, /* Set pulse generator register */
- 0xf6, 0x01,
-
- 0x87, 0x00, /* Disable I-port output */
- 0x88, 0xd0, /* reset scaler (was 0xD0) */
- 0x80, 0x20, /* Activate only task "B" */
- 0x88, 0xf0, /* activate scaler */
- 0x87, 0x01, /* Enable I-port output */
- 0x00, 0x00
-};
-
-/* ============== SAA7715 VIDEO templates (end) ======= */
-
-static const unsigned char saa7115_cfg_vbi_on[] = {
- 0x80, 0x00, /* reset tasks */
- 0x88, 0xd0, /* reset scaler */
- 0x80, 0x30, /* Activate both tasks */
- 0x88, 0xf0, /* activate scaler */
- 0x87, 0x01, /* Enable I-port output */
- 0x00, 0x00
-};
-
-static const unsigned char saa7115_cfg_vbi_off[] = {
- 0x80, 0x00, /* reset tasks */
- 0x88, 0xd0, /* reset scaler */
- 0x80, 0x20, /* Activate only task "B" */
- 0x88, 0xf0, /* activate scaler */
- 0x87, 0x01, /* Enable I-port output */
- 0x00, 0x00
-};
-
-static const unsigned char saa7115_init_misc[] = {
- 0x38, 0x03, /* audio stuff */
- 0x39, 0x10,
- 0x3a, 0x08,
-
- 0x81, 0x01, /* reg 0x15,0x16 define blanking window */
- 0x82, 0x00,
- 0x83, 0x01, /* I port settings */
- 0x84, 0x20,
- 0x85, 0x21,
- 0x86, 0xc5,
- 0x87, 0x01,
-
- /* Task A */
- 0xa0, 0x01, /* down scale = 1 */
- 0xa1, 0x00, /* prescale accumulation length = 1 */
- 0xa2, 0x00, /* dc gain and fir prefilter control */
- 0xa4, 0x80, /* Lum Brightness, nominal value = 0x80 */
- 0xa5, 0x40, /* Lum contrast, nominal value = 0x40 */
- 0xa6, 0x40, /* Chroma satur. nominal value = 0x80 */
- 0xa8, 0x00, /* hor lum scaling 0x0200 = 2 zoom */
- 0xa9, 0x02, /* note: 2 x zoom ensures that VBI lines have same length as video lines. */
- 0xaa, 0x00, /* H-phase offset Luma = 0 */
- 0xac, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
- 0xad, 0x01, /* H-scaling incr chroma */
- 0xae, 0x00, /* H-phase offset chroma. must be offset luma / 2 */
-
- 0xb0, 0x00, /* V-scaling incr luma low */
- 0xb1, 0x04, /* " hi */
- 0xb2, 0x00, /* V-scaling incr chroma low */
- 0xb3, 0x04, /* " hi */
- 0xb4, 0x01, /* V-scaling mode control */
- 0xb8, 0x00, /* V-phase offset chroma 00 */
- 0xb9, 0x00, /* V-phase offset chroma 01 */
- 0xba, 0x00, /* V-phase offset chroma 10 */
- 0xbb, 0x00, /* V-phase offset chroma 11 */
- 0xbc, 0x00, /* V-phase offset luma 00 */
- 0xbd, 0x00, /* V-phase offset luma 01 */
- 0xbe, 0x00, /* V-phase offset luma 10 */
- 0xbf, 0x00, /* V-phase offset luma 11 */
-
- /* Task B */
- 0xd0, 0x01, /* down scale = 1 */
- 0xd1, 0x00, /* prescale accumulation length = 1 */
- 0xd2, 0x00, /* dc gain and fir prefilter control */
- 0xd4, 0x80, /* Lum Brightness, nominal value = 0x80 */
- 0xd5, 0x40, /* Lum contrast, nominal value = 0x40 */
- 0xd6, 0x40, /* Chroma satur. nominal value = 0x80 */
- 0xd8, 0x00, /* hor lum scaling 0x0400 = 1 */
- 0xd9, 0x04,
- 0xda, 0x00, /* H-phase offset Luma = 0 */
- 0xdc, 0x00, /* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
- 0xdd, 0x02, /* H-scaling incr chroma */
- 0xde, 0x00, /* H-phase offset chroma. must be offset luma / 2 */
-
- 0xe0, 0x00, /* V-scaling incr luma low */
- 0xe1, 0x04, /* " hi */
- 0xe2, 0x00, /* V-scaling incr chroma low */
- 0xe3, 0x04, /* " hi */
- 0xe4, 0x01, /* V-scaling mode control */
- 0xe8, 0x00, /* V-phase offset chroma 00 */
- 0xe9, 0x00, /* V-phase offset chroma 01 */
- 0xea, 0x00, /* V-phase offset chroma 10 */
- 0xeb, 0x00, /* V-phase offset chroma 11 */
- 0xec, 0x00, /* V-phase offset luma 00 */
- 0xed, 0x00, /* V-phase offset luma 01 */
- 0xee, 0x00, /* V-phase offset luma 10 */
- 0xef, 0x00, /* V-phase offset luma 11 */
-
- 0xf2, 0x50, /* crystal clock = 24.576 MHz, target = 27MHz */
- 0xf3, 0x46,
- 0xf4, 0x00,
- 0xf7, 0x4b, /* not the recommended settings! */
- 0xf8, 0x00,
- 0xf9, 0x4b,
- 0xfa, 0x00,
- 0xfb, 0x4b,
- 0xff, 0x88, /* PLL2 lock detection settings: 71 lines 50% phase error */
-
- /* Turn off VBI */
- 0x40, 0x20, /* No framing code errors allowed. */
- 0x41, 0xff,
- 0x42, 0xff,
- 0x43, 0xff,
- 0x44, 0xff,
- 0x45, 0xff,
- 0x46, 0xff,
- 0x47, 0xff,
- 0x48, 0xff,
- 0x49, 0xff,
- 0x4a, 0xff,
- 0x4b, 0xff,
- 0x4c, 0xff,
- 0x4d, 0xff,
- 0x4e, 0xff,
- 0x4f, 0xff,
- 0x50, 0xff,
- 0x51, 0xff,
- 0x52, 0xff,
- 0x53, 0xff,
- 0x54, 0xff,
- 0x55, 0xff,
- 0x56, 0xff,
- 0x57, 0xff,
- 0x58, 0x40,
- 0x59, 0x47,
- 0x5b, 0x83,
- 0x5d, 0xbd,
- 0x5e, 0x35,
-
- 0x02, 0x84, /* input tuner -> input 4, amplifier active */
- 0x09, 0x53, /* 0x53, was 0x56 for 60hz. luminance control */
-
- 0x80, 0x20, /* enable task B */
- 0x88, 0xd0,
- 0x88, 0xf0,
- 0x00, 0x00
-};
-
-/* ============== SAA7715 AUDIO settings ============= */
-
-/* 48.0 kHz */
-static const unsigned char saa7115_cfg_48_audio[] = {
- 0x34, 0xce,
- 0x35, 0xfb,
- 0x36, 0x30,
- 0x00, 0x00
-};
-
-/* 44.1 kHz */
-static const unsigned char saa7115_cfg_441_audio[] = {
- 0x34, 0xf2,
- 0x35, 0x00,
- 0x36, 0x2d,
- 0x00, 0x00
-};
-
-/* 32.0 kHz */
-static const unsigned char saa7115_cfg_32_audio[] = {
- 0x34, 0xdf,
- 0x35, 0xa7,
- 0x36, 0x20,
- 0x00, 0x00
-};
-
-/* 48.0 kHz 60hz */
-static const unsigned char saa7115_cfg_60hz_48_audio[] = {
- 0x30, 0xcd,
- 0x31, 0x20,
- 0x32, 0x03,
- 0x00, 0x00
-};
-
-/* 48.0 kHz 50hz */
-static const unsigned char saa7115_cfg_50hz_48_audio[] = {
- 0x30, 0x00,
- 0x31, 0xc0,
- 0x32, 0x03,
- 0x00, 0x00
-};
-
-/* 44.1 kHz 60hz */
-static const unsigned char saa7115_cfg_60hz_441_audio[] = {
- 0x30, 0xbc,
- 0x31, 0xdf,
- 0x32, 0x02,
- 0x00, 0x00
-};
-
-/* 44.1 kHz 50hz */
-static const unsigned char saa7115_cfg_50hz_441_audio[] = {
- 0x30, 0x00,
- 0x31, 0x72,
- 0x32, 0x03,
- 0x00, 0x00
-};
-
-/* 32.0 kHz 60hz */
-static const unsigned char saa7115_cfg_60hz_32_audio[] = {
- 0x30, 0xde,
- 0x31, 0x15,
- 0x32, 0x02,
- 0x00, 0x00
-};
-
-/* 32.0 kHz 50hz */
-static const unsigned char saa7115_cfg_50hz_32_audio[] = {
- 0x30, 0x00,
- 0x31, 0x80,
- 0x32, 0x02,
- 0x00, 0x00
-};
-
-static int saa7115_odd_parity(u8 c)
-{
- c ^= (c >> 4);
- c ^= (c >> 2);
- c ^= (c >> 1);
-
- return c & 1;
-}
-
-static int saa7115_decode_vps(u8 * dst, u8 * p)
-{
- static const u8 biphase_tbl[] = {
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
- 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
- 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
- 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
- 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
- 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
- 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
- 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
- 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
- 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
- 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
- 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
- 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
- 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
- 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
- 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
- };
- int i;
- u8 c, err = 0;
-
- for (i = 0; i < 2 * 13; i += 2) {
- err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
- c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
- dst[i / 2] = c;
- }
- return err & 0xf0;
-}
-
-static int saa7115_decode_wss(u8 * p)
-{
- static const int wss_bits[8] = {
- 0, 0, 0, 1, 0, 1, 1, 1
- };
- unsigned char parity;
- int wss = 0;
- int i;
-
- for (i = 0; i < 16; i++) {
- int b1 = wss_bits[p[i] & 7];
- int b2 = wss_bits[(p[i] >> 3) & 7];
-
- if (b1 == b2)
- return -1;
- wss |= b2 << i;
- }
- parity = wss & 15;
- parity ^= parity >> 2;
- parity ^= parity >> 1;
-
- if (!(parity & 1))
- return -1;
-
- return wss;
-}
-
-
-static int saa7115_set_audio_clock_freq(struct i2c_client *client, enum v4l2_audio_clock_freq freq)
-{
- struct saa7115_state *state = i2c_get_clientdata(client);
-
- saa7115_dbg("set audio clock freq: %d\n", freq);
- switch (freq) {
- case V4L2_AUDCLK_32_KHZ:
- saa7115_writeregs(client, saa7115_cfg_32_audio);
- if (state->std & V4L2_STD_525_60) {
- saa7115_writeregs(client, saa7115_cfg_60hz_32_audio);
- } else {
- saa7115_writeregs(client, saa7115_cfg_50hz_32_audio);
- }
- break;
- case V4L2_AUDCLK_441_KHZ:
- saa7115_writeregs(client, saa7115_cfg_441_audio);
- if (state->std & V4L2_STD_525_60) {
- saa7115_writeregs(client, saa7115_cfg_60hz_441_audio);
- } else {
- saa7115_writeregs(client, saa7115_cfg_50hz_441_audio);
- }
- break;
- case V4L2_AUDCLK_48_KHZ:
- saa7115_writeregs(client, saa7115_cfg_48_audio);
- if (state->std & V4L2_STD_525_60) {
- saa7115_writeregs(client, saa7115_cfg_60hz_48_audio);
- } else {
- saa7115_writeregs(client, saa7115_cfg_50hz_48_audio);
- }
- break;
- default:
- saa7115_dbg("invalid audio setting %d\n", freq);
- return -EINVAL;
- }
- state->audclk_freq = freq;
- return 0;
-}
-
-static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
-{
- struct saa7115_state *state = i2c_get_clientdata(client);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- if (ctrl->value < 0 || ctrl->value > 255) {
- saa7115_err("invalid brightness setting %d\n", ctrl->value);
- return -ERANGE;
- }
-
- state->bright = ctrl->value;
- saa7115_write(client, 0x0a, state->bright);
- break;
-
- case V4L2_CID_CONTRAST:
- if (ctrl->value < 0 || ctrl->value > 127) {
- saa7115_err("invalid contrast setting %d\n", ctrl->value);
- return -ERANGE;
- }
-
- state->contrast = ctrl->value;
- saa7115_write(client, 0x0b, state->contrast);
- break;
-
- case V4L2_CID_SATURATION:
- if (ctrl->value < 0 || ctrl->value > 127) {
- saa7115_err("invalid saturation setting %d\n", ctrl->value);
- return -ERANGE;
- }
-
- state->sat = ctrl->value;
- saa7115_write(client, 0x0c, state->sat);
- break;
-
- case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
- saa7115_err("invalid hue setting %d\n", ctrl->value);
- return -ERANGE;
- }
-
- state->hue = ctrl->value;
- saa7115_write(client, 0x0d, state->hue);
- break;
- }
-
- return 0;
-}
-
-static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
-{
- struct saa7115_state *state = i2c_get_clientdata(client);
-
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctrl->value = state->bright;
- break;
- case V4L2_CID_CONTRAST:
- ctrl->value = state->contrast;
- break;
- case V4L2_CID_SATURATION:
- ctrl->value = state->sat;
- break;
- case V4L2_CID_HUE:
- ctrl->value = state->hue;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
-{
- struct saa7115_state *state = i2c_get_clientdata(client);
- int taskb = saa7115_read(client, 0x80) & 0x10;
-
- // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
- if (std & V4L2_STD_525_60) {
- saa7115_dbg("decoder set standard 60 Hz\n");
- saa7115_writeregs(client, saa7115_cfg_60hz_video);
- } else {
- saa7115_dbg("decoder set standard 50 Hz\n");
- saa7115_writeregs(client, saa7115_cfg_50hz_video);
- }
-
- state->std = std;
-
- /* restart task B if needed */
- if (taskb && state->ident == V4L2_IDENT_SAA7114) {
- saa7115_writeregs(client, saa7115_cfg_vbi_on);
- }
-
- /* switch audio mode too! */
- saa7115_set_audio_clock_freq(client, state->audclk_freq);
-}
-
-static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client)
-{
- struct saa7115_state *state = i2c_get_clientdata(client);
-
- return state->std;
-}
-
-static void saa7115_log_status(struct i2c_client *client)
-{
- static const char * const audclk_freq_strs[] = {
- "44.1 kHz",
- "48 kHz",
- "32 kHz"
- };
- struct saa7115_state *state = i2c_get_clientdata(client);
- int reg1e, reg1f;
- int signalOk;
- int vcr;
-
- saa7115_info("Audio frequency: %s\n", audclk_freq_strs[state->audclk_freq]);
- if (client->name[6] == '4') {
- /* status for the saa7114 */
- reg1f = saa7115_read(client, 0x1f);
- signalOk = (reg1f & 0xc1) == 0x81;
- saa7115_info("Video signal: %s\n", signalOk ? "ok" : "bad");
- saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz");
- return;
- }
-
- /* status for the saa7115 */
- reg1e = saa7115_read(client, 0x1e);
- reg1f = saa7115_read(client, 0x1f);
-
- signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
- vcr = !(reg1f & 0x10);
-
- saa7115_info("Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
- saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz");
-
- switch (reg1e & 0x03) {
- case 1:
- saa7115_info("Detected format: NTSC\n");
- break;
- case 2:
- saa7115_info("Detected format: PAL\n");
- break;
- case 3:
- saa7115_info("Detected format: SECAM\n");
- break;
- default:
- saa7115_info("Detected format: BW/No color\n");
- break;
- }
-}
-
-/* setup the sliced VBI lcr registers according to the sliced VBI format */
-static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
-{
- struct saa7115_state *state = i2c_get_clientdata(client);
- int is_50hz = (state->std & V4L2_STD_625_50);
- u8 lcr[24];
- int i, x;
-
- /* saa7114 doesn't yet support VBI */
- if (state->ident == V4L2_IDENT_SAA7114)
- return;
-
- for (i = 0; i <= 23; i++)
- lcr[i] = 0xff;
-
- if (fmt->service_set == 0) {
- /* raw VBI */
- if (is_50hz)
- for (i = 6; i <= 23; i++)
- lcr[i] = 0xdd;
- else
- for (i = 10; i <= 21; i++)
- lcr[i] = 0xdd;
- } else {
- /* sliced VBI */
- /* first clear lines that cannot be captured */
- if (is_50hz) {
- for (i = 0; i <= 5; i++)
- fmt->service_lines[0][i] =
- fmt->service_lines[1][i] = 0;
- }
- else {
- for (i = 0; i <= 9; i++)
- fmt->service_lines[0][i] =
- fmt->service_lines[1][i] = 0;
- for (i = 22; i <= 23; i++)
- fmt->service_lines[0][i] =
- fmt->service_lines[1][i] = 0;
- }
-
- /* Now set the lcr values according to the specified service */
- for (i = 6; i <= 23; i++) {
- lcr[i] = 0;
- for (x = 0; x <= 1; x++) {
- switch (fmt->service_lines[1-x][i]) {
- case 0:
- lcr[i] |= 0xf << (4 * x);
- break;
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 5 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 7 << (4 * x);
- break;
- }
- }
- }
- }
-
- /* write the lcr registers */
- for (i = 2; i <= 23; i++) {
- saa7115_write(client, i - 2 + 0x41, lcr[i]);
- }
-
- /* enable/disable raw VBI capturing */
- saa7115_writeregs(client, fmt->service_set == 0 ? saa7115_cfg_vbi_on : saa7115_cfg_vbi_off);
-}
-
-static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
-{
- static u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_CAPTION_525, /* 4 */
- V4L2_SLICED_WSS_625, 0, /* 5 */
- V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */
- 0, 0, 0, 0
- };
- struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced;
- int i;
-
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
- memset(sliced, 0, sizeof(*sliced));
- /* done if using raw VBI */
- if (saa7115_read(client, 0x80) & 0x10)
- return 0;
- for (i = 2; i <= 23; i++) {
- u8 v = saa7115_read(client, i - 2 + 0x41);
-
- sliced->service_lines[0][i] = lcr2vbi[v >> 4];
- sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
- sliced->service_set |=
- sliced->service_lines[0][i] | sliced->service_lines[1][i];
- }
- return 0;
-}
-
-static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
-{
- struct saa7115_state *state = i2c_get_clientdata(client);
- struct v4l2_pix_format *pix;
- int HPSC, HFSC;
- int VSCY, Vsrc;
- int is_50hz = state->std & V4L2_STD_625_50;
-
- if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
- saa7115_set_lcr(client, &fmt->fmt.sliced);
- return 0;
- }
- if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- pix = &(fmt->fmt.pix);
-
- saa7115_dbg("decoder set size\n");
-
- /* FIXME need better bounds checking here */
- if ((pix->width < 1) || (pix->width > 1440))
- return -EINVAL;
- if ((pix->height < 1) || (pix->height > 960))
- return -EINVAL;
-
- /* probably have a valid size, let's set it */
- /* Set output width/height */
- /* width */
- saa7115_write(client, 0xcc, (u8) (pix->width & 0xff));
- saa7115_write(client, 0xcd, (u8) ((pix->width >> 8) & 0xff));
- /* height */
- saa7115_write(client, 0xce, (u8) (pix->height & 0xff));
- saa7115_write(client, 0xcf, (u8) ((pix->height >> 8) & 0xff));
-
- /* Scaling settings */
- /* Hprescaler is floor(inres/outres) */
- /* FIXME hardcoding input res */
- if (pix->width != 720) {
- HPSC = (int)(720 / pix->width);
- /* 0 is not allowed (div. by zero) */
- HPSC = HPSC ? HPSC : 1;
- HFSC = (int)((1024 * 720) / (HPSC * pix->width));
-
- saa7115_dbg("Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
- /* FIXME hardcodes to "Task B"
- * write H prescaler integer */
- saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f));
-
- /* write H fine-scaling (luminance) */
- saa7115_write(client, 0xd8, (u8) (HFSC & 0xff));
- saa7115_write(client, 0xd9, (u8) ((HFSC >> 8) & 0xff));
- /* write H fine-scaling (chrominance)
- * must be lum/2, so i'll just bitshift :) */
- saa7115_write(client, 0xDC, (u8) ((HFSC >> 1) & 0xff));
- saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff));
- } else {
- if (is_50hz) {
- saa7115_dbg("Setting full 50hz width\n");
- saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x);
- } else {
- saa7115_dbg("Setting full 60hz width\n");
- saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
- }
- }
-
- Vsrc = is_50hz ? 576 : 480;
-
- if (pix->height != Vsrc) {
- VSCY = (int)((1024 * Vsrc) / pix->height);
- saa7115_dbg("Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
-
- /* Correct Contrast and Luminance */
- saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY));
- saa7115_write(client, 0xd6, (u8) (64 * 1024 / VSCY));
-
- /* write V fine-scaling (luminance) */
- saa7115_write(client, 0xe0, (u8) (VSCY & 0xff));
- saa7115_write(client, 0xe1, (u8) ((VSCY >> 8) & 0xff));
- /* write V fine-scaling (chrominance) */
- saa7115_write(client, 0xe2, (u8) (VSCY & 0xff));
- saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff));
- } else {
- if (is_50hz) {
- saa7115_dbg("Setting full 50Hz height\n");
- saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y);
- } else {
- saa7115_dbg("Setting full 60hz height\n");
- saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
- }
- }
-
- saa7115_writeregs(client, saa7115_cfg_reset_scaler);
- return 0;
-}
-
-/* Decode the sliced VBI data stream as created by the saa7115.
- The format is described in the saa7115 datasheet in Tables 25 and 26
- and in Figure 33.
- The current implementation uses SAV/EAV codes and not the ancillary data
- headers. The vbi->p pointer points to the SDID byte right after the SAV
- code. */
-static void saa7115_decode_vbi_line(struct i2c_client *client,
- struct v4l2_decode_vbi_line *vbi)
-{
- static const char vbi_no_data_pattern[] = {
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
- };
- struct saa7115_state *state = i2c_get_clientdata(client);
- u8 *p = vbi->p;
- u32 wss;
- int id1, id2; /* the ID1 and ID2 bytes from the internal header */
-
- vbi->type = 0; /* mark result as a failure */
- id1 = p[2];
- id2 = p[3];
- /* Note: the field bit is inverted for 60 Hz video */
- if (state->std & V4L2_STD_525_60)
- id1 ^= 0x40;
-
- /* Skip internal header, p now points to the start of the payload */
- p += 4;
- vbi->p = p;
-
- /* calculate field and line number of the VBI packet (1-23) */
- vbi->is_second_field = ((id1 & 0x40) != 0);
- vbi->line = (id1 & 0x3f) << 3;
- vbi->line |= (id2 & 0x70) >> 4;
-
- /* Obtain data type */
- id2 &= 0xf;
-
- /* If the VBI slicer does not detect any signal it will fill up
- the payload buffer with 0xa0 bytes. */
- if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
- return;
-
- /* decode payloads */
- switch (id2) {
- case 1:
- vbi->type = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1]))
- return;
- vbi->type = V4L2_SLICED_CAPTION_525;
- break;
- case 5:
- wss = saa7115_decode_wss(p);
- if (wss == -1)
- return;
- p[0] = wss & 0xff;
- p[1] = wss >> 8;
- vbi->type = V4L2_SLICED_WSS_625;
- break;
- case 7:
- if (saa7115_decode_vps(p, p) != 0)
- return;
- vbi->type = V4L2_SLICED_VPS;
- break;
- default:
- return;
- }
-}
-
-/* ============ SAA7115 AUDIO settings (end) ============= */
-
-static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- struct saa7115_state *state = i2c_get_clientdata(client);
- int *iarg = arg;
-
- /* ioctls to allow direct access to the saa7115 registers for testing */
- switch (cmd) {
- case VIDIOC_S_FMT:
- return saa7115_set_v4lfmt(client, (struct v4l2_format *)arg);
-
- case VIDIOC_G_FMT:
- return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg);
-
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- return saa7115_set_audio_clock_freq(client, *(enum v4l2_audio_clock_freq *)arg);
-
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *vt = arg;
- int status;
-
- status = saa7115_read(client, 0x1f);
-
- saa7115_dbg("status: 0x%02x\n", status);
- vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
- break;
- }
-
- case VIDIOC_LOG_STATUS:
- saa7115_log_status(client);
- break;
-
- case VIDIOC_G_CTRL:
- return saa7115_get_v4lctrl(client, (struct v4l2_control *)arg);
-
- case VIDIOC_S_CTRL:
- return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg);
-
- case VIDIOC_G_STD:
- *(v4l2_std_id *)arg = saa7115_get_v4lstd(client);
- break;
-
- case VIDIOC_S_STD:
- saa7115_set_v4lstd(client, *(v4l2_std_id *)arg);
- break;
-
- case VIDIOC_G_INPUT:
- *(int *)arg = state->input;
- break;
-
- case VIDIOC_S_INPUT:
- saa7115_dbg("decoder set input %d\n", *iarg);
- /* inputs from 0-9 are available */
- if (*iarg < 0 || *iarg > 9) {
- return -EINVAL;
- }
-
- if (state->input == *iarg)
- break;
- saa7115_dbg("now setting %s input\n",
- *iarg >= 6 ? "S-Video" : "Composite");
- state->input = *iarg;
-
- /* select mode */
- saa7115_write(client, 0x02,
- (saa7115_read(client, 0x02) & 0xf0) |
- state->input);
-
- /* bypass chrominance trap for modes 6..9 */
- saa7115_write(client, 0x09,
- (saa7115_read(client, 0x09) & 0x7f) |
- (state->input < 6 ? 0x0 : 0x80));
- break;
-
- case VIDIOC_STREAMON:
- case VIDIOC_STREAMOFF:
- saa7115_dbg("%s output\n",
- (cmd == VIDIOC_STREAMON) ? "enable" : "disable");
-
- if (state->enable != (cmd == VIDIOC_STREAMON)) {
- state->enable = (cmd == VIDIOC_STREAMON);
- saa7115_write(client, 0x87, state->enable);
- }
- break;
-
- case VIDIOC_INT_DECODE_VBI_LINE:
- saa7115_decode_vbi_line(client, arg);
- break;
-
- case VIDIOC_INT_RESET:
- saa7115_dbg("decoder RESET\n");
- saa7115_writeregs(client, saa7115_cfg_reset_scaler);
- break;
-
- case VIDIOC_INT_G_VBI_DATA:
- {
- struct v4l2_sliced_vbi_data *data = arg;
-
- switch (data->id) {
- case V4L2_SLICED_WSS_625:
- if (saa7115_read(client, 0x6b) & 0xc0)
- return -EIO;
- data->data[0] = saa7115_read(client, 0x6c);
- data->data[1] = saa7115_read(client, 0x6d);
- return 0;
- case V4L2_SLICED_CAPTION_525:
- if (data->field == 0) {
- /* CC */
- if (saa7115_read(client, 0x66) & 0xc0)
- return -EIO;
- data->data[0] = saa7115_read(client, 0x67);
- data->data[1] = saa7115_read(client, 0x68);
- return 0;
- }
- /* XDS */
- if (saa7115_read(client, 0x66) & 0x30)
- return -EIO;
- data->data[0] = saa7115_read(client, 0x69);
- data->data[1] = saa7115_read(client, 0x6a);
- return 0;
- default:
- return -EINVAL;
- }
- break;
- }
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_INT_G_REGISTER:
- {
- struct v4l2_register *reg = arg;
-
- if (reg->i2c_id != I2C_DRIVERID_SAA711X)
- return -EINVAL;
- reg->val = saa7115_read(client, reg->reg & 0xff);
- break;
- }
-
- case VIDIOC_INT_S_REGISTER:
- {
- struct v4l2_register *reg = arg;
-
- if (reg->i2c_id != I2C_DRIVERID_SAA711X)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- saa7115_write(client, reg->reg & 0xff, reg->val & 0xff);
- break;
- }
-#endif
-
- case VIDIOC_INT_G_CHIP_IDENT:
- *iarg = state->ident;
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_driver i2c_driver_saa7115;
-
-static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
-{
- struct i2c_client *client;
- struct saa7115_state *state;
- u8 chip_id;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
-
- client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (client == 0)
- return -ENOMEM;
- memset(client, 0, sizeof(struct i2c_client));
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_saa7115;
- client->flags = I2C_CLIENT_ALLOW_USE;
- snprintf(client->name, sizeof(client->name) - 1, "saa7115");
-
- saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1);
-
- saa7115_write(client, 0, 5);
- chip_id = saa7115_read(client, 0) & 0x0f;
- if (chip_id != 4 && chip_id != 5) {
- saa7115_dbg("saa7115 not found\n");
- kfree(client);
- return 0;
- }
- if (chip_id == 4) {
- snprintf(client->name, sizeof(client->name) - 1, "saa7114");
- }
- saa7115_info("saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name);
-
- state = kmalloc(sizeof(struct saa7115_state), GFP_KERNEL);
- i2c_set_clientdata(client, state);
- if (state == NULL) {
- kfree(client);
- return -ENOMEM;
- }
- memset(state, 0, sizeof(struct saa7115_state));
- state->std = V4L2_STD_NTSC;
- state->input = -1;
- state->enable = 1;
- state->bright = 128;
- state->contrast = 64;
- state->hue = 0;
- state->sat = 64;
- state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115;
- state->audclk_freq = V4L2_AUDCLK_48_KHZ;
-
- saa7115_dbg("writing init values\n");
-
- /* init to 60hz/48khz */
- saa7115_writeregs(client, saa7115_init_auto_input);
- saa7115_writeregs(client, saa7115_init_misc);
- saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
- saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
- saa7115_writeregs(client, saa7115_cfg_60hz_video);
- saa7115_writeregs(client, saa7115_cfg_48_audio);
- saa7115_writeregs(client, saa7115_cfg_60hz_48_audio);
- saa7115_writeregs(client, saa7115_cfg_reset_scaler);
-
- i2c_attach_client(client);
-
- saa7115_dbg("status: (1E) 0x%02x, (1F) 0x%02x\n",
- saa7115_read(client, 0x1e), saa7115_read(client, 0x1f));
-
- return 0;
-}
-
-static int saa7115_probe(struct i2c_adapter *adapter)
-{
-#ifdef I2C_CLASS_TV_ANALOG
- if (adapter->class & I2C_CLASS_TV_ANALOG)
-#else
- if (adapter->id == I2C_HW_B_BT848)
-#endif
- return i2c_probe(adapter, &addr_data, &saa7115_attach);
- return 0;
-}
-
-static int saa7115_detach(struct i2c_client *client)
-{
- struct saa7115_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_saa7115 = {
- .name = "saa7115",
- .id = I2C_DRIVERID_SAA711X,
- .flags = I2C_DF_NOTIFY,
- .attach_adapter = saa7115_probe,
- .detach_client = saa7115_detach,
- .command = saa7115_command,
- .owner = THIS_MODULE,
-};
-
-
-static int __init saa7115_init_module(void)
-{
- return i2c_add_driver(&i2c_driver_saa7115);
-}
-
-static void __exit saa7115_cleanup_module(void)
-{
- i2c_del_driver(&i2c_driver_saa7115);
-}
-
-module_init(saa7115_init_module);
-module_exit(saa7115_cleanup_module);
diff --git a/trunk/drivers/media/video/saa711x.c b/trunk/drivers/media/video/saa711x.c
index 25b30f352d84..9aa8827de2c3 100644
--- a/trunk/drivers/media/video/saa711x.c
+++ b/trunk/drivers/media/video/saa711x.c
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/trunk/drivers/media/video/saa7127.c b/trunk/drivers/media/video/saa7127.c
deleted file mode 100644
index 843431f10e3b..000000000000
--- a/trunk/drivers/media/video/saa7127.c
+++ /dev/null
@@ -1,849 +0,0 @@
-/*
- * saa7127 - Philips SAA7127/SAA7129 video encoder driver
- *
- * Copyright (C) 2003 Roy Bulter
- *
- * Based on SAA7126 video encoder driver by Gillem & Andreas Oberritter
- *
- * Copyright (C) 2000-2001 Gillem
- * Copyright (C) 2002 Andreas Oberritter
- *
- * Based on Stadis 4:2:2 MPEG-2 Decoder Driver by Nathan Laredo
- *
- * Copyright (C) 1999 Nathan Laredo
- *
- * This driver is designed for the Hauppauge 250/350 Linux driver
- * from the ivtv Project
- *
- * Copyright (C) 2003 Kevin Thayer
- *
- * Dual output support:
- * Copyright (C) 2004 Eric Varsanyi
- *
- * NTSC Tuning and 7.5 IRE Setup
- * Copyright (C) 2004 Chris Kennedy
- *
- * VBI additions & cleanup:
- * Copyright (C) 2004, 2005 Hans Verkuil
- *
- * Note: the saa7126 is identical to the saa7127, and the saa7128 is
- * identical to the saa7129, except that the saa7126 and saa7128 have
- * macrovision anti-taping support. This driver will almost certainly
- * work find for those chips, except of course for the missing anti-taping
- * support.
- *
- * 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
-#include
-#include
-#include
-#include
-#include
-
-static int debug = 0;
-static int test_image = 0;
-
-MODULE_DESCRIPTION("Philips SAA7127/9 video encoder driver");
-MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
-MODULE_LICENSE("GPL");
-module_param(debug, int, 0644);
-module_param(test_image, int, 0644);
-MODULE_PARM_DESC(debug, "debug level (0-2)");
-MODULE_PARM_DESC(test_image, "test_image (0-1)");
-
-#define saa7127_dbg(fmt, arg...) \
- do { \
- if (debug >= 1) \
- printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
- i2c_adapter_id(client->adapter), client->addr , ## arg); \
- } while (0)
-
-/* High volume debug. Use with care. */
-#define saa7127_dbg_highvol(fmt, arg...) \
- do { \
- if (debug == 2) \
- printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
- i2c_adapter_id(client->adapter), client->addr , ## arg); \
- } while (0)
-
-#define saa7127_err(fmt, arg...) do { \
- printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
- i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-#define saa7127_info(fmt, arg...) do { \
- printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
- i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
-
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-
-
-I2C_CLIENT_INSMOD;
-
-/*
- * SAA7127 registers
- */
-
-#define SAA7127_REG_STATUS 0x00
-#define SAA7127_REG_WIDESCREEN_CONFIG 0x26
-#define SAA7127_REG_WIDESCREEN_ENABLE 0x27
-#define SAA7127_REG_BURST_START 0x28
-#define SAA7127_REG_BURST_END 0x29
-#define SAA7127_REG_COPYGEN_0 0x2a
-#define SAA7127_REG_COPYGEN_1 0x2b
-#define SAA7127_REG_COPYGEN_2 0x2c
-#define SAA7127_REG_OUTPUT_PORT_CONTROL 0x2d
-#define SAA7127_REG_GAIN_LUMINANCE_RGB 0x38
-#define SAA7127_REG_GAIN_COLORDIFF_RGB 0x39
-#define SAA7127_REG_INPUT_PORT_CONTROL_1 0x3a
-#define SAA7129_REG_FADE_KEY_COL2 0x4f
-#define SAA7127_REG_CHROMA_PHASE 0x5a
-#define SAA7127_REG_GAINU 0x5b
-#define SAA7127_REG_GAINV 0x5c
-#define SAA7127_REG_BLACK_LEVEL 0x5d
-#define SAA7127_REG_BLANKING_LEVEL 0x5e
-#define SAA7127_REG_VBI_BLANKING 0x5f
-#define SAA7127_REG_DAC_CONTROL 0x61
-#define SAA7127_REG_BURST_AMP 0x62
-#define SAA7127_REG_SUBC3 0x63
-#define SAA7127_REG_SUBC2 0x64
-#define SAA7127_REG_SUBC1 0x65
-#define SAA7127_REG_SUBC0 0x66
-#define SAA7127_REG_LINE_21_ODD_0 0x67
-#define SAA7127_REG_LINE_21_ODD_1 0x68
-#define SAA7127_REG_LINE_21_EVEN_0 0x69
-#define SAA7127_REG_LINE_21_EVEN_1 0x6a
-#define SAA7127_REG_RCV_PORT_CONTROL 0x6b
-#define SAA7127_REG_VTRIG 0x6c
-#define SAA7127_REG_HTRIG_HI 0x6d
-#define SAA7127_REG_MULTI 0x6e
-#define SAA7127_REG_CLOSED_CAPTION 0x6f
-#define SAA7127_REG_RCV2_OUTPUT_START 0x70
-#define SAA7127_REG_RCV2_OUTPUT_END 0x71
-#define SAA7127_REG_RCV2_OUTPUT_MSBS 0x72
-#define SAA7127_REG_TTX_REQUEST_H_START 0x73
-#define SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH 0x74
-#define SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT 0x75
-#define SAA7127_REG_TTX_ODD_REQ_VERT_START 0x76
-#define SAA7127_REG_TTX_ODD_REQ_VERT_END 0x77
-#define SAA7127_REG_TTX_EVEN_REQ_VERT_START 0x78
-#define SAA7127_REG_TTX_EVEN_REQ_VERT_END 0x79
-#define SAA7127_REG_FIRST_ACTIVE 0x7a
-#define SAA7127_REG_LAST_ACTIVE 0x7b
-#define SAA7127_REG_MSB_VERTICAL 0x7c
-#define SAA7127_REG_DISABLE_TTX_LINE_LO_0 0x7e
-#define SAA7127_REG_DISABLE_TTX_LINE_LO_1 0x7f
-
-/*
- **********************************************************************
- *
- * Arrays with configuration parameters for the SAA7127
- *
- **********************************************************************
- */
-
-struct i2c_reg_value {
- unsigned char reg;
- unsigned char value;
-};
-
-static const struct i2c_reg_value saa7129_init_config_extra[] = {
- { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 },
- { SAA7127_REG_VTRIG, 0xfa },
-};
-
-static const struct i2c_reg_value saa7127_init_config_common[] = {
- { SAA7127_REG_WIDESCREEN_CONFIG, 0x0d },
- { SAA7127_REG_WIDESCREEN_ENABLE, 0x00 },
- { SAA7127_REG_COPYGEN_0, 0x77 },
- { SAA7127_REG_COPYGEN_1, 0x41 },
- { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */
- { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x9e },
- { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 },
- { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 },
- { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */
- { SAA7127_REG_LINE_21_ODD_0, 0x77 },
- { SAA7127_REG_LINE_21_ODD_1, 0x41 },
- { SAA7127_REG_LINE_21_EVEN_0, 0x88 },
- { SAA7127_REG_LINE_21_EVEN_1, 0x41 },
- { SAA7127_REG_RCV_PORT_CONTROL, 0x12 },
- { SAA7127_REG_VTRIG, 0xf9 },
- { SAA7127_REG_HTRIG_HI, 0x00 },
- { SAA7127_REG_RCV2_OUTPUT_START, 0x41 },
- { SAA7127_REG_RCV2_OUTPUT_END, 0xc3 },
- { SAA7127_REG_RCV2_OUTPUT_MSBS, 0x00 },
- { SAA7127_REG_TTX_REQUEST_H_START, 0x3e },
- { SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH, 0xb8 },
- { SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT, 0x03 },
- { SAA7127_REG_TTX_ODD_REQ_VERT_START, 0x15 },
- { SAA7127_REG_TTX_ODD_REQ_VERT_END, 0x16 },
- { SAA7127_REG_TTX_EVEN_REQ_VERT_START, 0x15 },
- { SAA7127_REG_TTX_EVEN_REQ_VERT_END, 0x16 },
- { SAA7127_REG_FIRST_ACTIVE, 0x1a },
- { SAA7127_REG_LAST_ACTIVE, 0x01 },
- { SAA7127_REG_MSB_VERTICAL, 0xc0 },
- { SAA7127_REG_DISABLE_TTX_LINE_LO_0, 0x00 },
- { SAA7127_REG_DISABLE_TTX_LINE_LO_1, 0x00 },
- { 0, 0 }
-};
-
-#define SAA7127_60HZ_DAC_CONTROL 0x15
-static const struct i2c_reg_value saa7127_init_config_60hz[] = {
- { SAA7127_REG_BURST_START, 0x19 },
- /* BURST_END is also used as a chip ID in saa7127_detect_client */
- { SAA7127_REG_BURST_END, 0x1d },
- { SAA7127_REG_CHROMA_PHASE, 0xa3 },
- { SAA7127_REG_GAINU, 0x98 },
- { SAA7127_REG_GAINV, 0xd3 },
- { SAA7127_REG_BLACK_LEVEL, 0x39 },
- { SAA7127_REG_BLANKING_LEVEL, 0x2e },
- { SAA7127_REG_VBI_BLANKING, 0x2e },
- { SAA7127_REG_DAC_CONTROL, 0x15 },
- { SAA7127_REG_BURST_AMP, 0x4d },
- { SAA7127_REG_SUBC3, 0x1f },
- { SAA7127_REG_SUBC2, 0x7c },
- { SAA7127_REG_SUBC1, 0xf0 },
- { SAA7127_REG_SUBC0, 0x21 },
- { SAA7127_REG_MULTI, 0x90 },
- { SAA7127_REG_CLOSED_CAPTION, 0x11 },
- { 0, 0 }
-};
-
-#define SAA7127_50HZ_DAC_CONTROL 0x02
-struct i2c_reg_value saa7127_init_config_50hz[] = {
- { SAA7127_REG_BURST_START, 0x21 },
- /* BURST_END is also used as a chip ID in saa7127_detect_client */
- { SAA7127_REG_BURST_END, 0x1d },
- { SAA7127_REG_CHROMA_PHASE, 0x3f },
- { SAA7127_REG_GAINU, 0x7d },
- { SAA7127_REG_GAINV, 0xaf },
- { SAA7127_REG_BLACK_LEVEL, 0x33 },
- { SAA7127_REG_BLANKING_LEVEL, 0x35 },
- { SAA7127_REG_VBI_BLANKING, 0x35 },
- { SAA7127_REG_DAC_CONTROL, 0x02 },
- { SAA7127_REG_BURST_AMP, 0x2f },
- { SAA7127_REG_SUBC3, 0xcb },
- { SAA7127_REG_SUBC2, 0x8a },
- { SAA7127_REG_SUBC1, 0x09 },
- { SAA7127_REG_SUBC0, 0x2a },
- { SAA7127_REG_MULTI, 0xa0 },
- { SAA7127_REG_CLOSED_CAPTION, 0x00 },
- { 0, 0 }
-};
-
-/* Enumeration for the Supported input types */
-enum saa7127_input_type {
- SAA7127_INPUT_TYPE_NORMAL,
- SAA7127_INPUT_TYPE_TEST_IMAGE
-};
-
-/* Enumeration for the Supported Output signal types */
-enum saa7127_output_type {
- SAA7127_OUTPUT_TYPE_BOTH,
- SAA7127_OUTPUT_TYPE_COMPOSITE,
- SAA7127_OUTPUT_TYPE_SVIDEO,
- SAA7127_OUTPUT_TYPE_RGB,
- SAA7127_OUTPUT_TYPE_YUV_C,
- SAA7127_OUTPUT_TYPE_YUV_V
-};
-
-/*
- **********************************************************************
- *
- * Encoder Struct, holds the configuration state of the encoder
- *
- **********************************************************************
- */
-
-struct saa7127_state {
- v4l2_std_id std;
- enum v4l2_chip_ident ident;
- enum saa7127_input_type input_type;
- enum saa7127_output_type output_type;
- int video_enable;
- int wss_enable;
- u16 wss_mode;
- int cc_enable;
- u16 cc_data;
- int xds_enable;
- u16 xds_data;
- int vps_enable;
- u8 vps_data[5];
- u8 reg_2d;
- u8 reg_3a;
- u8 reg_3a_cb; /* colorbar bit */
- u8 reg_61;
-};
-
-static const char * const output_strs[] =
-{
- "S-Video + Composite",
- "Composite",
- "S-Video",
- "RGB",
- "YUV C",
- "YUV V"
-};
-
-static const char * const wss_strs[] = {
- "invalid",
- "letterbox 14:9 center",
- "letterbox 14:9 top",
- "invalid",
- "letterbox 16:9 top",
- "invalid",
- "invalid",
- "16:9 full format anamorphic"
- "4:3 full format",
- "invalid",
- "invalid",
- "letterbox 16:9 center",
- "invalid",
- "letterbox >16:9 center",
- "14:9 full format center",
- "invalid",
-};
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_read(struct i2c_client *client, u8 reg)
-{
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_write(struct i2c_client *client, u8 reg, u8 val)
-{
- int i;
-
- for (i = 0; i < 3; i++) {
- if (i2c_smbus_write_byte_data(client, reg, val) == 0)
- return 0;
- }
- saa7127_err("I2C Write Problem\n");
- return -1;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_write_inittab(struct i2c_client *client,
- const struct i2c_reg_value *regs)
-{
- while (regs->reg != 0) {
- saa7127_write(client, regs->reg, regs->value);
- regs++;
- }
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
-{
- struct saa7127_state *state = i2c_get_clientdata(client);
- int enable = (data->line != 0);
-
- if (enable && (data->field != 0 || data->line != 16))
- return -EINVAL;
- if (state->vps_enable != enable) {
- saa7127_dbg("Turn VPS Signal %s\n", enable ? "on" : "off");
- saa7127_write(client, 0x54, enable << 7);
- state->vps_enable = enable;
- }
- 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];
- saa7127_dbg("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],
- state->vps_data[4]);
- saa7127_write(client, 0x55, state->vps_data[0]);
- saa7127_write(client, 0x56, state->vps_data[1]);
- saa7127_write(client, 0x57, state->vps_data[2]);
- saa7127_write(client, 0x58, state->vps_data[3]);
- saa7127_write(client, 0x59, state->vps_data[4]);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
-{
- struct saa7127_state *state = i2c_get_clientdata(client);
- u16 cc = data->data[0] << 8 | data->data[1];
- int enable = (data->line != 0);
-
- if (enable && (data->field != 0 || data->line != 21))
- return -EINVAL;
- if (state->cc_enable != enable) {
- saa7127_dbg("Turn CC %s\n", enable ? "on" : "off");
- saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
- (enable << 6) | 0x11);
- state->cc_enable = enable;
- }
- if (!enable)
- return 0;
-
- saa7127_dbg_highvol("CC data: %04x\n", cc);
- saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff);
- saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8);
- state->cc_data = cc;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
-{
- struct saa7127_state *state = i2c_get_clientdata(client);
- u16 xds = data->data[1] << 8 | data->data[0];
- int enable = (data->line != 0);
-
- if (enable && (data->field != 1 || data->line != 21))
- return -EINVAL;
- if (state->xds_enable != enable) {
- saa7127_dbg("Turn XDS %s\n", enable ? "on" : "off");
- saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
- (enable << 7) | 0x11);
- state->xds_enable = enable;
- }
- if (!enable)
- return 0;
-
- saa7127_dbg_highvol("XDS data: %04x\n", xds);
- saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff);
- saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8);
- state->xds_data = xds;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
-{
- struct saa7127_state *state = i2c_get_clientdata(client);
- int enable = (data->line != 0);
-
- if (enable && (data->field != 0 || data->line != 23))
- return -EINVAL;
- if (state->wss_enable != enable) {
- saa7127_dbg("Turn WSS %s\n", enable ? "on" : "off");
- saa7127_write(client, 0x27, enable << 7);
- state->wss_enable = enable;
- }
- if (!enable)
- return 0;
-
- saa7127_write(client, 0x26, data->data[0]);
- saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f));
- saa7127_dbg("WSS mode: %s\n", wss_strs[data->data[0] & 0xf]);
- state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0];
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_video_enable(struct i2c_client *client, int enable)
-{
- struct saa7127_state *state = i2c_get_clientdata(client);
-
- if (enable) {
- saa7127_dbg("Enable Video Output\n");
- saa7127_write(client, 0x2d, state->reg_2d);
- saa7127_write(client, 0x61, state->reg_61);
- } else {
- saa7127_dbg("Disable Video Output\n");
- saa7127_write(client, 0x2d, (state->reg_2d & 0xf0));
- saa7127_write(client, 0x61, (state->reg_61 | 0xc0));
- }
- state->video_enable = enable;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std)
-{
- struct saa7127_state *state = i2c_get_clientdata(client);
- const struct i2c_reg_value *inittab;
-
- if (std & V4L2_STD_525_60) {
- saa7127_dbg("Selecting 60 Hz video Standard\n");
- inittab = saa7127_init_config_60hz;
- state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
- } else {
- saa7127_dbg("Selecting 50 Hz video Standard\n");
- inittab = saa7127_init_config_50hz;
- state->reg_61 = SAA7127_50HZ_DAC_CONTROL;
- }
-
- /* Write Table */
- saa7127_write_inittab(client, inittab);
- state->std = std;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_output_type(struct i2c_client *client, int output)
-{
- struct saa7127_state *state = i2c_get_clientdata(client);
-
- switch (output) {
- case SAA7127_OUTPUT_TYPE_RGB:
- state->reg_2d = 0x0f; /* RGB + CVBS (for sync) */
- state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
- break;
-
- case SAA7127_OUTPUT_TYPE_COMPOSITE:
- state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
- state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
- break;
-
- case SAA7127_OUTPUT_TYPE_SVIDEO:
- state->reg_2d = 0xff; /* 11111111 croma -> R, luma -> CVBS + G + B */
- state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
- break;
-
- case SAA7127_OUTPUT_TYPE_YUV_V:
- state->reg_2d = 0x4f; /* reg 2D = 01001111, all DAC's on, RGB + VBS */
- state->reg_3a = 0x0b; /* reg 3A = 00001011, bypass RGB-matrix */
- break;
-
- case SAA7127_OUTPUT_TYPE_YUV_C:
- state->reg_2d = 0x0f; /* reg 2D = 00001111, all DAC's on, RGB + CVBS */
- state->reg_3a = 0x0b; /* reg 3A = 00001011, bypass RGB-matrix */
- break;
-
- case SAA7127_OUTPUT_TYPE_BOTH:
- state->reg_2d = 0xbf;
- state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */
- break;
-
- default:
- return -EINVAL;
- }
- saa7127_dbg("Selecting %s output type\n", output_strs[output]);
-
- /* Configure Encoder */
- saa7127_write(client, 0x2d, state->reg_2d);
- saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
- state->output_type = output;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_set_input_type(struct i2c_client *client, int input)
-{
- struct saa7127_state *state = i2c_get_clientdata(client);
-
- switch (input) {
- case SAA7127_INPUT_TYPE_NORMAL: /* avia */
- saa7127_dbg("Selecting Normal Encoder Input\n");
- state->reg_3a_cb = 0;
- break;
-
- case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */
- saa7127_dbg("Selecting Color Bar generator\n");
- state->reg_3a_cb = 0x80;
- break;
-
- default:
- return -EINVAL;
- }
- saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
- state->input_type = input;
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_command(struct i2c_client *client,
- unsigned int cmd, void *arg)
-{
- struct saa7127_state *state = i2c_get_clientdata(client);
- struct v4l2_format *fmt = arg;
- int *iarg = arg;
-
- switch (cmd) {
- case VIDIOC_S_STD:
- if (state->std == *(v4l2_std_id *)arg)
- break;
- return saa7127_set_std(client, *(v4l2_std_id *)arg);
-
- case VIDIOC_G_STD:
- *(v4l2_std_id *)arg = state->std;
- break;
-
- case VIDIOC_S_INPUT:
- if (state->input_type == *iarg)
- break;
- return saa7127_set_input_type(client, *iarg);
-
- case VIDIOC_S_OUTPUT:
- if (state->output_type == *iarg)
- break;
- return saa7127_set_output_type(client, *iarg);
-
- case VIDIOC_STREAMON:
- case VIDIOC_STREAMOFF:
- if (state->video_enable == (cmd == VIDIOC_STREAMON))
- break;
- return saa7127_set_video_enable(client, cmd == VIDIOC_STREAMON);
-
- case VIDIOC_G_FMT:
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
-
- memset(&fmt->fmt.sliced, 0, sizeof(fmt->fmt.sliced));
- if (state->vps_enable)
- fmt->fmt.sliced.service_lines[0][16] = V4L2_SLICED_VPS;
- if (state->wss_enable)
- fmt->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
- if (state->cc_enable) {
- fmt->fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525;
- fmt->fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525;
- }
- fmt->fmt.sliced.service_set =
- (state->vps_enable ? V4L2_SLICED_VPS : 0) |
- (state->wss_enable ? V4L2_SLICED_WSS_625 : 0) |
- (state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0);
- break;
-
- case VIDIOC_LOG_STATUS:
- saa7127_info("Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz");
- saa7127_info("Input: %s\n", state->input_type ? "color bars" : "normal");
- saa7127_info("Output: %s\n", state->video_enable ?
- output_strs[state->output_type] : "disabled");
- saa7127_info("WSS: %s\n", state->wss_enable ?
- wss_strs[state->wss_mode] : "disabled");
- saa7127_info("VPS: %s\n", state->vps_enable ? "enabled" : "disabled");
- saa7127_info("CC: %s\n", state->cc_enable ? "enabled" : "disabled");
- break;
-
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_INT_G_REGISTER:
- {
- struct v4l2_register *reg = arg;
-
- if (reg->i2c_id != I2C_DRIVERID_SAA7127)
- return -EINVAL;
- reg->val = saa7127_read(client, reg->reg & 0xff);
- break;
- }
-
- case VIDIOC_INT_S_REGISTER:
- {
- struct v4l2_register *reg = arg;
-
- if (reg->i2c_id != I2C_DRIVERID_SAA7127)
- return -EINVAL;
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
- break;
- }
-#endif
-
- case VIDIOC_INT_S_VBI_DATA:
- {
- struct v4l2_sliced_vbi_data *data = arg;
-
- switch (data->id) {
- case V4L2_SLICED_WSS_625:
- return saa7127_set_wss(client, data);
- case V4L2_SLICED_VPS:
- return saa7127_set_vps(client, data);
- case V4L2_SLICED_CAPTION_525:
- if (data->field == 0)
- return saa7127_set_cc(client, data);
- return saa7127_set_xds(client, data);
- default:
- return -EINVAL;
- }
- break;
- }
-
- case VIDIOC_INT_G_CHIP_IDENT:
- *(enum v4l2_chip_ident *)arg = state->ident;
- break;
-
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-struct i2c_driver i2c_driver_saa7127;
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind)
-{
- struct i2c_client *client;
- struct saa7127_state *state;
- struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */
- int read_result = 0;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
-
- client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (client == 0)
- return -ENOMEM;
-
- memset(client, 0, sizeof(struct i2c_client));
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_saa7127;
- client->flags = I2C_CLIENT_ALLOW_USE;
- snprintf(client->name, sizeof(client->name) - 1, "saa7127");
-
- saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1);
-
- /* First test register 0: Bits 5-7 are a version ID (should be 0),
- and bit 2 should also be 0.
- This is rather general, so the second test is more specific and
- looks at the 'ending point of burst in clock cycles' which is
- 0x1d after a reset and not expected to ever change. */
- if ((saa7127_read(client, 0) & 0xe4) != 0 ||
- (saa7127_read(client, 0x29) & 0x3f) != 0x1d) {
- saa7127_dbg("saa7127 not found\n");
- kfree(client);
- return 0;
- }
- state = kmalloc(sizeof(struct saa7127_state), GFP_KERNEL);
-
- if (state == NULL) {
- kfree(client);
- return (-ENOMEM);
- }
-
- i2c_set_clientdata(client, state);
- memset(state, 0, sizeof(struct saa7127_state));
-
- /* Configure Encoder */
-
- saa7127_dbg("Configuring encoder\n");
- saa7127_write_inittab(client, saa7127_init_config_common);
- saa7127_set_std(client, V4L2_STD_NTSC);
- saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH);
- saa7127_set_vps(client, &vbi);
- saa7127_set_wss(client, &vbi);
- saa7127_set_cc(client, &vbi);
- saa7127_set_xds(client, &vbi);
- if (test_image == 1) {
- /* The Encoder has an internal Colorbar generator */
- /* This can be used for debugging */
- saa7127_set_input_type(client, SAA7127_INPUT_TYPE_TEST_IMAGE);
- } else {
- saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL);
- }
- saa7127_set_video_enable(client, 1);
-
- /* Detect if it's an saa7129 */
- read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2);
- saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa);
- if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
- saa7127_info("saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name);
- saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result);
- saa7127_write_inittab(client, saa7129_init_config_extra);
- state->ident = V4L2_IDENT_SAA7129;
- } else {
- saa7127_info("saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name);
- state->ident = V4L2_IDENT_SAA7127;
- }
-
- i2c_attach_client(client);
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_probe(struct i2c_adapter *adapter)
-{
-#ifdef I2C_CLASS_TV_ANALOG
- if (adapter->class & I2C_CLASS_TV_ANALOG)
-#else
- if (adapter->id == I2C_HW_B_BT848)
-#endif
- return i2c_probe(adapter, &addr_data, saa7127_attach);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static int saa7127_detach(struct i2c_client *client)
-{
- struct saa7127_state *state = i2c_get_clientdata(client);
- int err;
-
- /* Turn off TV output */
- saa7127_set_video_enable(client, 0);
-
- err = i2c_detach_client(client);
-
- if (err) {
- return err;
- }
-
- kfree(state);
- kfree(client);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-struct i2c_driver i2c_driver_saa7127 = {
- .name = "saa7127",
- .id = I2C_DRIVERID_SAA7127,
- .flags = I2C_DF_NOTIFY,
- .attach_adapter = saa7127_probe,
- .detach_client = saa7127_detach,
- .command = saa7127_command,
- .owner = THIS_MODULE,
-};
-
-
-/* ----------------------------------------------------------------------- */
-
-static int __init saa7127_init_module(void)
-{
- return i2c_add_driver(&i2c_driver_saa7127);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static void __exit saa7127_cleanup_module(void)
-{
- i2c_del_driver(&i2c_driver_saa7127);
-}
-
-/* ----------------------------------------------------------------------- */
-
-module_init(saa7127_init_module);
-module_exit(saa7127_cleanup_module);
diff --git a/trunk/drivers/media/video/saa7134/Kconfig b/trunk/drivers/media/video/saa7134/Kconfig
index 7bdeabe638ca..624e8808a517 100644
--- a/trunk/drivers/media/video/saa7134/Kconfig
+++ b/trunk/drivers/media/video/saa7134/Kconfig
@@ -1,11 +1,10 @@
config VIDEO_SAA7134
tristate "Philips SAA7134 support"
- depends on VIDEO_DEV && PCI && I2C && SOUND && SND
+ depends on VIDEO_DEV && PCI && I2C && SOUND
select VIDEO_BUF
select VIDEO_IR
select VIDEO_TUNER
select CRC32
- select SND_PCM_OSS
---help---
This is a video4linux driver for Philips SAA713x based
TV cards.
diff --git a/trunk/drivers/media/video/saa7134/Makefile b/trunk/drivers/media/video/saa7134/Makefile
index 4226b61cc613..e0b28f0533af 100644
--- a/trunk/drivers/media/video/saa7134/Makefile
+++ b/trunk/drivers/media/video/saa7134/Makefile
@@ -1,11 +1,10 @@
saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \
- saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o \
- saa7134-video.o saa7134-input.o
+ saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \
+ saa7134-vbi.o saa7134-video.o saa7134-input.o
obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \
- saa6752hs.o saa7134-alsa.o \
- saa7134-oss.o
+ saa6752hs.o saa7134-alsa.o
obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
EXTRA_CFLAGS += -I$(src)/..
diff --git a/trunk/drivers/media/video/saa7134/saa7134-alsa.c b/trunk/drivers/media/video/saa7134/saa7134-alsa.c
index 5707c666660b..4f3c42354329 100644
--- a/trunk/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/trunk/drivers/media/video/saa7134/saa7134-alsa.c
@@ -30,9 +30,7 @@
#include
#include
#include
-#include
#include
-#include
#include "saa7134.h"
#include "saa7134-reg.h"
@@ -58,8 +56,6 @@ static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
-int position;
-
#define dprintk(fmt, arg...) if (debug) \
printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
@@ -72,7 +68,7 @@ typedef struct snd_card_saa7134 {
int mixer_volume[MIXER_ADDR_LAST+1][2];
int capture_source[MIXER_ADDR_LAST+1][2];
struct pci_dev *pci;
- struct saa7134_dev *dev;
+ struct saa7134_dev *saadev;
unsigned long iobase;
int irq;
@@ -87,10 +83,12 @@ typedef struct snd_card_saa7134 {
*/
typedef struct snd_card_saa7134_pcm {
- struct saa7134_dev *dev;
+ struct saa7134_dev *saadev;
spinlock_t lock;
-
+ unsigned int pcm_size; /* buffer size */
+ unsigned int pcm_count; /* bytes per period */
+ unsigned int pcm_bps; /* bytes per second */
snd_pcm_substream_t *substream;
} snd_card_saa7134_pcm_t;
@@ -102,11 +100,13 @@ static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
*
* Called when the capture device is released or the buffer overflows
*
- * - Copied verbatim from saa7134-oss's dsp_dma_stop.
+ * - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped
+ * if we just share dsp_dma_stop and use it here
*
*/
static void saa7134_dma_stop(struct saa7134_dev *dev)
+
{
dev->dmasound.dma_blk = -1;
dev->dmasound.dma_running = 0;
@@ -118,7 +118,8 @@ static void saa7134_dma_stop(struct saa7134_dev *dev)
*
* Called when preparing the capture device for use
*
- * - Copied verbatim from saa7134-oss's dsp_dma_start.
+ * - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped
+ * if we just share dsp_dma_start and use it here
*
*/
@@ -169,9 +170,9 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
dev->dmasound.bufsize, dev->dmasound.blocks);
- spin_unlock(&dev->slock);
snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
- return;
+ saa7134_dma_stop(dev);
+ goto done;
}
/* next block addr */
@@ -193,7 +194,6 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
snd_pcm_period_elapsed(dev->dmasound.substream);
spin_lock(&dev->slock);
}
-
done:
spin_unlock(&dev->slock);
@@ -209,9 +209,7 @@ void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
{
- struct saa7134_dmasound *dmasound = dev_id;
- struct saa7134_dev *dev = dmasound->priv_data;
-
+ struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
unsigned long report, status;
int loop, handled = 0;
@@ -250,23 +248,56 @@ static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
int cmd)
{
snd_pcm_runtime_t *runtime = substream->runtime;
- snd_card_saa7134_pcm_t *pcm = runtime->private_data;
- struct saa7134_dev *dev=pcm->dev;
+ snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
+ struct saa7134_dev *dev=saapcm->saadev;
int err = 0;
- spin_lock(&dev->slock);
- if (cmd == SNDRV_PCM_TRIGGER_START) {
+ spin_lock_irq(&dev->slock);
+ if (cmd == SNDRV_PCM_TRIGGER_START) {
/* start dma */
saa7134_dma_start(dev);
- } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
+ } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
/* stop dma */
saa7134_dma_stop(dev);
- } else {
- err = -EINVAL;
- }
- spin_unlock(&dev->slock);
+ } else {
+ err = -EINVAL;
+ }
+ spin_unlock_irq(&dev->slock);
- return err;
+ return err;
+}
+
+/*
+ * DMA buffer config
+ *
+ * Sets the values that will later be used as the size of the buffer,
+ * size of the fragments, and total number of fragments.
+ * Must be called during the preparation stage, before memory is
+ * allocated
+ *
+ * - Copied verbatim from saa7134-oss. Can be dropped
+ * if we just share dsp_buffer_conf from OSS.
+ */
+
+static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
+{
+ if (blksize < 0x100)
+ blksize = 0x100;
+ if (blksize > 0x10000)
+ blksize = 0x10000;
+
+ if (blocks < 2)
+ blocks = 2;
+ if ((blksize * blocks) > 1024*1024)
+ blocks = 1024*1024 / blksize;
+
+ dev->dmasound.blocks = blocks;
+ dev->dmasound.blksize = blksize;
+ dev->dmasound.bufsize = blksize * blocks;
+
+ dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
+ blocks,blksize,blksize * blocks / 1024);
+ return 0;
}
/*
@@ -276,16 +307,16 @@ static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
* ALSA, but I was unable to use ALSA's own DMA, and had to force the
* usage of V4L's
*
- * - Copied verbatim from saa7134-oss.
- *
+ * - Copied verbatim from saa7134-oss. Can be dropped
+ * if we just share dsp_buffer_init from OSS.
*/
static int dsp_buffer_init(struct saa7134_dev *dev)
{
int err;
- BUG_ON(!dev->dmasound.bufsize);
-
+ if (!dev->dmasound.bufsize)
+ BUG();
videobuf_dma_init(&dev->dmasound.dma);
err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
(dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
@@ -294,28 +325,6 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
return 0;
}
-/*
- * DMA buffer release
- *
- * Called after closing the device, during snd_card_saa7134_capture_close
- *
- */
-
-static int dsp_buffer_free(struct saa7134_dev *dev)
-{
- if (!dev->dmasound.blksize)
- BUG();
-
- videobuf_dma_free(&dev->dmasound.dma);
-
- dev->dmasound.blocks = 0;
- dev->dmasound.blksize = 0;
- dev->dmasound.bufsize = 0;
-
- return 0;
-}
-
-
/*
* ALSA PCM preparation
*
@@ -331,30 +340,84 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
- int bswap, sign;
+ int err, bswap, sign;
u32 fmt, control;
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
struct saa7134_dev *dev;
- snd_card_saa7134_pcm_t *pcm = runtime->private_data;
+ snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
+ unsigned int bps;
+ unsigned long size;
+ unsigned count;
+
+ size = snd_pcm_lib_buffer_bytes(substream);
+ count = snd_pcm_lib_period_bytes(substream);
+
+ saapcm->saadev->dmasound.substream = substream;
+ bps = runtime->rate * runtime->channels;
+ bps *= snd_pcm_format_width(runtime->format);
+ bps /= 8;
+ if (bps <= 0)
+ return -EINVAL;
+ saapcm->pcm_bps = bps;
+ saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream);
+ saapcm->pcm_count = snd_pcm_lib_period_bytes(substream);
+
- pcm->dev->dmasound.substream = substream;
+ dev=saa7134->saadev;
- dev = saa7134->dev;
+ dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count));
- if (snd_pcm_format_width(runtime->format) == 8)
+ err = dsp_buffer_init(dev);
+ if (0 != err)
+ goto fail2;
+
+ /* prepare buffer */
+ if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
+ return err;
+ if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
+ goto fail1;
+ if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
+ dev->dmasound.dma.sglist,
+ dev->dmasound.dma.sglen,
+ 0)))
+ goto fail2;
+
+
+
+ switch (runtime->format) {
+ case SNDRV_PCM_FORMAT_U8:
+ case SNDRV_PCM_FORMAT_S8:
fmt = 0x00;
- else
+ break;
+ case SNDRV_PCM_FORMAT_U16_LE:
+ case SNDRV_PCM_FORMAT_U16_BE:
+ case SNDRV_PCM_FORMAT_S16_LE:
+ case SNDRV_PCM_FORMAT_S16_BE:
fmt = 0x01;
+ break;
+ default:
+ err = -EINVAL;
+ return 1;
+ }
- if (snd_pcm_format_signed(runtime->format))
+ switch (runtime->format) {
+ case SNDRV_PCM_FORMAT_S8:
+ case SNDRV_PCM_FORMAT_S16_LE:
+ case SNDRV_PCM_FORMAT_S16_BE:
sign = 1;
- else
+ break;
+ default:
sign = 0;
+ break;
+ }
- if (snd_pcm_format_big_endian(runtime->format))
- bswap = 1;
- else
- bswap = 0;
+ switch (runtime->format) {
+ case SNDRV_PCM_FORMAT_U16_BE:
+ case SNDRV_PCM_FORMAT_S16_BE:
+ bswap = 1; break;
+ default:
+ bswap = 0; break;
+ }
switch (dev->pci->device) {
case PCI_DEVICE_ID_PHILIPS_SAA7134:
@@ -382,6 +445,7 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
fmt |= 0x04;
saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1);
saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
+ //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210);
break;
}
@@ -395,6 +459,12 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
if (bswap)
control |= SAA7134_RS_CONTROL_BSWAP;
+ /* I should be able to use runtime->dma_addr in the control
+ byte, but it doesn't work. So I allocate the DMA using the
+ V4L functions, and force ALSA to use that as the DMA area */
+
+ runtime->dma_area = dev->dmasound.dma.vmalloc;
+
saa_writel(SAA7134_RS_BA1(6),0);
saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
saa_writel(SAA7134_RS_PITCH(6),0);
@@ -403,6 +473,12 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
dev->dmasound.rate = runtime->rate;
return 0;
+ fail2:
+ saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
+ fail1:
+ videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
+ return err;
+
}
@@ -420,8 +496,10 @@ static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
- snd_card_saa7134_pcm_t *pcm = runtime->private_data;
- struct saa7134_dev *dev=pcm->dev;
+ snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
+ struct saa7134_dev *dev=saapcm->saadev;
+
+
if (dev->dmasound.read_count) {
dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream);
@@ -462,9 +540,9 @@ static snd_pcm_hardware_t snd_card_saa7134_capture =
static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
{
- snd_card_saa7134_pcm_t *pcm = runtime->private_data;
+ snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
- kfree(pcm);
+ kfree(saapcm);
}
@@ -474,76 +552,17 @@ static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
* - One of the ALSA capture callbacks.
*
* Called on initialization, right before the PCM preparation
+ * Usually used in ALSA to allocate the DMA, but since we don't use the
+ * ALSA DMA it does nothing
*
*/
static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
snd_pcm_hw_params_t * hw_params)
{
- snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
- struct saa7134_dev *dev;
- unsigned int period_size, periods;
- int err;
-
- period_size = params_period_bytes(hw_params);
- periods = params_periods(hw_params);
-
- snd_assert(period_size >= 0x100 && period_size <= 0x10000,
- return -EINVAL);
- snd_assert(periods >= 2, return -EINVAL);
- snd_assert(period_size * periods <= 1024 * 1024, return -EINVAL);
- dev = saa7134->dev;
-
- if (dev->dmasound.blocks == periods &&
- dev->dmasound.blksize == period_size)
- return 0;
-
- /* release the old buffer */
- if (substream->runtime->dma_area) {
- saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
- dsp_buffer_free(dev);
- substream->runtime->dma_area = NULL;
- }
- dev->dmasound.blocks = periods;
- dev->dmasound.blksize = period_size;
- dev->dmasound.bufsize = period_size * periods;
-
- err = dsp_buffer_init(dev);
- if (0 != err) {
- dev->dmasound.blocks = 0;
- dev->dmasound.blksize = 0;
- dev->dmasound.bufsize = 0;
- return err;
- }
-
- if (0 != (err = videobuf_dma_pci_map(dev->pci, &dev->dmasound.dma))) {
- dsp_buffer_free(dev);
- return err;
- }
- if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) {
- videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
- dsp_buffer_free(dev);
- return err;
- }
- if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
- dev->dmasound.dma.sglist,
- dev->dmasound.dma.sglen,
- 0))) {
- saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
- dsp_buffer_free(dev);
- return err;
- }
-
- /* I should be able to use runtime->dma_addr in the control
- byte, but it doesn't work. So I allocate the DMA using the
- V4L functions, and force ALSA to use that as the DMA area */
-
- substream->runtime->dma_area = dev->dmasound.dma.vmalloc;
+ return 0;
- return 1;
}
@@ -553,23 +572,33 @@ static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
* - One of the ALSA capture callbacks.
*
* Called after closing the device, but before snd_card_saa7134_capture_close
- * It stops the DMA audio and releases the buffers.
+ * Usually used in ALSA to free the DMA, but since we don't use the
+ * ALSA DMA I'm almost sure this isn't necessary.
*
*/
static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
{
- snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
- struct saa7134_dev *dev;
+ return 0;
+}
- dev = saa7134->dev;
+/*
+ * DMA buffer release
+ *
+ * Called after closing the device, during snd_card_saa7134_capture_close
+ *
+ */
- if (substream->runtime->dma_area) {
- saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
- dsp_buffer_free(dev);
- substream->runtime->dma_area = NULL;
- }
+static int dsp_buffer_free(struct saa7134_dev *dev)
+{
+ if (!dev->dmasound.blksize)
+ BUG();
+
+ videobuf_dma_free(&dev->dmasound.dma);
+
+ dev->dmasound.blocks = 0;
+ dev->dmasound.blksize = 0;
+ dev->dmasound.bufsize = 0;
return 0;
}
@@ -579,12 +608,21 @@ static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
*
* - One of the ALSA capture callbacks.
*
- * Called after closing the device.
+ * Called after closing the device. It stops the DMA audio and releases
+ * the buffers
*
*/
static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
{
+ snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream);
+ struct saa7134_dev *dev = chip->saadev;
+
+ /* unlock buffer */
+ saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
+ videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
+
+ dsp_buffer_free(dev);
return 0;
}
@@ -601,28 +639,29 @@ static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
- snd_card_saa7134_pcm_t *pcm;
+ snd_card_saa7134_pcm_t *saapcm;
snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
- struct saa7134_dev *dev = saa7134->dev;
+ struct saa7134_dev *dev = saa7134->saadev;
int err;
down(&dev->dmasound.lock);
+ dev->dmasound.afmt = SNDRV_PCM_FORMAT_U8;
+ dev->dmasound.channels = 2;
dev->dmasound.read_count = 0;
dev->dmasound.read_offset = 0;
up(&dev->dmasound.lock);
- pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
- if (pcm == NULL)
+ saapcm = kzalloc(sizeof(*saapcm), GFP_KERNEL);
+ if (saapcm == NULL)
return -ENOMEM;
+ saapcm->saadev=saa7134->saadev;
- pcm->dev=saa7134->dev;
+ spin_lock_init(&saapcm->lock);
- spin_lock_init(&pcm->lock);
-
- pcm->substream = substream;
- runtime->private_data = pcm;
+ saapcm->substream = substream;
+ runtime->private_data = saapcm;
runtime->private_free = snd_card_saa7134_runtime_free;
runtime->hw = snd_card_saa7134_capture;
@@ -697,6 +736,7 @@ static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
+ unsigned long flags;
int change, addr = kcontrol->private_value;
int left, right;
@@ -710,12 +750,12 @@ static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_
right = 0;
if (right > 20)
right = 20;
- spin_lock_irq(&chip->mixer_lock);
+ spin_lock_irqsave(&chip->mixer_lock, flags);
change = chip->mixer_volume[addr][0] != left ||
chip->mixer_volume[addr][1] != right;
chip->mixer_volume[addr][0] = left;
chip->mixer_volume[addr][1] = right;
- spin_unlock_irq(&chip->mixer_lock);
+ spin_unlock_irqrestore(&chip->mixer_lock, flags);
return change;
}
@@ -737,37 +777,38 @@ static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_
static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
+ unsigned long flags;
int addr = kcontrol->private_value;
- spin_lock_irq(&chip->mixer_lock);
+ spin_lock_irqsave(&chip->mixer_lock, flags);
ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
- spin_unlock_irq(&chip->mixer_lock);
-
+ spin_unlock_irqrestore(&chip->mixer_lock, flags);
return 0;
}
static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
+ unsigned long flags;
int change, addr = kcontrol->private_value;
int left, right;
u32 anabar, xbarin;
int analog_io, rate;
struct saa7134_dev *dev;
- dev = chip->dev;
+ dev = chip->saadev;
left = ucontrol->value.integer.value[0] & 1;
right = ucontrol->value.integer.value[1] & 1;
- spin_lock_irq(&chip->mixer_lock);
+ spin_lock_irqsave(&chip->mixer_lock, flags);
change = chip->capture_source[addr][0] != left ||
chip->capture_source[addr][1] != right;
chip->capture_source[addr][0] = left;
chip->capture_source[addr][1] = right;
dev->dmasound.input=addr;
- spin_unlock_irq(&chip->mixer_lock);
+ spin_unlock_irqrestore(&chip->mixer_lock, flags);
if (change) {
@@ -857,44 +898,43 @@ static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
return 0;
}
-static void snd_saa7134_free(snd_card_t * card)
+static int snd_saa7134_free(snd_card_saa7134_t *chip)
{
- snd_card_saa7134_t *chip = card->private_data;
-
- if (chip->dev->dmasound.priv_data == NULL)
- return;
-
- if (chip->irq >= 0) {
- synchronize_irq(chip->irq);
- free_irq(chip->irq, &chip->dev->dmasound);
- }
-
- chip->dev->dmasound.priv_data = NULL;
+ return 0;
+}
+static int snd_saa7134_dev_free(snd_device_t *device)
+{
+ snd_card_saa7134_t *chip = device->device_data;
+ return snd_saa7134_free(chip);
}
/*
* ALSA initialization
*
- * Called by the init routine, once for each saa7134 device present,
- * it creates the basic structures and registers the ALSA devices
+ * Called by saa7134-core, it creates the basic structures and registers
+ * the ALSA devices
*
*/
-int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
+int alsa_card_saa7134_create (struct saa7134_dev *saadev)
{
+ static int dev;
snd_card_t *card;
snd_card_saa7134_t *chip;
int err;
+ static snd_device_ops_t ops = {
+ .dev_free = snd_saa7134_dev_free,
+ };
- if (devnum >= SNDRV_CARDS)
+ if (dev >= SNDRV_CARDS)
return -ENODEV;
- if (!enable[devnum])
+ if (!enable[dev])
return -ENODEV;
- card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t));
+ card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL)
return -ENOMEM;
@@ -903,33 +943,34 @@ int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
/* Card "creation" */
- card->private_free = snd_saa7134_free;
- chip = (snd_card_saa7134_t *) card->private_data;
+ chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
+ if (chip == NULL) {
+ return -ENOMEM;
+ }
spin_lock_init(&chip->lock);
spin_lock_init(&chip->mixer_lock);
- chip->dev = dev;
+ chip->saadev = saadev;
chip->card = card;
- chip->pci = dev->pci;
- chip->iobase = pci_resource_start(dev->pci, 0);
+ chip->pci = saadev->pci;
+ chip->irq = saadev->pci->irq;
+ chip->iobase = pci_resource_start(saadev->pci, 0);
-
- err = request_irq(dev->pci->irq, saa7134_alsa_irq,
- SA_SHIRQ | SA_INTERRUPT, dev->name,
- (void*) &dev->dmasound);
+ err = request_irq(saadev->pci->irq, saa7134_alsa_irq,
+ SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev);
if (err < 0) {
printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n",
- dev->name, dev->pci->irq);
+ saadev->name, saadev->pci->irq);
goto __nodev;
}
- chip->irq = dev->pci->irq;
-
- init_MUTEX(&dev->dmasound.lock);
+ if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+ goto __nodev;
+ }
if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
goto __nodev;
@@ -943,15 +984,16 @@ int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
strcpy(card->shortname, "SAA7134");
sprintf(card->longname, "%s at 0x%lx irq %d",
- chip->dev->name, chip->iobase, chip->irq);
+ chip->saadev->name, chip->iobase, chip->irq);
if ((err = snd_card_register(card)) == 0) {
- snd_saa7134_cards[devnum] = card;
+ snd_saa7134_cards[dev] = card;
return 0;
}
__nodev:
snd_card_free(card);
+ kfree(chip);
return err;
}
@@ -965,29 +1007,21 @@ int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
static int saa7134_alsa_init(void)
{
- struct saa7134_dev *dev = NULL;
- struct list_head *list;
+ struct saa7134_dev *saadev = NULL;
+ struct list_head *list;
- position = 0;
+ printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
- printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
+ list_for_each(list,&saa7134_devlist) {
+ saadev = list_entry(list, struct saa7134_dev, devlist);
+ alsa_card_saa7134_create(saadev);
+ }
- list_for_each(list,&saa7134_devlist) {
- dev = list_entry(list, struct saa7134_dev, devlist);
- if (dev->dmasound.priv_data == NULL) {
- dev->dmasound.priv_data = dev;
- alsa_card_saa7134_create(dev,position);
- position++;
- } else {
- printk(KERN_ERR "saa7134 ALSA: DMA sound is being handled by OSS. ignoring %s\n",dev->name);
- return -EBUSY;
- }
- }
-
- if (dev == NULL)
+ if (saadev == NULL)
printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
return 0;
+
}
/*
diff --git a/trunk/drivers/media/video/saa7134/saa7134-cards.c b/trunk/drivers/media/video/saa7134/saa7134-cards.c
index 75abc20b0ccd..663d03e5bc67 100644
--- a/trunk/drivers/media/video/saa7134/saa7134-cards.c
+++ b/trunk/drivers/media/video/saa7134/saa7134-cards.c
@@ -2529,32 +2529,6 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE1,
}},
},
- [SAA7134_BOARD_MSI_TVATANYWHERE_PLUS] = {
- .name = "MSI TV@Anywhere plus",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_TDA8290,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .inputs = {{
- .name = name_tv,
- .vmux = 1,
- .amux = TV,
- .tv = 1,
- },{
- .name = name_comp1,
- .vmux = 3,
- .amux = LINE1,
- },{
- .name = name_svideo,
- .vmux = 0,
- .amux = LINE1,
- }},
- .radio = {
- .name = name_radio,
- .amux = LINE1,
- },
- },
};
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -2995,12 +2969,6 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subvendor = PCI_VENDOR_ID_PHILIPS,
.subdevice = 0x2018,
.driver_data = SAA7134_BOARD_PHILIPS_TIGER,
- },{
- .vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
- .subvendor = 0x1462,
- .subdevice = 0x6231,
- .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
},{
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
diff --git a/trunk/drivers/media/video/saa7134/saa7134-core.c b/trunk/drivers/media/video/saa7134/saa7134-core.c
index 4275d2ddb864..19b88744fb31 100644
--- a/trunk/drivers/media/video/saa7134/saa7134-core.c
+++ b/trunk/drivers/media/video/saa7134/saa7134-core.c
@@ -53,13 +53,13 @@ static unsigned int gpio_tracking = 0;
module_param(gpio_tracking, int, 0644);
MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
-static unsigned int alsa = 0;
-module_param(alsa, int, 0644);
-MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]");
-
static unsigned int oss = 0;
-module_param(oss, int, 0644);
-MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]");
+module_param(oss, int, 0444);
+MODULE_PARM_DESC(oss,"register oss devices (default: no)");
+
+static unsigned int alsa = 0;
+module_param(alsa, int, 0444);
+MODULE_PARM_DESC(alsa,"register alsa devices (default: no)");
static unsigned int latency = UNSET;
module_param(latency, int, 0444);
@@ -68,18 +68,24 @@ MODULE_PARM_DESC(latency,"pci latency timer");
static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
static unsigned int vbi_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
+static unsigned int dsp_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
+static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
static unsigned int tuner[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
static unsigned int card[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
module_param_array(video_nr, int, NULL, 0444);
module_param_array(vbi_nr, int, NULL, 0444);
module_param_array(radio_nr, int, NULL, 0444);
+module_param_array(dsp_nr, int, NULL, 0444);
+module_param_array(mixer_nr, int, NULL, 0444);
module_param_array(tuner, int, NULL, 0444);
module_param_array(card, int, NULL, 0444);
MODULE_PARM_DESC(video_nr, "video device number");
MODULE_PARM_DESC(vbi_nr, "vbi device number");
MODULE_PARM_DESC(radio_nr, "radio device number");
+MODULE_PARM_DESC(dsp_nr, "oss dsp device number");
+MODULE_PARM_DESC(mixer_nr, "oss mixer device number");
MODULE_PARM_DESC(tuner, "tuner type");
MODULE_PARM_DESC(card, "card type");
@@ -189,7 +195,6 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
static int need_empress;
static int need_dvb;
static int need_alsa;
-static int need_oss;
static int pending_call(struct notifier_block *self, unsigned long state,
void *module)
@@ -203,8 +208,6 @@ static int pending_call(struct notifier_block *self, unsigned long state,
request_module("saa7134-dvb");
if (need_alsa)
request_module("saa7134-alsa");
- if (need_oss)
- request_module("saa7134-oss");
return NOTIFY_DONE;
}
@@ -215,11 +218,10 @@ static struct notifier_block pending_notifier = {
static void request_module_depend(char *name, int *flag)
{
- int err;
switch (THIS_MODULE->state) {
case MODULE_STATE_COMING:
if (!pending_registered) {
- err = register_module_notifier(&pending_notifier);
+ register_module_notifier(&pending_notifier);
pending_registered = 1;
}
*flag = 1;
@@ -576,14 +578,12 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
goto out;
}
- /* If dmasound support is active and we get a sound report, exit
- and let the saa7134-alsa/oss module deal with it */
+ /* If alsa support is active and we get a sound report, exit
+ and let the saa7134-alsa module deal with it */
- if ((report & SAA7134_IRQ_REPORT_DONE_RA3) &&
- (dev->dmasound.priv_data != NULL) )
- {
+ if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && alsa) {
if (irq_debug > 1)
- printk(KERN_DEBUG "%s/irq: ignoring interrupt for DMA sound\n",
+ printk(KERN_DEBUG "%s/irq: ignoring interrupt for ALSA\n",
dev->name);
goto out;
}
@@ -609,6 +609,12 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
card_has_mpeg(dev))
saa7134_irq_ts_done(dev,status);
+ if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) {
+ if (oss) {
+ saa7134_irq_oss_done(dev,status);
+ }
+ }
+
if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
SAA7134_IRQ_REPORT_GPIO18)) &&
dev->remote)
@@ -683,6 +689,14 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
* audio will not work.
*/
+ switch (dev->pci->device) {
+ case PCI_DEVICE_ID_PHILIPS_SAA7134:
+ case PCI_DEVICE_ID_PHILIPS_SAA7133:
+ case PCI_DEVICE_ID_PHILIPS_SAA7135:
+ saa7134_oss_init1(dev);
+ break;
+ }
+
/* enable peripheral devices */
saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
@@ -714,6 +728,8 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
SAA7134_IRQ2_INTE_GPIO18A |
SAA7134_IRQ2_INTE_GPIO16 );
+ else if (dev->has_remote == SAA7134_REMOTE_I2C)
+ request_module("ir-kbd-i2c");
saa_writel(SAA7134_IRQ1, 0);
saa_writel(SAA7134_IRQ2, irq2_mask);
@@ -726,6 +742,13 @@ static int saa7134_hwfini(struct saa7134_dev *dev)
{
dprintk("hwfini\n");
+ switch (dev->pci->device) {
+ case PCI_DEVICE_ID_PHILIPS_SAA7134:
+ case PCI_DEVICE_ID_PHILIPS_SAA7133:
+ case PCI_DEVICE_ID_PHILIPS_SAA7135:
+ saa7134_oss_fini(dev);
+ break;
+ }
if (card_has_mpeg(dev))
saa7134_ts_fini(dev);
saa7134_input_fini(dev);
@@ -963,12 +986,11 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
if (card_is_dvb(dev))
request_module_depend("saa7134-dvb",&need_dvb);
-
- if (alsa)
+ if (!oss && alsa) {
+ dprintk("Requesting ALSA module\n");
request_module_depend("saa7134-alsa",&need_alsa);
+ }
- if (oss)
- request_module_depend("saa7134-oss",&need_oss);
v4l2_prio_init(&dev->prio);
@@ -1002,6 +1024,32 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
dev->name,dev->radio_dev->minor & 0x1f);
}
+ /* register oss devices */
+ switch (dev->pci->device) {
+ case PCI_DEVICE_ID_PHILIPS_SAA7134:
+ case PCI_DEVICE_ID_PHILIPS_SAA7133:
+ case PCI_DEVICE_ID_PHILIPS_SAA7135:
+ if (oss) {
+ err = dev->dmasound.minor_dsp =
+ register_sound_dsp(&saa7134_dsp_fops,
+ dsp_nr[dev->nr]);
+ if (err < 0) {
+ goto fail4;
+ }
+ printk(KERN_INFO "%s: registered device dsp%d\n",
+ dev->name,dev->dmasound.minor_dsp >> 4);
+
+ err = dev->dmasound.minor_mixer =
+ register_sound_mixer(&saa7134_mixer_fops,
+ mixer_nr[dev->nr]);
+ if (err < 0)
+ goto fail5;
+ printk(KERN_INFO "%s: registered device mixer%d\n",
+ dev->name,dev->dmasound.minor_mixer >> 4);
+ }
+ break;
+ }
+
/* everything worked */
pci_set_drvdata(pci_dev,dev);
saa7134_devcount++;
@@ -1016,9 +1064,17 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
/* check for signal */
saa7134_irq_video_intl(dev);
-
return 0;
+ fail5:
+ switch (dev->pci->device) {
+ case PCI_DEVICE_ID_PHILIPS_SAA7134:
+ case PCI_DEVICE_ID_PHILIPS_SAA7133:
+ case PCI_DEVICE_ID_PHILIPS_SAA7135:
+ if (oss)
+ unregister_sound_dsp(dev->dmasound.minor_dsp);
+ break;
+ }
fail4:
saa7134_unregister_video(dev);
saa7134_i2c_unregister(dev);
@@ -1069,16 +1125,19 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
saa7134_devcount--;
saa7134_i2c_unregister(dev);
- saa7134_unregister_video(dev);
-
- /* the DMA sound modules should be unloaded before reaching
- this, but just in case they are still present... */
- if (dev->dmasound.priv_data != NULL) {
- free_irq(pci_dev->irq, &dev->dmasound);
- dev->dmasound.priv_data = NULL;
+ switch (dev->pci->device) {
+ case PCI_DEVICE_ID_PHILIPS_SAA7134:
+ case PCI_DEVICE_ID_PHILIPS_SAA7133:
+ case PCI_DEVICE_ID_PHILIPS_SAA7135:
+ if (oss) {
+ unregister_sound_mixer(dev->dmasound.minor_mixer);
+ unregister_sound_dsp(dev->dmasound.minor_dsp);
+ }
+ break;
}
+ saa7134_unregister_video(dev);
- /* release resources */
+ /* release ressources */
free_irq(pci_dev->irq, dev);
iounmap(dev->lmmio);
release_mem_region(pci_resource_start(pci_dev,0),
@@ -1166,7 +1225,7 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients);
EXPORT_SYMBOL(saa7134_devlist);
EXPORT_SYMBOL(saa7134_boards);
-/* ----------------- for the DMA sound modules --------------- */
+/* ----------------- For ALSA -------------------------------- */
EXPORT_SYMBOL(saa7134_pgtable_free);
EXPORT_SYMBOL(saa7134_pgtable_build);
diff --git a/trunk/drivers/media/video/saa7134/saa7134-input.c b/trunk/drivers/media/video/saa7134/saa7134-input.c
index e648cc3bc96d..329accda6d45 100644
--- a/trunk/drivers/media/video/saa7134/saa7134-input.c
+++ b/trunk/drivers/media/video/saa7134/saa7134-input.c
@@ -485,6 +485,64 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
};
+static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
+ [ 0x59 ] = KEY_MUTE,
+ [ 0x4a ] = KEY_POWER,
+
+ [ 0x18 ] = KEY_TEXT,
+ [ 0x26 ] = KEY_TV,
+ [ 0x3d ] = KEY_PRINT,
+
+ [ 0x48 ] = KEY_RED,
+ [ 0x04 ] = KEY_GREEN,
+ [ 0x11 ] = KEY_YELLOW,
+ [ 0x00 ] = KEY_BLUE,
+
+ [ 0x2d ] = KEY_VOLUMEUP,
+ [ 0x1e ] = KEY_VOLUMEDOWN,
+
+ [ 0x49 ] = KEY_MENU,
+
+ [ 0x16 ] = KEY_CHANNELUP,
+ [ 0x17 ] = KEY_CHANNELDOWN,
+
+ [ 0x20 ] = KEY_UP,
+ [ 0x21 ] = KEY_DOWN,
+ [ 0x22 ] = KEY_LEFT,
+ [ 0x23 ] = KEY_RIGHT,
+ [ 0x0d ] = KEY_SELECT,
+
+
+
+ [ 0x08 ] = KEY_BACK,
+ [ 0x07 ] = KEY_REFRESH,
+
+ [ 0x2f ] = KEY_ZOOM,
+ [ 0x29 ] = KEY_RECORD,
+
+ [ 0x4b ] = KEY_PAUSE,
+ [ 0x4d ] = KEY_REWIND,
+ [ 0x2e ] = KEY_PLAY,
+ [ 0x4e ] = KEY_FORWARD,
+ [ 0x53 ] = KEY_PREVIOUS,
+ [ 0x4c ] = KEY_STOP,
+ [ 0x54 ] = KEY_NEXT,
+
+ [ 0x69 ] = KEY_KP0,
+ [ 0x6a ] = KEY_KP1,
+ [ 0x6b ] = KEY_KP2,
+ [ 0x6c ] = KEY_KP3,
+ [ 0x6d ] = KEY_KP4,
+ [ 0x6e ] = KEY_KP5,
+ [ 0x6f ] = KEY_KP6,
+ [ 0x70 ] = KEY_KP7,
+ [ 0x71 ] = KEY_KP8,
+ [ 0x72 ] = KEY_KP9,
+
+ [ 0x74 ] = KEY_CHANNEL,
+ [ 0x0a ] = KEY_BACKSPACE,
+};
+
/* Mapping for the 28 key remote control as seen at
http://www.sednacomputer.com/photo/cardbus-tv.jpg
Pavel Mihaylov */
@@ -577,6 +635,57 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
+/* The new pinnacle PCTV remote (with the colored buttons)
+ *
+ * Ricardo Cerqueira
+ */
+
+static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+ unsigned char b[4];
+ unsigned int start = 0,parity = 0,code = 0;
+
+ /* poll IR chip */
+ if (4 != i2c_master_recv(&ir->c,b,4)) {
+ i2cdprintk("read error\n");
+ return -EIO;
+ }
+
+ for (start = 0; start<4; start++) {
+ if (b[start] == 0x80) {
+ code=b[(start+3)%4];
+ parity=b[(start+2)%4];
+ }
+ }
+
+ /* Empty Request */
+ if (parity==0)
+ return 0;
+
+ /* Repeating... */
+ if (ir->old == parity)
+ return 0;
+
+
+ ir->old = parity;
+
+ /* Reduce code value to fit inside IR_KEYTAB_SIZE
+ *
+ * this is the only value that results in 42 unique
+ * codes < 128
+ */
+
+ code %= 0x88;
+
+ *ir_raw = code;
+ *ir_key = code;
+
+ i2cdprintk("Pinnacle PCTV key %02x\n", code);
+
+ return 1;
+}
+
+
void saa7134_input_irq(struct saa7134_dev *dev)
{
struct saa7134_ir *ir = dev->remote;
diff --git a/trunk/drivers/media/video/saa7134/saa7134-oss.c b/trunk/drivers/media/video/saa7134/saa7134-oss.c
index fd9ed11ab1e2..fd53dfcc1644 100644
--- a/trunk/drivers/media/video/saa7134/saa7134-oss.c
+++ b/trunk/drivers/media/video/saa7134/saa7134-oss.c
@@ -4,8 +4,6 @@
* oss dsp interface
*
* (c) 2001,02 Gerd Knorr [SuSE Labs]
- * 2005 conversion to standalone module:
- * Ricardo Cerqueira
*
* 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
@@ -27,9 +25,7 @@
#include
#include
#include
-#include
#include
-#include
#include
#include "saa7134-reg.h"
@@ -37,23 +33,15 @@
/* ------------------------------------------------------------------ */
-static unsigned int debug = 0;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug,"enable debug messages [oss]");
+static unsigned int oss_debug = 0;
+module_param(oss_debug, int, 0644);
+MODULE_PARM_DESC(oss_debug,"enable debug messages [oss]");
-static unsigned int rate = 0;
-module_param(rate, int, 0444);
-MODULE_PARM_DESC(rate,"sample rate (valid are: 32000,48000)");
+static unsigned int oss_rate = 0;
+module_param(oss_rate, int, 0444);
+MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
-static unsigned int dsp_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-MODULE_PARM_DESC(dsp_nr, "device numbers for SAA7134 capture interface(s).");
-module_param_array(dsp_nr, int, NULL, 0444);
-
-static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-MODULE_PARM_DESC(mixer_nr, "mixer numbers for SAA7134 capture interface(s).");
-module_param_array(mixer_nr, int, NULL, 0444);
-
-#define dprintk(fmt, arg...) if (debug) \
+#define dprintk(fmt, arg...) if (oss_debug) \
printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
@@ -381,7 +369,7 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
int __user *p = argp;
int val = 0;
- if (debug > 1)
+ if (oss_debug > 1)
saa7134_print_ioctl(dev->name,cmd);
switch (cmd) {
case OSS_GETVERSION:
@@ -677,7 +665,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
void __user *argp = (void __user *) arg;
int __user *p = argp;
- if (debug > 1)
+ if (oss_debug > 1)
saa7134_print_ioctl(dev->name,cmd);
switch (cmd) {
case OSS_GETVERSION:
@@ -780,41 +768,8 @@ struct file_operations saa7134_mixer_fops = {
/* ------------------------------------------------------------------ */
-static irqreturn_t saa7134_oss_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct saa7134_dmasound *dmasound = dev_id;
- struct saa7134_dev *dev = dmasound->priv_data;
- unsigned long report, status;
- int loop, handled = 0;
-
- for (loop = 0; loop < 10; loop++) {
- report = saa_readl(SAA7134_IRQ_REPORT);
- status = saa_readl(SAA7134_IRQ_STATUS);
-
- if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
- handled = 1;
- saa_writel(SAA7134_IRQ_REPORT,report);
- saa7134_irq_oss_done(dev, status);
- } else {
- goto out;
- }
- }
-
- if (loop == 10) {
- dprintk("error! looping IRQ!");
- }
-out:
- return IRQ_RETVAL(handled);
-}
-
int saa7134_oss_init1(struct saa7134_dev *dev)
{
-
- if ((request_irq(dev->pci->irq, saa7134_oss_irq,
- SA_SHIRQ | SA_INTERRUPT, dev->name,
- (void*) &dev->dmasound)) < 0)
- return -1;
-
/* general */
init_MUTEX(&dev->dmasound.lock);
init_waitqueue_head(&dev->dmasound.wq);
@@ -830,8 +785,8 @@ int saa7134_oss_init1(struct saa7134_dev *dev)
/* dsp */
dev->dmasound.rate = 32000;
- if (rate)
- dev->dmasound.rate = rate;
+ if (oss_rate)
+ dev->dmasound.rate = oss_rate;
dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000;
/* mixer */
@@ -885,7 +840,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
/* next block addr */
next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
saa_writel(reg,next_blk * dev->dmasound.blksize);
- if (debug > 2)
+ if (oss_debug > 2)
dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
(status & 0x10000000) ? "even" : "odd ", next_blk,
next_blk * dev->dmasound.blksize);
@@ -899,98 +854,6 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
spin_unlock(&dev->slock);
}
-int saa7134_dsp_create(struct saa7134_dev *dev)
-{
- int err;
-
- err = dev->dmasound.minor_dsp =
- register_sound_dsp(&saa7134_dsp_fops,
- dsp_nr[dev->nr]);
- if (err < 0) {
- goto fail;
- }
- printk(KERN_INFO "%s: registered device dsp%d\n",
- dev->name,dev->dmasound.minor_dsp >> 4);
-
- err = dev->dmasound.minor_mixer =
- register_sound_mixer(&saa7134_mixer_fops,
- mixer_nr[dev->nr]);
- if (err < 0)
- goto fail;
- printk(KERN_INFO "%s: registered device mixer%d\n",
- dev->name,dev->dmasound.minor_mixer >> 4);
-
- return 0;
-
-fail:
- unregister_sound_dsp(dev->dmasound.minor_dsp);
- return 0;
-
-
-}
-
-static int saa7134_oss_init(void)
-{
- struct saa7134_dev *dev = NULL;
- struct list_head *list;
-
- printk(KERN_INFO "saa7134 OSS driver for DMA sound loaded\n");
-
- list_for_each(list,&saa7134_devlist) {
- dev = list_entry(list, struct saa7134_dev, devlist);
- if (dev->dmasound.priv_data == NULL) {
- dev->dmasound.priv_data = dev;
- saa7134_oss_init1(dev);
- saa7134_dsp_create(dev);
- } else {
- printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name);
- return -EBUSY;
- }
- }
-
- if (dev == NULL)
- printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n");
-
- return 0;
-
-}
-
-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);
-
- /* Device isn't registered by OSS, probably ALSA's */
- if (!dev->dmasound.minor_dsp)
- continue;
-
- unregister_sound_mixer(dev->dmasound.minor_mixer);
- unregister_sound_dsp(dev->dmasound.minor_dsp);
-
- saa7134_oss_fini(dev);
-
- if (dev->pci->irq > 0) {
- synchronize_irq(dev->pci->irq);
- free_irq(dev->pci->irq,&dev->dmasound);
- }
-
- dev->dmasound.priv_data = NULL;
-
- }
-
- printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n");
-
- return;
-}
-
-module_init(saa7134_oss_init);
-module_exit(saa7134_oss_exit);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Gerd Knorr [SuSE Labs]");
-
/* ----------------------------------------------------------- */
/*
* Local variables:
diff --git a/trunk/drivers/media/video/saa7134/saa7134.h b/trunk/drivers/media/video/saa7134/saa7134.h
index 244e1973081c..fb9727471661 100644
--- a/trunk/drivers/media/video/saa7134/saa7134.h
+++ b/trunk/drivers/media/video/saa7134/saa7134.h
@@ -208,7 +208,6 @@ struct saa7134_format {
#define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS 79
#define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
#define SAA7134_BOARD_PHILIPS_TIGER 81
-#define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS 82
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
@@ -384,7 +383,6 @@ struct saa7134_dmasound {
unsigned int dma_blk;
unsigned int read_offset;
unsigned int read_count;
- void * priv_data;
snd_pcm_substream_t *substream;
};
diff --git a/trunk/drivers/media/video/tda8290.c b/trunk/drivers/media/video/tda8290.c
index 61d94ddaff41..b2dfe07e9f9d 100644
--- a/trunk/drivers/media/video/tda8290.c
+++ b/trunk/drivers/media/video/tda8290.c
@@ -437,10 +437,6 @@ static void set_audio(struct tuner *t)
t->sgIF = 124;
t->tda8290_easy_mode = 0x20;
mode = "L";
- } else if (t->std & V4L2_STD_SECAM_LC) {
- t->sgIF = 20;
- t->tda8290_easy_mode = 0x40;
- mode = "LC";
}
tuner_dbg("setting tda8290 to system %s\n", mode);
}
diff --git a/trunk/drivers/media/video/tuner-core.c b/trunk/drivers/media/video/tuner-core.c
index e58abdfcaab8..73c4041c35d7 100644
--- a/trunk/drivers/media/video/tuner-core.c
+++ b/trunk/drivers/media/video/tuner-core.c
@@ -251,7 +251,7 @@ static inline int check_mode(struct tuner *t, char *cmd)
static char pal[] = "-";
module_param_string(pal, pal, sizeof(pal), 0644);
-static char secam[] = "--";
+static char secam[] = "-";
module_param_string(secam, secam, sizeof(secam), 0644);
/* get more precise norm info from insmod option */
@@ -307,13 +307,8 @@ static int tuner_fixup_std(struct tuner *t)
break;
case 'l':
case 'L':
- if ((secam[1]=='C')||(secam[1]=='c')) {
- tuner_dbg ("insmod fixup: SECAM => SECAM-L'\n");
- t->std = V4L2_STD_SECAM_LC;
- } else {
- tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
- t->std = V4L2_STD_SECAM_L;
- }
+ tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
+ t->std = V4L2_STD_SECAM_L;
break;
case '-':
/* default parameter, do nothing */
diff --git a/trunk/drivers/media/video/tuner-simple.c b/trunk/drivers/media/video/tuner-simple.c
index e0c9fdb9914a..d832205818f2 100644
--- a/trunk/drivers/media/video/tuner-simple.c
+++ b/trunk/drivers/media/video/tuner-simple.c
@@ -233,7 +233,7 @@ static struct tunertype tuners[] = {
{ "Ymec TVision TVF-5533MF", Philips, NTSC,
16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
- /* 60-69 */
+ /* 60-68 */
{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
{ "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
@@ -252,8 +252,6 @@ static struct tunertype tuners[] = {
16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 },
{ "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC,
16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 },
- { "Tena TNF 5335 MF", Philips, NTSC,
- 16*157.25,16*454.00,0x01,0x02,0x04,0x8e,732 },
};
unsigned const int tuner_count = ARRAY_SIZE(tuners);
diff --git a/trunk/drivers/media/video/wm8775.c b/trunk/drivers/media/video/wm8775.c
index a6936ad74fcf..22f286222004 100644
--- a/trunk/drivers/media/video/wm8775.c
+++ b/trunk/drivers/media/video/wm8775.c
@@ -5,11 +5,6 @@
*
* Based on saa7115 driver
*
- * Copyright (C) 2005 Hans Verkuil
- * - Cleanup
- * - V4L2 API update
- * - sound fixes
- *
* 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
@@ -36,7 +31,7 @@
#include
MODULE_DESCRIPTION("wm8775 driver");
-MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
+MODULE_AUTHOR("Ulf Eklund");
MODULE_LICENSE("GPL");
#define wm8775_err(fmt, arg...) do { \
diff --git a/trunk/drivers/mmc/mmci.c b/trunk/drivers/mmc/mmci.c
index 166c9b0ad04e..1e6bdba26756 100644
--- a/trunk/drivers/mmc/mmci.c
+++ b/trunk/drivers/mmc/mmci.c
@@ -22,6 +22,7 @@
#include
#include
+#include