Merge branch 'master' into upstream

This commit is contained in:
Jeff Garzik 2006-05-24 01:32:42 -04:00
commit 26e27cd424
145 changed files with 2743 additions and 979 deletions

View File

@ -259,9 +259,9 @@ sub dibusb {
}
sub nxt2002 {
my $sourcefile = "Broadband4PC_4_2_11.zip";
my $sourcefile = "Technisat_DVB-PC_4_4_COMPACT.zip";
my $url = "http://www.bbti.us/download/windows/$sourcefile";
my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a";
my $hash = "476befae8c7c1bb9648954060b1eec1f";
my $outfile = "dvb-fe-nxt2002.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
@ -269,8 +269,8 @@ sub nxt2002 {
wgetfile($sourcefile, $url);
unzip($sourcefile, $tmpdir);
verify("$tmpdir/SkyNETU.sys", $hash);
extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile);
verify("$tmpdir/SkyNET.sys", $hash);
extract("$tmpdir/SkyNET.sys", 331624, 5908, $outfile);
$outfile;
}

View File

@ -105,20 +105,3 @@
on the setup, so I think that the choice on what firmware to make
persistent should be left to userspace.
- Why register_firmware()+__init can be useful:
- For boot devices needing firmware.
- To make the transition easier:
The firmware can be declared __init and register_firmware()
called on module_init. Then the firmware is warranted to be
there even if "firmware hotplug userspace" is not there yet or
it doesn't yet provide the needed firmware.
Once the firmware is widely available in userspace, it can be
removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE).
In either case, if firmware hotplug support is there, it can move the
firmware out of kernel memory into the real filesystem for later
usage.
Note: If persistence is implemented on top of initramfs,
register_firmware() may not be appropriate.

View File

@ -5,8 +5,6 @@
*
* Sample code on how to use request_firmware() from drivers.
*
* Note that register_firmware() is currently useless.
*
*/
#include <linux/module.h>
@ -17,11 +15,6 @@
#include "linux/firmware.h"
#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
char __init inkernel_firmware[] = "let's say that this is firmware\n";
#endif
static struct device ghost_device = {
.bus_id = "ghost0",
};
@ -104,10 +97,6 @@ static void sample_probe_async(void)
static int sample_init(void)
{
#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
register_firmware("sample_driver_fw", inkernel_firmware,
sizeof(inkernel_firmware));
#endif
device_initialize(&ghost_device);
/* since there is no real hardware insertion I just call the
* sample probe functions here */

View File

@ -40,11 +40,20 @@ trivial patch so apply some common sense.
PLEASE document known bugs. If it doesn't work for everything
or does something very odd once a month document it.
PLEASE remember that submissions must be made under the terms
of the OSDL certificate of contribution
(http://www.osdl.org/newsroom/press_releases/2004/2004_05_24_dco.html)
and should include a Signed-off-by: line.
6. Make sure you have the right to send any changes you make. If you
do changes at work you may find your employer owns the patch
not you.
7. Happy hacking.
7. When sending security related changes or reports to a maintainer
please Cc: security@kernel.org, especially if the maintainer
does not respond.
8. Happy hacking.
-----------------------------------
@ -969,7 +978,7 @@ S: Maintained
EXT3 FILE SYSTEM
P: Stephen Tweedie, Andrew Morton
M: sct@redhat.com, akpm@osdl.org, adilger@clusterfs.com
L: ext3-users@redhat.com
L: ext2-devel@lists.sourceforge.net
S: Maintained
F71805F HARDWARE MONITORING DRIVER
@ -1530,12 +1539,28 @@ W: http://jfs.sourceforge.net/
T: git kernel.org:/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git
S: Supported
JOURNALLING LAYER FOR BLOCK DEVICS (JBD)
P: Stephen Tweedie, Andrew Morton
M: sct@redhat.com, akpm@osdl.org
L: ext2-devel@lists.sourceforge.net
S: Maintained
KCONFIG
P: Roman Zippel
M: zippel@linux-m68k.org
L: kbuild-devel@lists.sourceforge.net
S: Maintained
KDUMP
P: Vivek Goyal
M: vgoyal@in.ibm.com
P: Haren Myneni
M: hbabu@us.ibm.com
L: fastboot@lists.osdl.org
L: linux-kernel@vger.kernel.org
W: http://lse.sourceforge.net/kdump/
S: Maintained
KERNEL AUTOMOUNTER (AUTOFS)
P: H. Peter Anvin
M: hpa@zytor.com

View File

@ -1341,6 +1341,14 @@ int __init APIC_init_uniprocessor (void)
connect_bsp_APIC();
/*
* Hack: In case of kdump, after a crash, kernel might be booting
* on a cpu with non-zero lapic id. But boot_cpu_physical_apicid
* might be zero if read from MP tables. Get it from LAPIC.
*/
#ifdef CONFIG_CRASH_DUMP
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
#endif
phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
setup_local_APIC();

View File

@ -130,9 +130,8 @@ static inline int print_addr_and_symbol(unsigned long addr, char *log_lvl,
print_symbol("%s", addr);
printed = (printed + 1) % CONFIG_STACK_BACKTRACE_COLS;
if (printed)
printk(" ");
printk(" ");
else
printk("\n");
@ -212,7 +211,6 @@ static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp,
}
stack = esp;
printk(log_lvl);
for(i = 0; i < kstack_depth_to_print; i++) {
if (kstack_end(stack))
break;

View File

@ -651,7 +651,7 @@ void __init mem_init(void)
* Specifically, in the case of x86, we will always add
* memory to the highmem for now.
*/
#ifdef CONFIG_HOTPLUG_MEMORY
#ifdef CONFIG_MEMORY_HOTPLUG
#ifndef CONFIG_NEED_MULTIPLE_NODES
int add_memory(u64 start, u64 size)
{

View File

@ -92,7 +92,7 @@ void __restore_processor_state(struct saved_context *ctxt)
write_cr4(ctxt->cr4);
write_cr3(ctxt->cr3);
write_cr2(ctxt->cr2);
write_cr2(ctxt->cr0);
write_cr0(ctxt->cr0);
/*
* now restore the descriptor tables to their proper values

View File

@ -338,6 +338,8 @@ SYSCALL(symlinkat)
SYSCALL(readlinkat)
SYSCALL(fchmodat)
SYSCALL(faccessat)
COMPAT_SYS(get_robust_list)
COMPAT_SYS(set_robust_list)
/*
* please add new calls to arch/powerpc/platforms/cell/spu_callbacks.c

View File

@ -258,6 +258,7 @@ void *spu_syscall_table[] = {
[__NR_futex] sys_futex,
[__NR_sched_setaffinity] sys_sched_setaffinity,
[__NR_sched_getaffinity] sys_sched_getaffinity,
[224] sys_ni_syscall,
[__NR_tuxcall] sys_ni_syscall,
[226] sys_ni_syscall,
[__NR_io_setup] sys_io_setup,
@ -332,19 +333,21 @@ void *spu_syscall_table[] = {
[__NR_readlinkat] sys_readlinkat,
[__NR_fchmodat] sys_fchmodat,
[__NR_faccessat] sys_faccessat,
[__NR_get_robust_list] sys_get_robust_list,
[__NR_set_robust_list] sys_set_robust_list,
};
long spu_sys_callback(struct spu_syscall_block *s)
{
long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6);
syscall = spu_syscall_table[s->nr_ret];
if (s->nr_ret >= ARRAY_SIZE(spu_syscall_table)) {
pr_debug("%s: invalid syscall #%ld", __FUNCTION__, s->nr_ret);
return -ENOSYS;
}
syscall = spu_syscall_table[s->nr_ret];
#ifdef DEBUG
print_symbol(KERN_DEBUG "SPU-syscall %s:", (unsigned long)syscall);
printk("syscall%ld(%lx, %lx, %lx, %lx, %lx, %lx)\n",

View File

@ -272,7 +272,7 @@ static inline void stop_hz_timer(void)
next = next_timer_interrupt();
do {
seq = read_seqbegin_irqsave(&xtime_lock, flags);
timer = (__u64)(next - jiffies) + jiffies_64;
timer = (__u64 next) - (__u64 jiffies) + jiffies_64;
} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
todval = -1ULL;
/* Be careful about overflows. */

View File

@ -79,6 +79,7 @@ sys_call_table:
/*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
/*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
/*300*/ .long sys_set_robust_list, sys_get_robust_list
#ifdef CONFIG_SUNOS_EMUL
/* Now the SunOS syscall table. */
@ -190,6 +191,6 @@ sunos_sys_table:
/*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys
.long sunos_nosys, sunos_nosys, sunos_nosys
#endif

View File

@ -218,7 +218,7 @@ static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx)
* DMA for PCI device PDEV. Return non-NULL cpu-side address if
* successful and set *DMA_ADDRP to the PCI side dma address.
*/
static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
@ -232,7 +232,7 @@ static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr
if (order >= 10)
return NULL;
first_page = __get_free_pages(GFP_ATOMIC, order);
first_page = __get_free_pages(gfp, order);
if (first_page == 0UL)
return NULL;
memset((char *)first_page, 0, PAGE_SIZE << order);

View File

@ -154,7 +154,7 @@ static void pci_arena_free(struct pci_iommu_arena *arena, unsigned long base, un
__clear_bit(i, arena->map);
}
static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp)
{
struct pcidev_cookie *pcp;
struct pci_iommu *iommu;
@ -169,7 +169,7 @@ static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr
npages = size >> IO_PAGE_SHIFT;
first_page = __get_free_pages(GFP_ATOMIC, order);
first_page = __get_free_pages(gfp, order);
if (unlikely(first_page == 0UL))
return NULL;

View File

@ -78,8 +78,9 @@ sys_call_table32:
.word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
/*280*/ .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
.word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64
/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
/*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
.word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list
#endif /* CONFIG_COMPAT */
@ -147,8 +148,9 @@ sys_call_table:
.word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
/*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
.word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
/*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
.word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
/*300*/ .word sys_set_robust_list, sys_get_robust_list
#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
defined(CONFIG_SOLARIS_EMUL_MODULE)
@ -261,5 +263,5 @@ sunos_sys_table:
/*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
#endif

View File

@ -514,13 +514,13 @@ static void __kprobes resume_execution(struct kprobe *p,
*tos = orig_rip + (*tos - copy_rip);
break;
case 0xff:
if ((*insn & 0x30) == 0x10) {
if ((insn[1] & 0x30) == 0x10) {
/* call absolute, indirect */
/* Fix return addr; rip is correct. */
next_rip = regs->rip;
*tos = orig_rip + (*tos - copy_rip);
} else if (((*insn & 0x31) == 0x20) || /* jmp near, absolute indirect */
((*insn & 0x31) == 0x21)) { /* jmp far, absolute indirect */
} else if (((insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */
((insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */
/* rip is correct. */
next_rip = regs->rip;
}

View File

@ -3452,7 +3452,12 @@ void end_that_request_last(struct request *req, int uptodate)
if (unlikely(laptop_mode) && blk_fs_request(req))
laptop_io_completion();
if (disk && blk_fs_request(req)) {
/*
* Account IO completion. bar_rq isn't accounted as a normal
* IO on queueing nor completion. Accounting the containing
* request is enough.
*/
if (disk && blk_fs_request(req) && req != &req->q->bar_rq) {
unsigned long duration = jiffies - req->start_time;
const int rw = rq_data_dir(req);

View File

@ -86,18 +86,9 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count)
static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
static void fw_class_dev_release(struct class_device *class_dev);
int firmware_class_uevent(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
static struct class firmware_class = {
.name = "firmware",
.uevent = firmware_class_uevent,
.release = fw_class_dev_release,
};
int
firmware_class_uevent(struct class_device *class_dev, char **envp,
int num_envp, char *buffer, int buffer_size)
static int firmware_class_uevent(struct class_device *class_dev, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct firmware_priv *fw_priv = class_get_devdata(class_dev);
int i = 0, len = 0;
@ -116,6 +107,12 @@ firmware_class_uevent(struct class_device *class_dev, char **envp,
return 0;
}
static struct class firmware_class = {
.name = "firmware",
.uevent = firmware_class_uevent,
.release = fw_class_dev_release,
};
static ssize_t
firmware_loading_show(struct class_device *class_dev, char *buf)
{
@ -493,25 +490,6 @@ release_firmware(const struct firmware *fw)
}
}
/**
* register_firmware: - provide a firmware image for later usage
* @name: name of firmware image file
* @data: buffer pointer for the firmware image
* @size: size of the data buffer area
*
* Make sure that @data will be available by requesting firmware @name.
*
* Note: This will not be possible until some kind of persistence
* is available.
**/
void
register_firmware(const char *name, const u8 *data, size_t size)
{
/* This is meaningless without firmware caching, so until we
* decide if firmware caching is reasonable just leave it as a
* noop */
}
/* Async support */
struct firmware_work {
struct work_struct work;
@ -630,4 +608,3 @@ module_exit(firmware_class_exit);
EXPORT_SYMBOL(release_firmware);
EXPORT_SYMBOL(request_firmware);
EXPORT_SYMBOL(request_firmware_nowait);
EXPORT_SYMBOL(register_firmware);

View File

@ -398,7 +398,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
while (unlikely(size > copied));
return copied;
}
EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags);
EXPORT_SYMBOL(tty_insert_flip_string_flags);
void tty_schedule_flip(struct tty_struct *tty)
{

View File

@ -553,6 +553,8 @@ pmac_ide_init_hwif_ports(hw_regs_t *hw,
if (irq != NULL)
*irq = pmac_ide[ix].irq;
hw->dev = &pmac_ide[ix].mdev->ofdev.dev;
}
#define PMAC_IDE_REG(x) ((void __iomem *)(IDE_DATA_REG+(x)))

View File

@ -2880,7 +2880,7 @@ isdn_tty_cmd_ATand(char **p, modem_info * info)
p[0]++;
i = 0;
while (*p[0] && (strchr("0123456789,-*[]?;", *p[0])) &&
(i < ISDN_LMSNLEN))
(i < ISDN_LMSNLEN - 1))
m->lmsn[i++] = *p[0]++;
m->lmsn[i] = '\0';
break;

View File

@ -2252,7 +2252,7 @@ action_store(mddev_t *mddev, const char *page, size_t len)
} else {
if (cmd_match(page, "check"))
set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
else if (cmd_match(page, "repair"))
else if (!cmd_match(page, "repair"))
return -EINVAL;
set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
set_bit(MD_RECOVERY_SYNC, &mddev->recovery);

View File

@ -331,13 +331,14 @@ static int raid0_run (mddev_t *mddev)
goto out_free_conf;
size = conf->strip_zone[cur].size;
for (i=0; i< nb_zone; i++) {
conf->hash_table[i] = conf->strip_zone + cur;
conf->hash_table[0] = conf->strip_zone + cur;
for (i=1; i< nb_zone; i++) {
while (size <= conf->hash_spacing) {
cur++;
size += conf->strip_zone[cur].size;
}
size -= conf->hash_spacing;
conf->hash_table[i] = conf->strip_zone + cur;
}
if (conf->preshift) {
conf->hash_spacing >>= conf->preshift;

View File

@ -8,22 +8,54 @@ config VIDEO_DEV
tristate "Video For Linux"
---help---
Support for audio/video capture and overlay devices and FM radio
cards. The exact capabilities of each device vary. User tools for
this are available from
<ftp://ftp.uk.linux.org/pub/linux/video4linux/>.
cards. The exact capabilities of each device vary.
This kernel includes support for the new Video for Linux Two API,
(V4L2) as well as the original system. Drivers and applications
need to be rewritten to use V4L2, but drivers for popular cards
and applications for most video capture functions already exist.
Documentation for the original API is included in the file
<file:Documentation/video4linux/API.html>. Documentation for V4L2 is
available on the web at <http://bytesex.org/v4l/>.
Additional info and docs are available on the web at
<http://linuxtv.org>
Documentation for V4L2 is also available on the web at
<http://bytesex.org/v4l/>.
To compile this driver as a module, choose M here: the
module will be called videodev.
config VIDEO_V4L1
boolean "Enable Video For Linux API 1 (DEPRECATED)"
depends on VIDEO_DEV
select VIDEO_V4L1_COMPAT
default y
---help---
Enables a compatibility API used by most V4L2 devices to allow
its usage with legacy applications that supports only V4L1 api.
If you are unsure as to whether this is required, answer Y.
config VIDEO_V4L1_COMPAT
boolean "Enable Video For Linux API 1 compatible Layer"
depends on VIDEO_DEV
default y
---help---
This api were developed to be used at Kernel 2.2 and 2.4, but
lacks support for several video standards. There are several
drivers at kernel that still depends on it.
Documentation for the original API is included in the file
<Documentation/video4linux/API.html>.
User tools for this are available from
<ftp://ftp.uk.linux.org/pub/linux/video4linux/>.
If you are unsure as to whether this is required, answer Y.
config VIDEO_V4L2
tristate
default y
source "drivers/media/video/Kconfig"
source "drivers/media/radio/Kconfig"
@ -65,4 +97,3 @@ config USB_DABUSB
module will be called dabusb.
endmenu

View File

@ -4,6 +4,7 @@ config VIDEO_SAA7146
config VIDEO_SAA7146_VV
tristate
select VIDEO_V4L2
select VIDEO_BUF
select VIDEO_VIDEOBUF
select VIDEO_SAA7146

View File

@ -22,26 +22,26 @@ config DVB
source "drivers/media/dvb/dvb-core/Kconfig"
comment "Supported SAA7146 based PCI Adapters"
depends on DVB_CORE && PCI
depends on DVB_CORE && PCI && I2C
source "drivers/media/dvb/ttpci/Kconfig"
comment "Supported USB Adapters"
depends on DVB_CORE && USB
depends on DVB_CORE && USB && I2C
source "drivers/media/dvb/dvb-usb/Kconfig"
source "drivers/media/dvb/ttusb-budget/Kconfig"
source "drivers/media/dvb/ttusb-dec/Kconfig"
source "drivers/media/dvb/cinergyT2/Kconfig"
comment "Supported FlexCopII (B2C2) Adapters"
depends on DVB_CORE && (PCI || USB)
depends on DVB_CORE && (PCI || USB) && I2C
source "drivers/media/dvb/b2c2/Kconfig"
comment "Supported BT878 Adapters"
depends on DVB_CORE && PCI
depends on DVB_CORE && PCI && I2C
source "drivers/media/dvb/bt8xx/Kconfig"
comment "Supported Pluto2 Adapters"
depends on DVB_CORE && PCI
depends on DVB_CORE && PCI && I2C
source "drivers/media/dvb/pluto2/Kconfig"
comment "Supported DVB Frontends"

View File

@ -1,6 +1,6 @@
config DVB_B2C2_FLEXCOP
tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters"
depends on DVB_CORE
depends on DVB_CORE && I2C
select DVB_STV0299
select DVB_MT352
select DVB_MT312
@ -16,7 +16,7 @@ config DVB_B2C2_FLEXCOP
config DVB_B2C2_FLEXCOP_PCI
tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI"
depends on DVB_B2C2_FLEXCOP && PCI
depends on DVB_B2C2_FLEXCOP && PCI && I2C
help
Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2.
@ -24,7 +24,7 @@ config DVB_B2C2_FLEXCOP_PCI
config DVB_B2C2_FLEXCOP_USB
tristate "Technisat/B2C2 Air/Sky/Cable2PC USB"
depends on DVB_B2C2_FLEXCOP && USB
depends on DVB_B2C2_FLEXCOP && USB && I2C
help
Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2,

View File

@ -1,12 +1,13 @@
config DVB_BT8XX
tristate "BT8xx based PCI cards"
depends on DVB_CORE && PCI && VIDEO_BT848
depends on DVB_CORE && PCI && I2C && VIDEO_BT848
select DVB_MT352
select DVB_SP887X
select DVB_NXT6000
select DVB_CX24110
select DVB_OR51211
select DVB_LGDT330X
select DVB_ZL10353
select FW_LOADER
help
Support for PCI cards based on the Bt8xx PCI bridge. Examples are

View File

@ -115,7 +115,7 @@ static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev)
return 0;
}
static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
{
unsigned int card_nr;
@ -709,7 +709,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
}
}
static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
{
int result;
@ -794,7 +794,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
return 0;
}
static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub)
{
struct dvb_bt8xx_card *card;
struct pci_dev* bttv_pci_dev;

View File

@ -902,7 +902,10 @@ static int cinergyt2_probe (struct usb_interface *intf,
return -ENOMEM;
}
dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE);
if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE)) < 0) {
kfree(cinergyt2);
return err;
}
cinergyt2->demux.priv = cinergyt2;
cinergyt2->demux.filternum = 256;

View File

@ -106,6 +106,8 @@ struct dvb_frontend_private {
unsigned long tune_mode_flags;
unsigned int delay;
unsigned int reinitialise;
int tone;
int voltage;
/* swzigzag values */
unsigned int state;
@ -537,6 +539,12 @@ static int dvb_frontend_thread(void *data)
if (fepriv->reinitialise) {
dvb_frontend_init(fe);
if (fepriv->tone != -1) {
fe->ops->set_tone(fe, fepriv->tone);
}
if (fepriv->voltage != -1) {
fe->ops->set_voltage(fe, fepriv->voltage);
}
fepriv->reinitialise = 0;
}
@ -788,6 +796,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
case FE_SET_TONE:
if (fe->ops->set_tone) {
err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg);
fepriv->tone = (fe_sec_tone_mode_t) parg;
fepriv->state = FESTATE_DISEQC;
fepriv->status = 0;
}
@ -796,6 +805,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
case FE_SET_VOLTAGE:
if (fe->ops->set_voltage) {
err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg);
fepriv->voltage = (fe_sec_voltage_t) parg;
fepriv->state = FESTATE_DISEQC;
fepriv->status = 0;
}
@ -995,6 +1005,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
/* normal tune mode when opened R/W */
fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
fepriv->tone = -1;
fepriv->voltage = -1;
}
return ret;

View File

@ -219,8 +219,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
return -ENOMEM;
}
mutex_unlock(&dvbdev_register_lock);
memcpy(dvbdev, template, sizeof(struct dvb_device));
dvbdev->type = type;
dvbdev->id = id;
@ -231,6 +229,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
list_add_tail (&dvbdev->list_head, &adap->device_list);
mutex_unlock(&dvbdev_register_lock);
devfs_mk_cdev(MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
S_IFCHR | S_IRUSR | S_IWUSR,
"dvb/adapter%d/%s%d", adap->num, dnames[type], id);

View File

@ -1,6 +1,6 @@
config DVB_USB
tristate "Support for various USB DVB devices"
depends on DVB_CORE && USB
depends on DVB_CORE && USB && I2C
select FW_LOADER
help
By enabling this you will be able to choose the various supported

View File

@ -150,6 +150,15 @@ static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
}
static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
{
u8 b = 0;
if (onoff)
return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
else
return 0;
}
static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
{
u8 buf[2] = { 0x03, 0x00 };
@ -544,7 +553,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
.size_of_priv = sizeof(struct cxusb_state),
.streaming_ctrl = cxusb_streaming_ctrl,
.power_ctrl = cxusb_power_ctrl,
.power_ctrl = cxusb_bluebird_power_ctrl,
.frontend_attach = cxusb_lgdt3303_frontend_attach,
.tuner_attach = cxusb_lgh064f_tuner_attach,
@ -589,7 +598,7 @@ static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = {
.size_of_priv = sizeof(struct cxusb_state),
.streaming_ctrl = cxusb_streaming_ctrl,
.power_ctrl = cxusb_power_ctrl,
.power_ctrl = cxusb_bluebird_power_ctrl,
.frontend_attach = cxusb_dee1601_frontend_attach,
.tuner_attach = cxusb_dee1601_tuner_attach,
@ -638,7 +647,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgz201_properties = {
.size_of_priv = sizeof(struct cxusb_state),
.streaming_ctrl = cxusb_streaming_ctrl,
.power_ctrl = cxusb_power_ctrl,
.power_ctrl = cxusb_bluebird_power_ctrl,
.frontend_attach = cxusb_mt352_frontend_attach,
.tuner_attach = cxusb_lgz201_tuner_attach,
@ -683,7 +692,7 @@ static struct dvb_usb_properties cxusb_bluebird_dtt7579_properties = {
.size_of_priv = sizeof(struct cxusb_state),
.streaming_ctrl = cxusb_streaming_ctrl,
.power_ctrl = cxusb_power_ctrl,
.power_ctrl = cxusb_bluebird_power_ctrl,
.frontend_attach = cxusb_mt352_frontend_attach,
.tuner_attach = cxusb_dtt7579_tuner_attach,

View File

@ -29,6 +29,9 @@
#include "dvb_frontend.h"
#include "cx24123.h"
#define XTAL 10111000
static int force_band;
static int debug;
#define dprintk(args...) \
do { \
@ -52,6 +55,7 @@ struct cx24123_state
u32 VGAarg;
u32 bandselectarg;
u32 pllarg;
u32 FILTune;
/* The Demod/Tuner can't easily provide these, we cache them */
u32 currentfreq;
@ -63,43 +67,33 @@ static struct
{
u32 symbolrate_low;
u32 symbolrate_high;
u32 VCAslope;
u32 VCAoffset;
u32 VGA1offset;
u32 VGA2offset;
u32 VCAprogdata;
u32 VGAprogdata;
u32 FILTune;
} cx24123_AGC_vals[] =
{
{
.symbolrate_low = 1000000,
.symbolrate_high = 4999999,
.VCAslope = 0x07,
.VCAoffset = 0x0f,
.VGA1offset = 0x1f8,
.VGA2offset = 0x1f8,
.VGAprogdata = (2 << 18) | (0x1f8 << 9) | 0x1f8,
.VCAprogdata = (4 << 18) | (0x07 << 9) | 0x07,
/* the specs recommend other values for VGA offsets,
but tests show they are wrong */
.VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0,
.VCAprogdata = (2 << 19) | (0x07 << 9) | 0x07,
.FILTune = 0x27f /* 0.41 V */
},
{
.symbolrate_low = 5000000,
.symbolrate_high = 14999999,
.VCAslope = 0x1f,
.VCAoffset = 0x1f,
.VGA1offset = 0x1e0,
.VGA2offset = 0x180,
.VGAprogdata = (2 << 18) | (0x180 << 9) | 0x1e0,
.VCAprogdata = (4 << 18) | (0x07 << 9) | 0x1f,
.VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0,
.VCAprogdata = (2 << 19) | (0x07 << 9) | 0x1f,
.FILTune = 0x317 /* 0.90 V */
},
{
.symbolrate_low = 15000000,
.symbolrate_high = 45000000,
.VCAslope = 0x3f,
.VCAoffset = 0x3f,
.VGA1offset = 0x180,
.VGA2offset = 0x100,
.VGAprogdata = (2 << 18) | (0x100 << 9) | 0x180,
.VCAprogdata = (4 << 18) | (0x07 << 9) | 0x3f,
.VGAprogdata = (1 << 19) | (0x100 << 9) | 0x180,
.VCAprogdata = (2 << 19) | (0x07 << 9) | 0x3f,
.FILTune = 0x145 /* 2.70 V */
},
};
@ -112,91 +106,80 @@ static struct
{
u32 freq_low;
u32 freq_high;
u32 bandselect;
u32 VCOdivider;
u32 VCOnumber;
u32 progdata;
} cx24123_bandselect_vals[] =
{
/* band 1 */
{
.freq_low = 950000,
.freq_high = 1018999,
.bandselect = 0x40,
.VCOdivider = 4,
.VCOnumber = 7,
.progdata = (0 << 18) | (0 << 9) | 0x40,
},
{
.freq_low = 1019000,
.freq_high = 1074999,
.bandselect = 0x80,
.VCOdivider = 4,
.VCOnumber = 8,
.progdata = (0 << 18) | (0 << 9) | 0x80,
.progdata = (0 << 19) | (0 << 9) | 0x40,
},
/* band 2 */
{
.freq_low = 1075000,
.freq_high = 1227999,
.bandselect = 0x01,
.VCOdivider = 2,
.VCOnumber = 1,
.progdata = (0 << 18) | (1 << 9) | 0x01,
.freq_high = 1177999,
.VCOdivider = 4,
.progdata = (0 << 19) | (0 << 9) | 0x80,
},
/* band 3 */
{
.freq_low = 1228000,
.freq_high = 1349999,
.bandselect = 0x02,
.freq_low = 1178000,
.freq_high = 1295999,
.VCOdivider = 2,
.VCOnumber = 2,
.progdata = (0 << 18) | (1 << 9) | 0x02,
.progdata = (0 << 19) | (1 << 9) | 0x01,
},
/* band 4 */
{
.freq_low = 1350000,
.freq_high = 1481999,
.bandselect = 0x04,
.freq_low = 1296000,
.freq_high = 1431999,
.VCOdivider = 2,
.VCOnumber = 3,
.progdata = (0 << 18) | (1 << 9) | 0x04,
.progdata = (0 << 19) | (1 << 9) | 0x02,
},
/* band 5 */
{
.freq_low = 1482000,
.freq_high = 1595999,
.bandselect = 0x08,
.freq_low = 1432000,
.freq_high = 1575999,
.VCOdivider = 2,
.VCOnumber = 4,
.progdata = (0 << 18) | (1 << 9) | 0x08,
.progdata = (0 << 19) | (1 << 9) | 0x04,
},
/* band 6 */
{
.freq_low = 1596000,
.freq_low = 1576000,
.freq_high = 1717999,
.bandselect = 0x10,
.VCOdivider = 2,
.VCOnumber = 5,
.progdata = (0 << 18) | (1 << 9) | 0x10,
.progdata = (0 << 19) | (1 << 9) | 0x08,
},
/* band 7 */
{
.freq_low = 1718000,
.freq_high = 1855999,
.bandselect = 0x20,
.VCOdivider = 2,
.VCOnumber = 6,
.progdata = (0 << 18) | (1 << 9) | 0x20,
.progdata = (0 << 19) | (1 << 9) | 0x10,
},
/* band 8 */
{
.freq_low = 1856000,
.freq_high = 2035999,
.bandselect = 0x40,
.VCOdivider = 2,
.VCOnumber = 7,
.progdata = (0 << 18) | (1 << 9) | 0x40,
.progdata = (0 << 19) | (1 << 9) | 0x20,
},
/* band 9 */
{
.freq_low = 2036000,
.freq_high = 2149999,
.bandselect = 0x80,
.freq_high = 2150000,
.VCOdivider = 2,
.VCOnumber = 8,
.progdata = (0 << 18) | (1 << 9) | 0x80,
.progdata = (0 << 19) | (1 << 9) | 0x40,
},
};
@ -207,49 +190,44 @@ static struct {
{
{0x00, 0x03}, /* Reset system */
{0x00, 0x00}, /* Clear reset */
{0x01, 0x3b}, /* Apply sensible defaults, from an i2c sniffer */
{0x03, 0x07},
{0x04, 0x10},
{0x05, 0x04},
{0x06, 0x31},
{0x0d, 0x02},
{0x0e, 0x03},
{0x0f, 0xfe},
{0x10, 0x01},
{0x14, 0x01},
{0x15, 0x98},
{0x16, 0x00},
{0x17, 0x01},
{0x1b, 0x05},
{0x1c, 0x80},
{0x1d, 0x00},
{0x1e, 0x00},
{0x20, 0x41},
{0x21, 0x15},
{0x27, 0x14},
{0x28, 0x46},
{0x29, 0x00},
{0x2a, 0xb0},
{0x2b, 0x73},
{0x2c, 0x00},
{0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */
{0x04, 0x10}, /* MPEG */
{0x05, 0x04}, /* MPEG */
{0x06, 0x31}, /* MPEG (default) */
{0x0b, 0x00}, /* Freq search start point (default) */
{0x0c, 0x00}, /* Demodulator sample gain (default) */
{0x0d, 0x02}, /* Frequency search range = Fsymbol / 4 (default) */
{0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */
{0x0f, 0xfe}, /* FEC search mask (all supported codes) */
{0x10, 0x01}, /* Default search inversion, no repeat (default) */
{0x16, 0x00}, /* Enable reading of frequency */
{0x17, 0x01}, /* Enable EsNO Ready Counter */
{0x1c, 0x80}, /* Enable error counter */
{0x20, 0x00}, /* Tuner burst clock rate = 500KHz */
{0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */
{0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */
{0x29, 0x00}, /* DiSEqC LNB_DC off */
{0x2a, 0xb0}, /* DiSEqC Parameters (default) */
{0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */
{0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */
{0x2d, 0x00},
{0x2e, 0x00},
{0x2f, 0x00},
{0x30, 0x00},
{0x31, 0x00},
{0x32, 0x8c},
{0x33, 0x00},
{0x32, 0x8c}, /* DiSEqC Parameters (default) */
{0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */
{0x34, 0x00},
{0x35, 0x03},
{0x36, 0x02},
{0x37, 0x3a},
{0x3a, 0x00}, /* Enable AGC accumulator */
{0x44, 0x00},
{0x45, 0x00},
{0x46, 0x05},
{0x56, 0x41},
{0x57, 0xff},
{0x67, 0x83},
{0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */
{0x36, 0x02}, /* DiSEqC Parameters (default) */
{0x37, 0x3a}, /* DiSEqC Parameters (default) */
{0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */
{0x44, 0x00}, /* Constellation (default) */
{0x45, 0x00}, /* Symbol count (default) */
{0x46, 0x0d}, /* Symbol rate estimator on (default) */
{0x56, 0x41}, /* Various (default) */
{0x57, 0xff}, /* Error Counter Window (default) */
{0x67, 0x83}, /* Non-DCII symbol clock */
};
static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
@ -258,6 +236,10 @@ static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
int err;
if (debug>1)
printk("cx24123: %s: write reg 0x%02x, value 0x%02x\n",
__FUNCTION__,reg, data);
if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
printk("%s: writereg error(err == %i, reg == 0x%02x,"
" data == 0x%02x)\n", __FUNCTION__, err, reg, data);
@ -274,6 +256,10 @@ static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data)
struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 };
int err;
if (debug>1)
printk("cx24123: %s: writeln addr=0x08, reg 0x%02x, value 0x%02x\n",
__FUNCTION__,reg, data);
if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
printk("%s: writelnbreg error (err == %i, reg == 0x%02x,"
" data == 0x%02x)\n", __FUNCTION__, err, reg, data);
@ -303,6 +289,9 @@ static int cx24123_readreg(struct cx24123_state* state, u8 reg)
return ret;
}
if (debug>1)
printk("cx24123: read reg 0x%02x, value 0x%02x\n",reg, ret);
return b1[0];
}
@ -313,17 +302,23 @@ static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg)
static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
{
u8 nom_reg = cx24123_readreg(state, 0x0e);
u8 auto_reg = cx24123_readreg(state, 0x10);
switch (inversion) {
case INVERSION_OFF:
cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) & 0x7f);
cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80);
dprintk("%s: inversion off\n",__FUNCTION__);
cx24123_writereg(state, 0x0e, nom_reg & ~0x80);
cx24123_writereg(state, 0x10, auto_reg | 0x80);
break;
case INVERSION_ON:
cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) | 0x80);
cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80);
dprintk("%s: inversion on\n",__FUNCTION__);
cx24123_writereg(state, 0x0e, nom_reg | 0x80);
cx24123_writereg(state, 0x10, auto_reg | 0x80);
break;
case INVERSION_AUTO:
cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) & 0x7f);
dprintk("%s: inversion auto\n",__FUNCTION__);
cx24123_writereg(state, 0x10, auto_reg & ~0x80);
break;
default:
return -EINVAL;
@ -338,92 +333,191 @@ static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_invers
val = cx24123_readreg(state, 0x1b) >> 7;
if (val == 0)
if (val == 0) {
dprintk("%s: read inversion off\n",__FUNCTION__);
*inversion = INVERSION_OFF;
else
} else {
dprintk("%s: read inversion on\n",__FUNCTION__);
*inversion = INVERSION_ON;
}
return 0;
}
static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
{
u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07;
if ( (fec < FEC_NONE) || (fec > FEC_AUTO) )
fec = FEC_AUTO;
/* Hardware has 5/11 and 3/5 but are never unused */
switch (fec) {
case FEC_NONE:
return cx24123_writereg(state, 0x0f, 0x01);
case FEC_1_2:
return cx24123_writereg(state, 0x0f, 0x02);
dprintk("%s: set FEC to 1/2\n",__FUNCTION__);
cx24123_writereg(state, 0x0e, nom_reg | 0x01);
cx24123_writereg(state, 0x0f, 0x02);
break;
case FEC_2_3:
return cx24123_writereg(state, 0x0f, 0x04);
dprintk("%s: set FEC to 2/3\n",__FUNCTION__);
cx24123_writereg(state, 0x0e, nom_reg | 0x02);
cx24123_writereg(state, 0x0f, 0x04);
break;
case FEC_3_4:
return cx24123_writereg(state, 0x0f, 0x08);
dprintk("%s: set FEC to 3/4\n",__FUNCTION__);
cx24123_writereg(state, 0x0e, nom_reg | 0x03);
cx24123_writereg(state, 0x0f, 0x08);
break;
case FEC_4_5:
dprintk("%s: set FEC to 4/5\n",__FUNCTION__);
cx24123_writereg(state, 0x0e, nom_reg | 0x04);
cx24123_writereg(state, 0x0f, 0x10);
break;
case FEC_5_6:
return cx24123_writereg(state, 0x0f, 0x20);
dprintk("%s: set FEC to 5/6\n",__FUNCTION__);
cx24123_writereg(state, 0x0e, nom_reg | 0x05);
cx24123_writereg(state, 0x0f, 0x20);
break;
case FEC_6_7:
dprintk("%s: set FEC to 6/7\n",__FUNCTION__);
cx24123_writereg(state, 0x0e, nom_reg | 0x06);
cx24123_writereg(state, 0x0f, 0x40);
break;
case FEC_7_8:
return cx24123_writereg(state, 0x0f, 0x80);
dprintk("%s: set FEC to 7/8\n",__FUNCTION__);
cx24123_writereg(state, 0x0e, nom_reg | 0x07);
cx24123_writereg(state, 0x0f, 0x80);
break;
case FEC_AUTO:
return cx24123_writereg(state, 0x0f, 0xae);
dprintk("%s: set FEC to auto\n",__FUNCTION__);
cx24123_writereg(state, 0x0f, 0xfe);
break;
default:
return -EOPNOTSUPP;
}
}
static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec)
{
int ret;
u8 val;
ret = cx24123_readreg (state, 0x1b);
if (ret < 0)
return ret;
val = ret & 0x07;
switch (val) {
case 1:
*fec = FEC_1_2;
break;
case 3:
*fec = FEC_2_3;
break;
case 4:
*fec = FEC_3_4;
break;
case 5:
*fec = FEC_4_5;
break;
case 6:
*fec = FEC_5_6;
break;
case 7:
*fec = FEC_7_8;
break;
case 2: /* *fec = FEC_3_5; break; */
case 0: /* *fec = FEC_5_11; break; */
*fec = FEC_AUTO;
break;
default:
*fec = FEC_NONE; // can't happen
}
return 0;
}
/* fixme: Symbol rates < 3MSps may not work because of precision loss */
static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec)
{
int ret;
ret = cx24123_readreg (state, 0x1b);
if (ret < 0)
return ret;
ret = ret & 0x07;
switch (ret) {
case 1:
*fec = FEC_1_2;
break;
case 2:
*fec = FEC_2_3;
break;
case 3:
*fec = FEC_3_4;
break;
case 4:
*fec = FEC_4_5;
break;
case 5:
*fec = FEC_5_6;
break;
case 6:
*fec = FEC_6_7;
break;
case 7:
*fec = FEC_7_8;
break;
default:
/* this can happen when there's no lock */
*fec = FEC_NONE;
}
return 0;
}
/* Approximation of closest integer of log2(a/b). It actually gives the
lowest integer i such that 2^i >= round(a/b) */
static u32 cx24123_int_log2(u32 a, u32 b)
{
u32 exp, nearest = 0;
u32 div = a / b;
if(a % b >= b / 2) ++div;
if(div < (1 << 31))
{
for(exp = 1; div > exp; nearest++)
exp += exp;
}
return nearest;
}
static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
{
u32 val;
u32 tmp, sample_rate, ratio, sample_gain;
u8 pll_mult;
val = (srate / 1185) * 100;
/* check if symbol rate is within limits */
if ((srate > state->ops.info.symbol_rate_max) ||
(srate < state->ops.info.symbol_rate_min))
return -EOPNOTSUPP;;
/* Compensate for scaling up, by removing 17 symbols per 1Msps */
val = val - (17 * (srate / 1000000));
/* choose the sampling rate high enough for the required operation,
while optimizing the power consumed by the demodulator */
if (srate < (XTAL*2)/2)
pll_mult = 2;
else if (srate < (XTAL*3)/2)
pll_mult = 3;
else if (srate < (XTAL*4)/2)
pll_mult = 4;
else if (srate < (XTAL*5)/2)
pll_mult = 5;
else if (srate < (XTAL*6)/2)
pll_mult = 6;
else if (srate < (XTAL*7)/2)
pll_mult = 7;
else if (srate < (XTAL*8)/2)
pll_mult = 8;
else
pll_mult = 9;
cx24123_writereg(state, 0x08, (val >> 16) & 0xff );
cx24123_writereg(state, 0x09, (val >> 8) & 0xff );
cx24123_writereg(state, 0x0a, (val ) & 0xff );
sample_rate = pll_mult * XTAL;
/*
SYSSymbolRate[21:0] = (srate << 23) / sample_rate
We have to use 32 bit unsigned arithmetic without precision loss.
The maximum srate is 45000000 or 0x02AEA540. This number has
only 6 clear bits on top, hence we can shift it left only 6 bits
at a time. Borrowed from cx24110.c
*/
tmp = srate << 6;
ratio = tmp / sample_rate;
tmp = (tmp % sample_rate) << 6;
ratio = (ratio << 6) + (tmp / sample_rate);
tmp = (tmp % sample_rate) << 6;
ratio = (ratio << 6) + (tmp / sample_rate);
tmp = (tmp % sample_rate) << 5;
ratio = (ratio << 5) + (tmp / sample_rate);
cx24123_writereg(state, 0x01, pll_mult * 6);
cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f );
cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff );
cx24123_writereg(state, 0x0a, (ratio ) & 0xff );
/* also set the demodulator sample gain */
sample_gain = cx24123_int_log2(sample_rate, srate);
tmp = cx24123_readreg(state, 0x0c) & ~0xe0;
cx24123_writereg(state, 0x0c, tmp | sample_gain << 5);
dprintk("%s: srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n", __FUNCTION__, srate, ratio, sample_rate, sample_gain);
return 0;
}
@ -437,6 +531,9 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
struct cx24123_state *state = fe->demodulator_priv;
u32 ndiv = 0, adiv = 0, vco_div = 0;
int i = 0;
int pump = 2;
int band = 0;
int num_bands = sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]);
/* Defaults for low freq, low rate */
state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
@ -444,38 +541,49 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
state->bandselectarg = cx24123_bandselect_vals[0].progdata;
vco_div = cx24123_bandselect_vals[0].VCOdivider;
/* For the given symbolerate, determine the VCA and VGA programming bits */
/* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */
for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++)
{
if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) &&
(cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) {
(cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) {
state->VCAarg = cx24123_AGC_vals[i].VCAprogdata;
state->VGAarg = cx24123_AGC_vals[i].VGAprogdata;
state->FILTune = cx24123_AGC_vals[i].FILTune;
}
}
/* For the given frequency, determine the bandselect programming bits */
for (i = 0; i < sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); i++)
/* determine the band to use */
if(force_band < 1 || force_band > num_bands)
{
if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) &&
(cx24123_bandselect_vals[i].freq_high >= p->frequency) ) {
state->bandselectarg = cx24123_bandselect_vals[i].progdata;
vco_div = cx24123_bandselect_vals[i].VCOdivider;
for (i = 0; i < num_bands; i++)
{
if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) &&
(cx24123_bandselect_vals[i].freq_high >= p->frequency) )
band = i;
}
}
else
band = force_band - 1;
state->bandselectarg = cx24123_bandselect_vals[band].progdata;
vco_div = cx24123_bandselect_vals[band].VCOdivider;
/* determine the charge pump current */
if ( p->frequency < (cx24123_bandselect_vals[band].freq_low + cx24123_bandselect_vals[band].freq_high)/2 )
pump = 0x01;
else
pump = 0x02;
/* Determine the N/A dividers for the requested lband freq (in kHz). */
/* Note: 10111 (kHz) is the Crystal Freq and divider of 10. */
ndiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) / 32) & 0x1ff;
adiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) % 32) & 0x1f;
/* Note: the reference divider R=10, frequency is in KHz, XTAL is in Hz */
ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff;
adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f;
if (adiv == 0)
adiv++;
ndiv++;
/* determine the correct pll frequency values. */
/* Command 11, refdiv 11, cpump polarity 1, cpump current 3mA 10. */
state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (2 << 14);
state->pllarg |= (ndiv << 5) | adiv;
/* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */
state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv;
return 0;
}
@ -489,6 +597,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
struct cx24123_state *state = fe->demodulator_priv;
unsigned long timeout;
dprintk("%s: pll writereg called, data=0x%08x\n",__FUNCTION__,data);
/* align the 21 bytes into to bit23 boundary */
data = data << 3;
@ -538,6 +648,9 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
{
struct cx24123_state *state = fe->demodulator_priv;
u8 val;
dprintk("frequency=%i\n", p->frequency);
if (cx24123_pll_calculate(fe, p) != 0) {
printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__);
@ -552,6 +665,14 @@ static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_paramet
cx24123_pll_writereg(fe, p, state->bandselectarg);
cx24123_pll_writereg(fe, p, state->pllarg);
/* set the FILTUNE voltage */
val = cx24123_readreg(state, 0x28) & ~0x3;
cx24123_writereg(state, 0x27, state->FILTune >> 2);
cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3));
dprintk("%s: pll tune VCA=%d, band=%d, pll=%d\n",__FUNCTION__,state->VCAarg,
state->bandselectarg,state->pllarg);
return 0;
}
@ -560,6 +681,8 @@ static int cx24123_initfe(struct dvb_frontend* fe)
struct cx24123_state *state = fe->demodulator_priv;
int i;
dprintk("%s: init frontend\n",__FUNCTION__);
/* Configure the demod to a good set of defaults */
for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
@ -587,10 +710,13 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
switch (voltage) {
case SEC_VOLTAGE_13:
dprintk("%s: isl6421 voltage = 13V\n",__FUNCTION__);
return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */
case SEC_VOLTAGE_18:
dprintk("%s: isl6421 voltage = 18V\n",__FUNCTION__);
return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */
case SEC_VOLTAGE_OFF:
dprintk("%s: isl5421 voltage off\n",__FUNCTION__);
return cx24123_writelnbreg(state, 0x0, val & 0x30);
default:
return -EINVAL;
@ -624,13 +750,93 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
return 0;
}
static int cx24123_send_diseqc_msg(struct dvb_frontend* fe,
struct dvb_diseqc_master_cmd *cmd)
/* wait for diseqc queue to become ready (or timeout) */
static void cx24123_wait_for_diseqc(struct cx24123_state *state)
{
/* fixme: Implement diseqc */
printk("%s: No support yet\n",__FUNCTION__);
unsigned long timeout = jiffies + msecs_to_jiffies(200);
while (!(cx24123_readreg(state, 0x29) & 0x40)) {
if(time_after(jiffies, timeout)) {
printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__);
break;
}
msleep(10);
}
}
return -ENOTSUPP;
static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
{
struct cx24123_state *state = fe->demodulator_priv;
int i, val;
dprintk("%s:\n",__FUNCTION__);
/* check if continuous tone has been stopped */
if (state->config->use_isl6421)
val = cx24123_readlnbreg(state, 0x00) & 0x10;
else
val = cx24123_readreg(state, 0x29) & 0x10;
if (val) {
printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
return -ENOTSUPP;
}
/* wait for diseqc queue ready */
cx24123_wait_for_diseqc(state);
/* select tone mode */
cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8);
for (i = 0; i < cmd->msg_len; i++)
cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
val = cx24123_readreg(state, 0x29);
cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
/* wait for diseqc message to finish sending */
cx24123_wait_for_diseqc(state);
return 0;
}
static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
{
struct cx24123_state *state = fe->demodulator_priv;
int val;
dprintk("%s:\n", __FUNCTION__);
/* check if continuous tone has been stoped */
if (state->config->use_isl6421)
val = cx24123_readlnbreg(state, 0x00) & 0x10;
else
val = cx24123_readreg(state, 0x29) & 0x10;
if (val) {
printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
return -ENOTSUPP;
}
cx24123_wait_for_diseqc(state);
/* select tone mode */
val = cx24123_readreg(state, 0x2a) & 0xf8;
cx24123_writereg(state, 0x2a, val | 0x04);
val = cx24123_readreg(state, 0x29);
if (burst == SEC_MINI_A)
cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
else if (burst == SEC_MINI_B)
cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08));
else
return -EINVAL;
cx24123_wait_for_diseqc(state);
return 0;
}
static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
@ -642,13 +848,15 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
*status = 0;
if (lock & 0x01)
*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
*status |= FE_HAS_SIGNAL;
if (sync & 0x02)
*status |= FE_HAS_CARRIER;
if (sync & 0x04)
*status |= FE_HAS_VITERBI;
if (sync & 0x08)
*status |= FE_HAS_CARRIER;
*status |= FE_HAS_SYNC;
if (sync & 0x80)
*status |= FE_HAS_SYNC | FE_HAS_LOCK;
*status |= FE_HAS_LOCK;
return 0;
}
@ -681,6 +889,8 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
else
state->snr = 0;
dprintk("%s: BER = %d, S/N index = %d\n",__FUNCTION__,state->lastber, state->snr);
*ber = state->lastber;
return 0;
@ -691,6 +901,8 @@ static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
struct cx24123_state *state = fe->demodulator_priv;
*signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
dprintk("%s: Signal strength = %d\n",__FUNCTION__,*signal_strength);
return 0;
}
@ -699,6 +911,8 @@ static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr)
struct cx24123_state *state = fe->demodulator_priv;
*snr = state->snr;
dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr);
return 0;
}
@ -707,6 +921,8 @@ static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
struct cx24123_state *state = fe->demodulator_priv;
*ucblocks = state->lastber;
dprintk("%s: ucblocks (ber) = %d\n",__FUNCTION__,*ucblocks);
return 0;
}
@ -714,6 +930,8 @@ static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
{
struct cx24123_state *state = fe->demodulator_priv;
dprintk("%s: set_frontend\n",__FUNCTION__);
if (state->config->set_ts_params)
state->config->set_ts_params(fe, 0);
@ -737,6 +955,8 @@ static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
{
struct cx24123_state *state = fe->demodulator_priv;
dprintk("%s: get_frontend\n",__FUNCTION__);
if (cx24123_get_inversion(state, &p->inversion) != 0) {
printk("%s: Failed to get inversion status\n",__FUNCTION__);
return -EREMOTEIO;
@ -763,8 +983,10 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
switch (tone) {
case SEC_TONE_ON:
dprintk("%s: isl6421 sec tone on\n",__FUNCTION__);
return cx24123_writelnbreg(state, 0x0, val | 0x10);
case SEC_TONE_OFF:
dprintk("%s: isl6421 sec tone off\n",__FUNCTION__);
return cx24123_writelnbreg(state, 0x0, val & 0x2f);
default:
printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
@ -855,12 +1077,13 @@ static struct dvb_frontend_ops cx24123_ops = {
.frequency_min = 950000,
.frequency_max = 2150000,
.frequency_stepsize = 1011, /* kHz for QPSK frontends */
.frequency_tolerance = 29500,
.frequency_tolerance = 5000,
.symbol_rate_min = 1000000,
.symbol_rate_max = 45000000,
.caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
FE_CAN_QPSK | FE_CAN_RECOVER
},
@ -875,12 +1098,16 @@ static struct dvb_frontend_ops cx24123_ops = {
.read_snr = cx24123_read_snr,
.read_ucblocks = cx24123_read_ucblocks,
.diseqc_send_master_cmd = cx24123_send_diseqc_msg,
.diseqc_send_burst = cx24123_diseqc_send_burst,
.set_tone = cx24123_set_tone,
.set_voltage = cx24123_set_voltage,
};
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
module_param(force_band, int, 0644);
MODULE_PARM_DESC(force_band, "Force a specific band select (1-9, default:off).");
MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware");
MODULE_AUTHOR("Steven Toth");

View File

@ -235,8 +235,8 @@ struct dvb_pll_desc dvb_pll_tdvs_tua6034 = {
.max = 863000000,
.count = 3,
.entries = {
{ 160000000, 44000000, 62500, 0xce, 0x01 },
{ 455000000, 44000000, 62500, 0xce, 0x02 },
{ 165000000, 44000000, 62500, 0xce, 0x01 },
{ 450000000, 44000000, 62500, 0xce, 0x02 },
{ 999999999, 44000000, 62500, 0xce, 0x04 },
},
};

View File

@ -1,6 +1,6 @@
config DVB_PLUTO2
tristate "Pluto2 cards"
depends on DVB_CORE && PCI
depends on DVB_CORE && PCI && I2C
select I2C
select I2C_ALGOBIT
select DVB_TDA1004X

View File

@ -1,3 +1,3 @@
obj-$(CONFIG_DVB_PLUTO2) = pluto2.o
obj-$(CONFIG_DVB_PLUTO2) += pluto2.o
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/

View File

@ -1,8 +1,7 @@
config DVB_AV7110
tristate "AV7110 cards"
depends on DVB_CORE && PCI
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select FW_LOADER
select VIDEO_DEV
select VIDEO_SAA7146_VV
select DVB_VES1820
select DVB_VES1X93
@ -59,7 +58,7 @@ config DVB_AV7110_OSD
config DVB_BUDGET
tristate "Budget cards"
depends on DVB_CORE && PCI
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select VIDEO_SAA7146
select DVB_STV0299
select DVB_VES1X93
@ -80,7 +79,7 @@ config DVB_BUDGET
config DVB_BUDGET_CI
tristate "Budget cards with onboard CI connector"
depends on DVB_CORE && PCI
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select VIDEO_SAA7146
select DVB_STV0297
select DVB_STV0299
@ -100,8 +99,7 @@ config DVB_BUDGET_CI
config DVB_BUDGET_AV
tristate "Budget cards with analog video inputs"
depends on DVB_CORE && PCI
select VIDEO_DEV
depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
select VIDEO_SAA7146_VV
select DVB_STV0299
select DVB_TDA1004X
@ -119,7 +117,7 @@ config DVB_BUDGET_AV
config DVB_BUDGET_PATCH
tristate "AV7110 cards with Budget Patch"
depends on DVB_CORE && DVB_BUDGET
depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1
select DVB_AV7110
select DVB_STV0299
select DVB_VES1X93

View File

@ -1190,8 +1190,6 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
SAA7146_HPS_SYNC_PORT_A);
saa7113_setinput(budget_av, 0);
} else {
ciintf_init(budget_av);
}
/* fixme: find some sane values here... */
@ -1211,6 +1209,10 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
budget_av->budget.dvb_adapter.priv = budget_av;
frontend_init(budget_av);
if (!budget_av->has_saa7113) {
ciintf_init(budget_av);
}
return 0;
}

View File

@ -71,6 +71,7 @@ struct budget_ci {
struct tasklet_struct msp430_irq_tasklet;
struct tasklet_struct ciintf_irq_tasklet;
int slot_status;
int ci_irq;
struct dvb_ca_en50221 ca;
char ir_dev_name[50];
u8 tuner_pll_address; /* used for philips_tdm1316l configs */
@ -276,8 +277,10 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
if (slot != 0)
return -EINVAL;
// trigger on RISING edge during reset so we know when READY is re-asserted
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
if (budget_ci->ci_irq) {
// trigger on RISING edge during reset so we know when READY is re-asserted
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
}
budget_ci->slot_status = SLOTSTATUS_RESET;
ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
msleep(1);
@ -370,11 +373,50 @@ static void ciintf_interrupt(unsigned long data)
}
}
static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
{
struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
unsigned int flags;
// ensure we don't get spurious IRQs during initialisation
if (!budget_ci->budget.ci_present)
return -EINVAL;
// read the CAM status
flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
if (flags & CICONTROL_CAMDETECT) {
// mark it as present if it wasn't before
if (budget_ci->slot_status & SLOTSTATUS_NONE) {
budget_ci->slot_status = SLOTSTATUS_PRESENT;
}
// during a RESET, we check if we can read from IO memory to see when CAM is ready
if (budget_ci->slot_status & SLOTSTATUS_RESET) {
if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
budget_ci->slot_status = SLOTSTATUS_READY;
}
}
} else {
budget_ci->slot_status = SLOTSTATUS_NONE;
}
if (budget_ci->slot_status != SLOTSTATUS_NONE) {
if (budget_ci->slot_status & SLOTSTATUS_READY) {
return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
}
return DVB_CA_EN50221_POLL_CAM_PRESENT;
}
return 0;
}
static int ciintf_init(struct budget_ci *budget_ci)
{
struct saa7146_dev *saa = budget_ci->budget.dev;
int flags;
int result;
int ci_version;
int ca_flags;
memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
@ -382,16 +424,29 @@ static int ciintf_init(struct budget_ci *budget_ci)
saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
// test if it is there
if ((ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0) & 0xa0) != 0xa0) {
ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
if ((ci_version & 0xa0) != 0xa0) {
result = -ENODEV;
goto error;
}
// determine whether a CAM is present or not
flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
budget_ci->slot_status = SLOTSTATUS_NONE;
if (flags & CICONTROL_CAMDETECT)
budget_ci->slot_status = SLOTSTATUS_PRESENT;
// version 0xa2 of the CI firmware doesn't generate interrupts
if (ci_version == 0xa2) {
ca_flags = 0;
budget_ci->ci_irq = 0;
} else {
ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
DVB_CA_EN50221_FLAG_IRQ_FR |
DVB_CA_EN50221_FLAG_IRQ_DA;
budget_ci->ci_irq = 1;
}
// register CI interface
budget_ci->ca.owner = THIS_MODULE;
budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
@ -401,23 +456,27 @@ static int ciintf_init(struct budget_ci *budget_ci)
budget_ci->ca.slot_reset = ciintf_slot_reset;
budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
budget_ci->ca.data = budget_ci;
if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
&budget_ci->ca,
DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
DVB_CA_EN50221_FLAG_IRQ_FR |
DVB_CA_EN50221_FLAG_IRQ_DA, 1)) != 0) {
ca_flags, 1)) != 0) {
printk("budget_ci: CI interface detected, but initialisation failed.\n");
goto error;
}
// Setup CI slot IRQ
tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
if (budget_ci->slot_status != SLOTSTATUS_NONE) {
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
} else {
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
if (budget_ci->ci_irq) {
tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
if (budget_ci->slot_status != SLOTSTATUS_NONE) {
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
} else {
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
}
saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
}
saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
// enable interface
ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
CICONTROL_RESET, 1, 0);
@ -426,10 +485,12 @@ static int ciintf_init(struct budget_ci *budget_ci)
budget_ci->budget.ci_present = 1;
// forge a fake CI IRQ so the CAM state is setup correctly
flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
if (budget_ci->slot_status != SLOTSTATUS_NONE)
flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
if (budget_ci->ci_irq) {
flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
if (budget_ci->slot_status != SLOTSTATUS_NONE)
flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
}
return 0;
@ -443,9 +504,13 @@ static void ciintf_deinit(struct budget_ci *budget_ci)
struct saa7146_dev *saa = budget_ci->budget.dev;
// disable CI interrupts
saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
tasklet_kill(&budget_ci->ciintf_irq_tasklet);
if (budget_ci->ci_irq) {
saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
tasklet_kill(&budget_ci->ciintf_irq_tasklet);
}
// reset interface
ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
msleep(1);
ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
@ -473,7 +538,7 @@ static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
if (*isr & MASK_10)
ttpci_budget_irq10_handler(dev, isr);
if ((*isr & MASK_03) && (budget_ci->budget.ci_present))
if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
}

View File

@ -1507,7 +1507,11 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
mutex_unlock(&ttusb->semi2c);
dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE);
if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE)) < 0) {
ttusb_free_iso_urbs(ttusb);
kfree(ttusb);
return result;
}
ttusb->adapter.priv = ttusb;
/* i2c */

View File

@ -7,7 +7,7 @@ menu "Radio Adapters"
config RADIO_CADET
tristate "ADS Cadet AM/FM Tuner"
depends on ISA && VIDEO_DEV
depends on ISA && VIDEO_V4L1
---help---
Choose Y here if you have one of these AM/FM radio cards, and then
fill in the port address below.
@ -25,7 +25,7 @@ config RADIO_CADET
config RADIO_RTRACK
tristate "AIMSlab RadioTrack (aka RadioReveal) support"
depends on ISA && VIDEO_DEV
depends on ISA && VIDEO_V4L1
---help---
Choose Y here if you have one of these FM radio cards, and then fill
in the port address below.
@ -59,7 +59,7 @@ config RADIO_RTRACK_PORT
config RADIO_RTRACK2
tristate "AIMSlab RadioTrack II support"
depends on ISA && VIDEO_DEV
depends on ISA && VIDEO_V4L1
---help---
Choose Y here if you have this FM radio card, and then fill in the
port address below.
@ -82,7 +82,7 @@ config RADIO_RTRACK2_PORT
config RADIO_AZTECH
tristate "Aztech/Packard Bell Radio"
depends on ISA && VIDEO_DEV
depends on ISA && VIDEO_V4L1
---help---
Choose Y here if you have one of these FM radio cards, and then fill
in the port address below.
@ -106,7 +106,7 @@ config RADIO_AZTECH_PORT
config RADIO_GEMTEK
tristate "GemTek Radio Card support"
depends on ISA && VIDEO_DEV
depends on ISA && VIDEO_V4L1
---help---
Choose Y here if you have this FM radio card, and then fill in the
port address below.
@ -131,7 +131,7 @@ config RADIO_GEMTEK_PORT
config RADIO_GEMTEK_PCI
tristate "GemTek PCI Radio Card support"
depends on VIDEO_DEV && PCI
depends on VIDEO_V4L1 && PCI
---help---
Choose Y here if you have this PCI FM radio card.
@ -145,7 +145,7 @@ config RADIO_GEMTEK_PCI
config RADIO_MAXIRADIO
tristate "Guillemot MAXI Radio FM 2000 radio"
depends on VIDEO_DEV && PCI
depends on VIDEO_V4L1 && PCI
---help---
Choose Y here if you have this radio card. This card may also be
found as Gemtek PCI FM.
@ -160,7 +160,7 @@ config RADIO_MAXIRADIO
config RADIO_MAESTRO
tristate "Maestro on board radio"
depends on VIDEO_DEV
depends on VIDEO_V4L1
---help---
Say Y here to directly support the on-board radio tuner on the
Maestro 2 or 2E sound card.
@ -175,7 +175,7 @@ config RADIO_MAESTRO
config RADIO_MIROPCM20
tristate "miroSOUND PCM20 radio"
depends on ISA && VIDEO_DEV && SOUND_ACI_MIXER
depends on ISA && VIDEO_V4L1 && SOUND_ACI_MIXER
---help---
Choose Y here if you have this FM radio card. You also need to say Y
to "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)" (in "Sound")
@ -208,7 +208,7 @@ config RADIO_MIROPCM20_RDS
config RADIO_SF16FMI
tristate "SF16FMI Radio"
depends on ISA && VIDEO_DEV
depends on ISA && VIDEO_V4L1
---help---
Choose Y here if you have one of these FM radio cards. If you
compile the driver into the kernel and your card is not PnP one, you
@ -225,7 +225,7 @@ config RADIO_SF16FMI
config RADIO_SF16FMR2
tristate "SF16FMR2 Radio"
depends on ISA && VIDEO_DEV
depends on ISA && VIDEO_V4L1
---help---
Choose Y here if you have one of these FM radio cards.
@ -239,7 +239,7 @@ config RADIO_SF16FMR2
config RADIO_TERRATEC
tristate "TerraTec ActiveRadio ISA Standalone"
depends on ISA && VIDEO_DEV
depends on ISA && VIDEO_V4L1
---help---
Choose Y here if you have this FM radio card, and then fill in the
port address below. (TODO)
@ -268,7 +268,7 @@ config RADIO_TERRATEC_PORT
config RADIO_TRUST
tristate "Trust FM radio card"
depends on ISA && VIDEO_DEV
depends on ISA && VIDEO_V4L1
help
This is a driver for the Trust FM radio cards. Say Y if you have
such a card and want to use it under Linux.
@ -286,7 +286,7 @@ config RADIO_TRUST_PORT
config RADIO_TYPHOON
tristate "Typhoon Radio (a.k.a. EcoRadio)"
depends on ISA && VIDEO_DEV
depends on ISA && VIDEO_V4L1
---help---
Choose Y here if you have one of these FM radio cards, and then fill
in the port address and the frequency used for muting below.
@ -330,7 +330,7 @@ config RADIO_TYPHOON_MUTEFREQ
config RADIO_ZOLTRIX
tristate "Zoltrix Radio"
depends on ISA && VIDEO_DEV
depends on ISA && VIDEO_V4L1
---help---
Choose Y here if you have one of these FM radio cards, and then fill
in the port address below.

View File

@ -2,10 +2,10 @@
# Multimedia Video device configuration
#
menu "Video For Linux"
menu "Video Capture Adapters"
depends on VIDEO_DEV
comment "Video Adapters"
comment "Video Capture Adapters"
config VIDEO_ADV_DEBUG
bool "Enable advanced debug functionality"
@ -16,11 +16,23 @@ config VIDEO_ADV_DEBUG
V4L devices.
In doubt, say N.
config VIDEO_VIVI
tristate "Virtual Video Driver"
depends on VIDEO_V4L2 && !SPARC32 && !SPARC64
select VIDEO_BUF
default n
---help---
Enables a virtual video driver. This device shows a color bar
and a timestamp, as a real device would generate by using V4L2
api.
Say Y here if you want to test video apps or debug V4L devices.
In doubt, say N.
source "drivers/media/video/bt8xx/Kconfig"
config VIDEO_SAA6588
tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
depends on VIDEO_DEV && I2C && VIDEO_BT848
depends on I2C && VIDEO_BT848
help
Support for Radio Data System (RDS) decoder. This allows seeing
@ -32,7 +44,7 @@ config VIDEO_SAA6588
config VIDEO_PMS
tristate "Mediavision Pro Movie Studio Video For Linux"
depends on VIDEO_DEV && ISA
depends on ISA && VIDEO_V4L1
help
Say Y if you have such a thing.
@ -41,7 +53,7 @@ config VIDEO_PMS
config VIDEO_PLANB
tristate "PlanB Video-In on PowerMac"
depends on PPC_PMAC && VIDEO_DEV && BROKEN
depends on PPC_PMAC && VIDEO_V4L1 && BROKEN
help
PlanB is the V4L driver for the PowerMac 7x00/8x00 series video
input hardware. If you want to experiment with this, say Y.
@ -52,7 +64,7 @@ config VIDEO_PLANB
config VIDEO_BWQCAM
tristate "Quickcam BW Video For Linux"
depends on VIDEO_DEV && PARPORT
depends on PARPORT && VIDEO_V4L1
help
Say Y have if you the black and white version of the QuickCam
camera. See the next option for the color version.
@ -62,7 +74,7 @@ config VIDEO_BWQCAM
config VIDEO_CQCAM
tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)"
depends on EXPERIMENTAL && VIDEO_DEV && PARPORT
depends on EXPERIMENTAL && PARPORT && VIDEO_V4L1
help
This is the video4linux driver for the colour version of the
Connectix QuickCam. If you have one of these cameras, say Y here,
@ -73,7 +85,7 @@ config VIDEO_CQCAM
config VIDEO_W9966
tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux"
depends on PARPORT_1284 && VIDEO_DEV && PARPORT
depends on PARPORT_1284 && PARPORT && VIDEO_V4L1
help
Video4linux driver for Winbond's w9966 based Webcams.
Currently tested with the LifeView FlyCam Supra.
@ -86,7 +98,7 @@ config VIDEO_W9966
config VIDEO_CPIA
tristate "CPiA Video For Linux"
depends on VIDEO_DEV
depends on VIDEO_V4L1
---help---
This is the video4linux driver for cameras based on Vision's CPiA
(Colour Processor Interface ASIC), such as the Creative Labs Video
@ -123,7 +135,7 @@ source "drivers/media/video/cpia2/Kconfig"
config VIDEO_SAA5246A
tristate "SAA5246A, SAA5281 Teletext processor"
depends on VIDEO_DEV && I2C
depends on I2C && VIDEO_V4L1
help
Support for I2C bus based teletext using the SAA5246A or SAA5281
chip. Useful only if you live in Europe.
@ -150,7 +162,7 @@ config TUNER_3036
config VIDEO_VINO
tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
depends on VIDEO_DEV && I2C && SGI_IP22 && EXPERIMENTAL
depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L1
select I2C_ALGO_SGI
help
Say Y here to build in support for the Vino video input system found
@ -158,7 +170,7 @@ config VIDEO_VINO
config VIDEO_STRADIS
tristate "Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)"
depends on EXPERIMENTAL && VIDEO_DEV && PCI
depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && !PPC64
help
Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video
driver for PCI. There is a product page at
@ -166,7 +178,7 @@ config VIDEO_STRADIS
config VIDEO_ZORAN
tristate "Zoran ZR36057/36067 Video For Linux"
depends on VIDEO_DEV && PCI && I2C_ALGOBIT
depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && !PPC64
help
Say Y for support for MJPEG capture cards based on the Zoran
36057/36067 PCI controller chipset. This includes the Iomega
@ -214,7 +226,7 @@ config VIDEO_ZORAN_LML33R10
config VIDEO_ZR36120
tristate "Zoran ZR36120/36125 Video For Linux"
depends on VIDEO_DEV && PCI && I2C && BROKEN
depends on PCI && I2C && VIDEO_V4L1 && BROKEN
help
Support for ZR36120/ZR36125 based frame grabber/overlay boards.
This includes the Victor II, WaveWatcher, Video Wonder, Maxi-TV,
@ -226,7 +238,7 @@ config VIDEO_ZR36120
config VIDEO_MEYE
tristate "Sony Vaio Picturebook Motion Eye Video For Linux"
depends on VIDEO_DEV && PCI && SONYPI
depends on PCI && SONYPI && VIDEO_V4L1
---help---
This is the video4linux driver for the Motion Eye camera found
in the Vaio Picturebook laptops. Please read the material in
@ -242,7 +254,7 @@ source "drivers/media/video/saa7134/Kconfig"
config VIDEO_MXB
tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
depends on VIDEO_DEV && PCI
depends on PCI && VIDEO_V4L1
select VIDEO_SAA7146_VV
select VIDEO_TUNER
---help---
@ -254,8 +266,9 @@ config VIDEO_MXB
config VIDEO_DPC
tristate "Philips-Semiconductors 'dpc7146 demonstration board'"
depends on VIDEO_DEV && PCI
depends on PCI && VIDEO_V4L1
select VIDEO_SAA7146_VV
select VIDEO_V4L2
---help---
This is a video4linux driver for the 'dpc7146 demonstration
board' by Philips-Semiconductors. It's the reference design
@ -268,8 +281,9 @@ config VIDEO_DPC
config VIDEO_HEXIUM_ORION
tristate "Hexium HV-PCI6 and Orion frame grabber"
depends on VIDEO_DEV && PCI
depends on PCI && VIDEO_V4L1
select VIDEO_SAA7146_VV
select VIDEO_V4L2
---help---
This is a video4linux driver for the Hexium HV-PCI6 and
Orion frame grabber cards by Hexium.
@ -279,8 +293,9 @@ config VIDEO_HEXIUM_ORION
config VIDEO_HEXIUM_GEMINI
tristate "Hexium Gemini frame grabber"
depends on VIDEO_DEV && PCI
depends on PCI && VIDEO_V4L1
select VIDEO_SAA7146_VV
select VIDEO_V4L2
---help---
This is a video4linux driver for the Hexium Gemini frame
grabber card by Hexium. Please note that the Gemini Dual
@ -293,7 +308,7 @@ source "drivers/media/video/cx88/Kconfig"
config VIDEO_OVCAMCHIP
tristate "OmniVision Camera Chip support"
depends on VIDEO_DEV && I2C
depends on I2C && VIDEO_V4L1
---help---
Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
This driver is intended to be used with the ov511 and w9968cf USB
@ -304,7 +319,7 @@ config VIDEO_OVCAMCHIP
config VIDEO_M32R_AR
tristate "AR devices"
depends on M32R
depends on M32R && VIDEO_V4L1
---help---
This is a video4linux driver for the Renesas AR (Artificial Retina)
camera module.
@ -365,17 +380,17 @@ config VIDEO_WM8739
source "drivers/media/video/cx25840/Kconfig"
config VIDEO_SAA711X
tristate "Philips SAA7113/4/5 video decoders"
depends on VIDEO_DEV && I2C && EXPERIMENTAL
tristate "Philips SAA7113/4/5 video decoders (OBSOLETED)"
depends on VIDEO_V4L1 && I2C && EXPERIMENTAL
---help---
Support for the Philips SAA7113/4/5 video decoders.
Old support for the Philips SAA7113/4 video decoders.
To compile this driver as a module, choose M here: the
module will be called saa7115.
config VIDEO_SAA7127
tristate "Philips SAA7127/9 digital video encoders"
depends on VIDEO_DEV && I2C && EXPERIMENTAL
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
---help---
Support for the Philips SAA7127/9 digital video encoders.
@ -384,7 +399,7 @@ config VIDEO_SAA7127
config VIDEO_UPD64031A
tristate "NEC Electronics uPD64031A Ghost Reduction"
depends on VIDEO_DEV && I2C && EXPERIMENTAL
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
---help---
Support for the NEC Electronics uPD64031A Ghost Reduction
video chip. It is most often found in NTSC TV cards made for
@ -396,7 +411,7 @@ config VIDEO_UPD64031A
config VIDEO_UPD64083
tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
depends on VIDEO_DEV && I2C && EXPERIMENTAL
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
---help---
Support for the NEC Electronics uPD64083 3-Dimensional Y/C
separation video chip. It is used to improve the quality of
@ -418,7 +433,7 @@ source "drivers/media/video/em28xx/Kconfig"
config USB_DSBR
tristate "D-Link USB FM radio support (EXPERIMENTAL)"
depends on USB && VIDEO_DEV && EXPERIMENTAL
depends on USB && VIDEO_V4L1 && EXPERIMENTAL
---help---
Say Y here if you want to connect this type of radio to your
computer's USB port. Note that the audio is not digital, and
@ -434,7 +449,7 @@ source "drivers/media/video/et61x251/Kconfig"
config USB_OV511
tristate "USB OV511 Camera support"
depends on USB && VIDEO_DEV
depends on USB && VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. See <file:Documentation/video4linux/ov511.txt>
@ -445,7 +460,7 @@ config USB_OV511
config USB_SE401
tristate "USB SE401 Camera support"
depends on USB && VIDEO_DEV
depends on USB && VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. See <file:Documentation/video4linux/se401.txt>
@ -458,7 +473,7 @@ source "drivers/media/video/sn9c102/Kconfig"
config USB_STV680
tristate "USB STV680 (Pencam) Camera support"
depends on USB && VIDEO_DEV
depends on USB && VIDEO_V4L1
---help---
Say Y here if you want to connect this type of camera to your
computer's USB port. This includes the Pencam line of cameras.
@ -470,7 +485,7 @@ config USB_STV680
config USB_W9968CF
tristate "USB W996[87]CF JPEG Dual Mode Camera support"
depends on USB && VIDEO_DEV && I2C
depends on USB && VIDEO_V4L1 && I2C
select VIDEO_OVCAMCHIP
---help---
Say Y here if you want support for cameras based on OV681 or

View File

@ -10,7 +10,11 @@ tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \
msp3400-objs := msp3400-driver.o msp3400-kthreads.o
obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o
obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o
ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
endif
obj-$(CONFIG_VIDEO_BT848) += bt8xx/
obj-$(CONFIG_VIDEO_BT848) += tvaudio.o tda7432.o tda9875.o ir-kbd-i2c.o
@ -84,4 +88,8 @@ obj-$(CONFIG_USB_IBMCAM) += usbvideo/
obj-$(CONFIG_USB_KONICAWC) += usbvideo/
obj-$(CONFIG_USB_VICAM) += usbvideo/
obj-$(CONFIG_VIDEO_VIVI) += vivi.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
extra-cflags-$(CONFIG_VIDEO_V4L1_COMPAT) += -DCONFIG_VIDEO_V4L1_COMPAT

View File

@ -1,6 +1,6 @@
config VIDEO_BT848
tristate "BT848 Video For Linux"
depends on VIDEO_DEV && PCI && I2C
depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2
select I2C_ALGOBIT
select FW_LOADER
select VIDEO_BTCX

View File

@ -8,5 +8,5 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
obj-$(CONFIG_VIDEO_BT848) += bttv.o
EXTRA_CFLAGS += -I$(src)/..
EXTRA_CFLAGS += -Idrivers/media/video
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core

View File

@ -2991,13 +2991,13 @@ void __devinit bttv_idcard(struct bttv *btv)
if (UNSET != audiomux[0]) {
gpiobits = 0;
for (i = 0; i < 5; i++) {
for (i = 0; i < 4; i++) {
bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i];
gpiobits |= audiomux[i];
}
} else {
gpiobits = audioall;
for (i = 0; i < 5; i++) {
for (i = 0; i < 4; i++) {
bttv_tvcards[btv->c.type].gpiomux[i] = audioall;
}
}

View File

@ -233,7 +233,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
const struct bttv_format *fmt, struct bttv_overlay *ov,
int skip_even, int skip_odd)
{
int instructions,rc,line,maxy,start,end,skip,nskips;
int dwords,rc,line,maxy,start,end,skip,nskips;
struct btcx_skiplist *skips;
u32 *rp,ri,ra;
u32 addr;
@ -242,12 +242,12 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
return -ENOMEM;
/* estimate risc mem: worst case is (clip+1) * lines instructions
/* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
+ sync + jump (all 2 dwords) */
instructions = (ov->nclips + 1) *
((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height);
instructions += 2;
if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) {
dwords = (3 * ov->nclips + 2) *
((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
dwords += 4;
if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
kfree(skips);
return rc;
}
@ -276,8 +276,6 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
if (line > maxy)
btcx_calc_skips(line, ov->w.width, &maxy,
skips, &nskips, ov->clips, ov->nclips);
else
nskips = 0;
/* write out risc code */
for (start = 0, skip = 0; start < ov->w.width; start = end) {

View File

@ -39,29 +39,12 @@
#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 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 void start_fw_load(struct i2c_client *client)
{
/* DL_ADDR_LB=0 DL_ADDR_HB=0 */
@ -71,16 +54,10 @@ static void start_fw_load(struct i2c_client *client)
cx25840_write(client, 0x803, 0x0b);
/* AUTO_INC_DIS=1 */
cx25840_write(client, 0x000, 0x20);
if (fastfw)
set_i2c_delay(client, 3);
}
static 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 */
@ -107,30 +84,8 @@ static int fw_write(struct i2c_client *client, u8 * data, int size)
int sent;
if ((sent = i2c_master_send(client, data, size)) < size) {
if (fastfw) {
v4l_err(client, "333MHz i2c firmware load failed\n");
fastfw = 0;
set_i2c_delay(client, 10);
if (sent > 2) {
u16 dl_addr = cx25840_read(client, 0x801) << 8;
dl_addr |= cx25840_read(client, 0x800);
dl_addr -= sent - 2;
cx25840_write(client, 0x801, dl_addr >> 8);
cx25840_write(client, 0x800, dl_addr & 0xff);
}
if (i2c_master_send(client, data, size) < size) {
v4l_err(client, "100MHz i2c firmware load failed\n");
return -ENOSYS;
}
} else {
v4l_err(client, "firmware load i2c failure\n");
return -ENOSYS;
}
v4l_err(client, "firmware load i2c failure\n");
return -ENOSYS;
}
return 0;

View File

@ -564,7 +564,7 @@ struct cx88_board cx88_boards[] = {
},
[CX88_BOARD_PCHDTV_HD3000] = {
.name = "pcHDTV HD3000 HDTV",
.tuner_type = TUNER_THOMSON_DTT7610,
.tuner_type = TUNER_THOMSON_DTT761X,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,

View File

@ -146,9 +146,11 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
fields++;
/* estimate risc mem: worst case is one write per page border +
one write per scan line + syncs + jump (all 2 dwords) */
instructions = (bpl * lines * fields) / PAGE_SIZE + lines * fields;
instructions += 3 + 4;
one write per scan line + syncs + jump (all 2 dwords). Padding
can cause next bpl to start close to a page border. First DMA
region may be smaller than PAGE_SIZE */
instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
instructions += 2;
if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
return rc;
@ -176,9 +178,11 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
int rc;
/* estimate risc mem: worst case is one write per page border +
one write per scan line + syncs + jump (all 2 dwords) */
instructions = (bpl * lines) / PAGE_SIZE + lines;
instructions += 3 + 4;
one write per scan line + syncs + jump (all 2 dwords). Here
there is no padding and no sync. First DMA region may be smaller
than PAGE_SIZE */
instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
instructions += 1;
if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
return rc;

View File

@ -372,7 +372,7 @@ static int or51132_set_ts_param(struct dvb_frontend* fe,
static struct or51132_config pchdtv_hd3000 = {
.demod_address = 0x15,
.pll_address = 0x61,
.pll_desc = &dvb_pll_thomson_dtt7610,
.pll_desc = &dvb_pll_thomson_dtt761x,
.set_ts_params = or51132_set_ts_param,
};
#endif

View File

@ -35,8 +35,10 @@
#include "cx88.h"
#include <media/v4l2-common.h>
#ifdef CONFIG_VIDEO_V4L1_COMPAT
/* Include V4L1 specific functions. Should be removed soon */
#include <linux/videodev.h>
#endif
MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");

View File

@ -1,6 +1,6 @@
config VIDEO_EM28XX
tristate "Empia EM2800/2820/2840 USB video capture support"
depends on VIDEO_DEV && USB && I2C
depends on VIDEO_V4L1 && USB && I2C
select VIDEO_BUF
select VIDEO_TUNER
select VIDEO_TVEEPROM

View File

@ -1576,8 +1576,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
errCode = em28xx_config(dev);
if (errCode) {
em28xx_errdev("error configuring device\n");
kfree(dev);
em28xx_devused&=~(1<<dev->devno);
kfree(dev);
return -ENOMEM;
}
@ -1603,8 +1603,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
dev->vdev = video_device_alloc();
if (NULL == dev->vdev) {
em28xx_errdev("cannot allocate video_device.\n");
kfree(dev);
em28xx_devused&=~(1<<dev->devno);
kfree(dev);
return -ENOMEM;
}
@ -1612,8 +1612,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
if (NULL == dev->vbi_dev) {
em28xx_errdev("cannot allocate video_device.\n");
kfree(dev->vdev);
kfree(dev);
em28xx_devused&=~(1<<dev->devno);
kfree(dev);
return -ENOMEM;
}
@ -1650,8 +1650,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
mutex_unlock(&dev->lock);
list_del(&dev->devlist);
video_device_release(dev->vdev);
kfree(dev);
em28xx_devused&=~(1<<dev->devno);
kfree(dev);
return -ENODEV;
}
@ -1662,8 +1662,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
list_del(&dev->devlist);
video_device_release(dev->vbi_dev);
video_device_release(dev->vdev);
kfree(dev);
em28xx_devused&=~(1<<dev->devno);
kfree(dev);
return -ENODEV;
} else {
printk("registered VBI\n");

View File

@ -1,6 +1,6 @@
config USB_ET61X251
tristate "USB ET61X[12]51 PC Camera Controller support"
depends on USB && VIDEO_DEV
depends on USB && VIDEO_V4L1
---help---
Say Y here if you want support for cameras based on Etoms ET61X151
or ET61X251 PC Camera Controllers.

View File

@ -1,6 +1,6 @@
config USB_PWC
tristate "USB Philips Cameras"
depends on USB && VIDEO_DEV
depends on USB && VIDEO_V4L1
---help---
Say Y or M here if you want to use one of these Philips & OEM
webcams:

View File

@ -1,20 +1,3 @@
ifneq ($(KERNELRELEASE),)
pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o
obj-$(CONFIG_USB_PWC) += pwc.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
endif
clean:
rm -f *.[oas] .*.flags *.ko .*.cmd .*.d .*.tmp *.mod.c
rm -rf .tmp_versions

View File

@ -142,6 +142,7 @@ struct i2c_reg_value {
static const struct i2c_reg_value saa7129_init_config_extra[] = {
{ SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 },
{ SAA7127_REG_VTRIG, 0xfa },
{ 0, 0 }
};
static const struct i2c_reg_value saa7127_init_config_common[] = {

View File

@ -3504,6 +3504,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
/* power-up tuner chip */
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
break;
case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
/* this turns the remote control chip off to work around a bug in it */
saa_writeb(SAA7134_GPIO_GPMODE1, 0x80);

View File

@ -548,6 +548,8 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
if (report & SAA7134_IRQ_REPORT_GPIO16) {
switch (dev->has_remote) {
case SAA7134_REMOTE_GPIO:
if (!dev->remote)
break;
if (dev->remote->mask_keydown & 0x10000) {
saa7134_input_irq(dev);
}
@ -564,6 +566,8 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
if (report & SAA7134_IRQ_REPORT_GPIO18) {
switch (dev->has_remote) {
case SAA7134_REMOTE_GPIO:
if (!dev->remote)
break;
if ((dev->remote->mask_keydown & 0x40000) ||
(dev->remote->mask_keyup & 0x40000)) {
saa7134_input_irq(dev);
@ -676,7 +680,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
SAA7134_IRQ2_INTE_PE |
SAA7134_IRQ2_INTE_AR;
if (dev->has_remote == SAA7134_REMOTE_GPIO) {
if (dev->has_remote == SAA7134_REMOTE_GPIO && dev->remote) {
if (dev->remote->mask_keydown & 0x10000)
irq2_mask |= SAA7134_IRQ2_INTE_GPIO16;
else if (dev->remote->mask_keydown & 0x40000)

View File

@ -31,8 +31,10 @@
#include "saa7134.h"
#include <media/v4l2-common.h>
#ifdef CONFIG_VIDEO_V4L1_COMPAT
/* Include V4L1 specific functions. Should be removed soon */
#include <linux/videodev.h>
#endif
/* ------------------------------------------------------------------ */

View File

@ -1,6 +1,6 @@
config USB_SN9C102
tristate "USB SN9C10x PC Camera Controller support"
depends on USB && VIDEO_DEV
depends on USB && VIDEO_V4L1
---help---
Say Y here if you want support for cameras based on SONiX SN9C101,
SN9C102 or SN9C103 PC Camera Controllers.

View File

@ -877,8 +877,8 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = {
/* ------------ TUNER_LG_TDVS_H062F - INFINEON ATSC ------------ */
static struct tuner_range tuner_tua6034_ntsc_ranges[] = {
{ 16 * 160.00 /*MHz*/, 0x8e, 0x01 },
{ 16 * 455.00 /*MHz*/, 0x8e, 0x02 },
{ 16 * 165.00 /*MHz*/, 0x8e, 0x01 },
{ 16 * 450.00 /*MHz*/, 0x8e, 0x02 },
{ 16 * 999.99 , 0x8e, 0x04 },
};

View File

@ -218,7 +218,7 @@ hauppauge_tuner[] =
/* 110-119 */
{ TUNER_ABSENT, "Thompson DTT75105"},
{ TUNER_ABSENT, "Conexant_CX24109"},
{ TUNER_ABSENT, "TCL M2523_5N_E"},
{ TUNER_TCL_2002N, "TCL M2523_5N_E"},
{ TUNER_ABSENT, "TCL M2523_3DB_E"},
{ TUNER_ABSENT, "Philips 8275A"},
{ TUNER_ABSENT, "Microtune MT2060"},

View File

@ -3,7 +3,7 @@ config VIDEO_USBVIDEO
config USB_VICAM
tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
depends on USB && VIDEO_DEV && EXPERIMENTAL
depends on USB && VIDEO_V4L1 && EXPERIMENTAL
select VIDEO_USBVIDEO
---help---
Say Y here if you have 3com homeconnect camera (vicam).
@ -13,7 +13,7 @@ config USB_VICAM
config USB_IBMCAM
tristate "USB IBM (Xirlink) C-it Camera support"
depends on USB && VIDEO_DEV
depends on USB && VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
Say Y here if you want to connect a IBM "C-It" camera, also known as
@ -28,7 +28,7 @@ config USB_IBMCAM
config USB_KONICAWC
tristate "USB Konica Webcam support"
depends on USB && VIDEO_DEV
depends on USB && VIDEO_V4L1
select VIDEO_USBVIDEO
---help---
Say Y here if you want support for webcams based on a Konica

View File

@ -26,6 +26,11 @@
#include <linux/random.h>
#include <linux/version.h>
#include <linux/videodev2.h>
#include <linux/dma-mapping.h>
#ifdef CONFIG_VIDEO_V4L1_COMPAT
/* Include V4L1 specific functions. Should be removed soon */
#include <linux/videodev.h>
#endif
#include <linux/interrupt.h>
#include <media/video-buf.h>
#include <media/v4l2-common.h>

View File

@ -1,6 +1,6 @@
config USB_ZC0301
tristate "USB ZC0301 Image Processor and Control Chip support"
depends on USB && VIDEO_DEV
depends on USB && VIDEO_V4L1
---help---
Say Y here if you want support for cameras based on the ZC0301
Image Processor and Control Chip.

View File

@ -55,8 +55,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "1.4.39"
#define DRV_MODULE_RELDATE "March 22, 2006"
#define DRV_MODULE_VERSION "1.4.40"
#define DRV_MODULE_RELDATE "May 22, 2006"
#define RUN_AT(x) (jiffies + (x))
@ -2945,7 +2945,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
int buf_size)
{
u32 written, offset32, len32;
u8 *buf, start[4], end[4];
u8 *buf, start[4], end[4], *flash_buffer = NULL;
int rc = 0;
int align_start, align_end;
@ -2985,12 +2985,19 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
memcpy(buf + align_start, data_buf, buf_size);
}
if (bp->flash_info->buffered == 0) {
flash_buffer = kmalloc(264, GFP_KERNEL);
if (flash_buffer == NULL) {
rc = -ENOMEM;
goto nvram_write_end;
}
}
written = 0;
while ((written < len32) && (rc == 0)) {
u32 page_start, page_end, data_start, data_end;
u32 addr, cmd_flags;
int i;
u8 flash_buffer[264];
/* Find the page_start addr */
page_start = offset32 + written;
@ -3061,7 +3068,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
}
/* Loop to write the new data from data_start to data_end */
for (addr = data_start; addr < data_end; addr += 4, i++) {
for (addr = data_start; addr < data_end; addr += 4, i += 4) {
if ((addr == page_end - 4) ||
((bp->flash_info->buffered) &&
(addr == data_end - 4))) {
@ -3109,6 +3116,9 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
}
nvram_write_end:
if (bp->flash_info->buffered == 0)
kfree(flash_buffer);
if (align_start || align_end)
kfree(buf);
return rc;

View File

@ -2891,78 +2891,6 @@ static int nv_open(struct net_device *dev)
goto out_drain;
}
if (np->msi_flags & NV_MSI_X_CAPABLE) {
for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) {
np->msi_x_entry[i].entry = i;
}
if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) {
np->msi_flags |= NV_MSI_X_ENABLED;
if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) {
/* Request irq for rx handling */
if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_drain;
}
/* Request irq for tx handling */
if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, SA_SHIRQ, dev->name, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_drain;
}
/* Request irq for link and timer handling */
if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, SA_SHIRQ, dev->name, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_drain;
}
/* map interrupts to their respective vector */
writel(0, base + NvRegMSIXMap0);
writel(0, base + NvRegMSIXMap1);
set_msix_vector_map(dev, NV_MSI_X_VECTOR_RX, NVREG_IRQ_RX_ALL);
set_msix_vector_map(dev, NV_MSI_X_VECTOR_TX, NVREG_IRQ_TX_ALL);
set_msix_vector_map(dev, NV_MSI_X_VECTOR_OTHER, NVREG_IRQ_OTHER);
} else {
/* Request irq for all interrupts */
if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_drain;
}
/* map interrupts to vector 0 */
writel(0, base + NvRegMSIXMap0);
writel(0, base + NvRegMSIXMap1);
}
}
}
if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
np->msi_flags |= NV_MSI_ENABLED;
if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
pci_disable_msi(np->pci_dev);
np->msi_flags &= ~NV_MSI_ENABLED;
goto out_drain;
}
/* map interrupts to vector 0 */
writel(0, base + NvRegMSIMap0);
writel(0, base + NvRegMSIMap1);
/* enable msi vector 0 */
writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask);
}
}
if (ret != 0) {
if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0)
goto out_drain;
}
/* ask for interrupts */
nv_enable_hw_interrupts(dev, np->irqmask);

View File

@ -1691,17 +1691,6 @@ static void do_set_multicast_list(struct net_device *dev)
memset(ei_local->mcfilter, 0xFF, 8);
}
/*
* DP8390 manuals don't specify any magic sequence for altering
* the multicast regs on an already running card. To be safe, we
* ensure multicast mode is off prior to loading up the new hash
* table. If this proves to be not enough, we can always resort
* to stopping the NIC, loading the table and then restarting.
*/
if (netif_running(dev))
outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR);
outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD);
for(i = 0; i < 8; i++)
{
@ -1715,6 +1704,8 @@ static void do_set_multicast_list(struct net_device *dev)
outb_p(E8390_RXCONFIG | 0x48, e8390_base + EN0_RXCR);
else
outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR);
outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD);
}
/*

View File

@ -78,8 +78,7 @@ static const struct pci_device_id skge_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) },
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) }, /* DGE-530T */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */
{ PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) },
@ -402,7 +401,7 @@ static int skge_set_ring_param(struct net_device *dev,
int err;
if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE ||
p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE)
p->tx_pending < MAX_SKB_FRAGS+1 || p->tx_pending > MAX_TX_RING_SIZE)
return -EINVAL;
skge->rx_ring.count = p->rx_pending;
@ -2717,8 +2716,7 @@ static int skge_poll(struct net_device *dev, int *budget)
if (control & BMU_OWN)
break;
skb = skge_rx_get(skge, e, control, rd->status,
le16_to_cpu(rd->csum2));
skb = skge_rx_get(skge, e, control, rd->status, rd->csum2);
if (likely(skb)) {
dev->last_rx = jiffies;
netif_receive_skb(skb);

View File

@ -51,7 +51,7 @@
#include "sky2.h"
#define DRV_NAME "sky2"
#define DRV_VERSION "1.3"
#define DRV_VERSION "1.4"
#define PFX DRV_NAME " "
/*
@ -105,6 +105,7 @@ MODULE_PARM_DESC(idle_timeout, "Idle timeout workaround for lost interrupts (ms)
static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
@ -235,6 +236,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state)
}
if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON);
sky2_pci_write32(hw, PCI_DEV_REG3, 0);
reg1 = sky2_pci_read32(hw, PCI_DEV_REG4);
reg1 &= P_ASPM_CONTROL_MSK;
@ -306,7 +308,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
u16 ctrl, ct1000, adv, pg, ledctrl, ledover;
if (sky2->autoneg == AUTONEG_ENABLE &&
(hw->chip_id != CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
!(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
@ -1020,19 +1022,26 @@ static int sky2_up(struct net_device *dev)
struct sky2_hw *hw = sky2->hw;
unsigned port = sky2->port;
u32 ramsize, rxspace, imask;
int err;
int cap, err = -ENOMEM;
struct net_device *otherdev = hw->dev[sky2->port^1];
/* Block bringing up both ports at the same time on a dual port card.
* There is an unfixed bug where receiver gets confused and picks up
* packets out of order. Until this is fixed, prevent data corruption.
/*
* On dual port PCI-X card, there is an problem where status
* can be received out of order due to split transactions
*/
if (otherdev && netif_running(otherdev)) {
printk(KERN_INFO PFX "dual port support is disabled.\n");
return -EBUSY;
}
if (otherdev && netif_running(otherdev) &&
(cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) {
struct sky2_port *osky2 = netdev_priv(otherdev);
u16 cmd;
cmd = sky2_pci_read16(hw, cap + PCI_X_CMD);
cmd &= ~PCI_X_CMD_MAX_SPLIT;
sky2_pci_write16(hw, cap + PCI_X_CMD, cmd);
sky2->rx_csum = 0;
osky2->rx_csum = 0;
}
err = -ENOMEM;
if (netif_msg_ifup(sky2))
printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
@ -1910,6 +1919,12 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
}
}
/* Is status ring empty or is there more to do? */
static inline int sky2_more_work(const struct sky2_hw *hw)
{
return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX));
}
/* Process status response ring */
static int sky2_status_intr(struct sky2_hw *hw, int to_do)
{
@ -2182,19 +2197,19 @@ static int sky2_poll(struct net_device *dev0, int *budget)
if (status & Y2_IS_CHK_TXA2)
sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
if (status & Y2_IS_STAT_BMU)
sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
work_done = sky2_status_intr(hw, work_limit);
*budget -= work_done;
dev0->quota -= work_done;
if (work_done >= work_limit)
if (status & Y2_IS_STAT_BMU)
sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
if (sky2_more_work(hw))
return 1;
netif_rx_complete(dev0);
status = sky2_read32(hw, B0_Y2_SP_LISR);
sky2_read32(hw, B0_Y2_SP_LISR);
return 0;
}
@ -3078,12 +3093,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
sky2->duplex = -1;
sky2->speed = -1;
sky2->advertising = sky2_supported_modes(hw);
/* Receive checksum disabled for Yukon XL
* because of observed problems with incorrect
* values when multiple packets are received in one interrupt
*/
sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
sky2->rx_csum = 1;
spin_lock_init(&sky2->phy_lock);
sky2->tx_pending = TX_DEF_PENDING;

View File

@ -214,6 +214,8 @@ enum csr_regs {
enum {
Y2_VMAIN_AVAIL = 1<<17,/* VMAIN available (YUKON-2 only) */
Y2_VAUX_AVAIL = 1<<16,/* VAUX available (YUKON-2 only) */
Y2_HW_WOL_ON = 1<<15,/* HW WOL On (Yukon-EC Ultra A1 only) */
Y2_HW_WOL_OFF = 1<<14,/* HW WOL On (Yukon-EC Ultra A1 only) */
Y2_ASF_ENABLE = 1<<13,/* ASF Unit Enable (YUKON-2 only) */
Y2_ASF_DISABLE = 1<<12,/* ASF Unit Disable (YUKON-2 only) */
Y2_CLK_RUN_ENA = 1<<11,/* CLK_RUN Enable (YUKON-2 only) */

View File

@ -69,8 +69,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "3.57"
#define DRV_MODULE_RELDATE "Apr 28, 2006"
#define DRV_MODULE_VERSION "3.58"
#define DRV_MODULE_RELDATE "May 22, 2006"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@ -6488,6 +6488,10 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp)
TG3_STAT_ADD32(&sp->rx_frame_too_long_errors, MAC_RX_STATS_FRAME_TOO_LONG);
TG3_STAT_ADD32(&sp->rx_jabbers, MAC_RX_STATS_JABBERS);
TG3_STAT_ADD32(&sp->rx_undersize_packets, MAC_RX_STATS_UNDERSIZE);
TG3_STAT_ADD32(&sp->rxbds_empty, RCVLPC_NO_RCV_BD_CNT);
TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT);
TG3_STAT_ADD32(&sp->rx_errors, RCVLPC_IN_ERRORS_CNT);
}
static void tg3_timer(unsigned long __opaque)

View File

@ -850,7 +850,7 @@ static void init_rxtx_rings(struct net_device *dev)
break;
skb->dev = dev; /* Mark as being used by this device. */
np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data,
skb->len,PCI_DMA_FROMDEVICE);
np->rx_buf_sz,PCI_DMA_FROMDEVICE);
np->rx_ring[i].buffer1 = np->rx_addr[i];
np->rx_ring[i].status = DescOwn;
@ -1316,7 +1316,7 @@ static int netdev_rx(struct net_device *dev)
skb->dev = dev; /* Mark as being used by this device. */
np->rx_addr[entry] = pci_map_single(np->pci_dev,
skb->data,
skb->len, PCI_DMA_FROMDEVICE);
np->rx_buf_sz, PCI_DMA_FROMDEVICE);
np->rx_ring[entry].buffer1 = np->rx_addr[entry];
}
wmb();

View File

@ -491,8 +491,6 @@ struct rhine_private {
u8 tx_thresh, rx_thresh;
struct mii_if_info mii_if;
struct work_struct tx_timeout_task;
struct work_struct check_media_task;
void __iomem *base;
};
@ -500,8 +498,6 @@ static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
static int rhine_open(struct net_device *dev);
static void rhine_tx_timeout(struct net_device *dev);
static void rhine_tx_timeout_task(struct net_device *dev);
static void rhine_check_media_task(struct net_device *dev);
static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static void rhine_tx(struct net_device *dev);
@ -856,12 +852,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
if (rp->quirks & rqRhineI)
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
INIT_WORK(&rp->tx_timeout_task,
(void (*)(void *))rhine_tx_timeout_task, dev);
INIT_WORK(&rp->check_media_task,
(void (*)(void *))rhine_check_media_task, dev);
/* dev->name not defined before register_netdev()! */
rc = register_netdev(dev);
if (rc)
@ -1108,11 +1098,6 @@ static void rhine_set_carrier(struct mii_if_info *mii)
netif_carrier_ok(mii->dev));
}
static void rhine_check_media_task(struct net_device *dev)
{
rhine_check_media(dev, 0);
}
static void init_registers(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
@ -1166,8 +1151,8 @@ static void rhine_disable_linkmon(void __iomem *ioaddr, u32 quirks)
if (quirks & rqRhineI) {
iowrite8(0x01, ioaddr + MIIRegAddr); // MII_BMSR
/* Do not call from ISR! */
msleep(1);
/* Can be called from ISR. Evil. */
mdelay(1);
/* 0x80 must be set immediately before turning it off */
iowrite8(0x80, ioaddr + MIICmd);
@ -1255,16 +1240,6 @@ static int rhine_open(struct net_device *dev)
}
static void rhine_tx_timeout(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
/*
* Move bulk of work outside of interrupt context
*/
schedule_work(&rp->tx_timeout_task);
}
static void rhine_tx_timeout_task(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
void __iomem *ioaddr = rp->base;
@ -1677,7 +1652,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
spin_lock(&rp->lock);
if (intr_status & IntrLinkChange)
schedule_work(&rp->check_media_task);
rhine_check_media(dev, 0);
if (intr_status & IntrStatsMax) {
rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
@ -1927,9 +1902,6 @@ static int rhine_close(struct net_device *dev)
spin_unlock_irq(&rp->lock);
free_irq(rp->pdev->irq, dev);
flush_scheduled_work();
free_rbufs(dev);
free_tbufs(dev);
free_ring(dev);

View File

@ -3271,6 +3271,9 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)
bcm43xx_sysfs_register(bcm);
//FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though...
/*FIXME: This should be handled by softmac instead. */
schedule_work(&bcm->softmac->associnfo.work);
assert(err == 0);
out:
return err;
@ -3946,9 +3949,6 @@ static int bcm43xx_resume(struct pci_dev *pdev)
netif_device_attach(net_dev);
/*FIXME: This should be handled by softmac instead. */
schedule_work(&bcm->softmac->associnfo.work);
dprintk(KERN_INFO PFX "Device resumed.\n");
return 0;

View File

@ -812,7 +812,6 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
if (datalen > IEEE80211_DATA_LEN + 12) {
printk(KERN_DEBUG "%s: oversized monitor frame, "
"data length = %d\n", dev->name, datalen);
err = -EIO;
stats->rx_length_errors++;
goto update_stats;
}
@ -821,8 +820,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
if (!skb) {
printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
dev->name);
err = -ENOMEM;
goto drop;
goto update_stats;
}
/* Copy the 802.11 header to the skb */

View File

@ -33,13 +33,10 @@ acpi_query_osc (
acpi_status status;
struct acpi_object_list input;
union acpi_object in_params[4];
struct acpi_buffer output;
union acpi_object out_obj;
struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
union acpi_object *out_obj;
u32 osc_dw0;
/* Setting up output buffer */
output.length = sizeof(out_obj) + 3*sizeof(u32);
output.pointer = &out_obj;
/* Setting up input parameters */
input.count = 4;
@ -61,12 +58,15 @@ acpi_query_osc (
"Evaluate _OSC Set fails. Status = 0x%04x\n", status);
return status;
}
if (out_obj.type != ACPI_TYPE_BUFFER) {
out_obj = output.pointer;
if (out_obj->type != ACPI_TYPE_BUFFER) {
printk(KERN_DEBUG
"Evaluate _OSC returns wrong type\n");
return AE_TYPE;
status = AE_TYPE;
goto query_osc_out;
}
osc_dw0 = *((u32 *) out_obj.buffer.pointer);
osc_dw0 = *((u32 *) out_obj->buffer.pointer);
if (osc_dw0) {
if (osc_dw0 & OSC_REQUEST_ERROR)
printk(KERN_DEBUG "_OSC request fails\n");
@ -76,15 +76,21 @@ acpi_query_osc (
printk(KERN_DEBUG "_OSC invalid revision\n");
if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
/* Update Global Control Set */
global_ctrlsets = *((u32 *)(out_obj.buffer.pointer+8));
return AE_OK;
global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8));
status = AE_OK;
goto query_osc_out;
}
return AE_ERROR;
status = AE_ERROR;
goto query_osc_out;
}
/* Update Global Control Set */
global_ctrlsets = *((u32 *)(out_obj.buffer.pointer + 8));
return AE_OK;
global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
status = AE_OK;
query_osc_out:
kfree(output.pointer);
return status;
}
@ -96,14 +102,10 @@ acpi_run_osc (
acpi_status status;
struct acpi_object_list input;
union acpi_object in_params[4];
struct acpi_buffer output;
union acpi_object out_obj;
struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
union acpi_object *out_obj;
u32 osc_dw0;
/* Setting up output buffer */
output.length = sizeof(out_obj) + 3*sizeof(u32);
output.pointer = &out_obj;
/* Setting up input parameters */
input.count = 4;
input.pointer = in_params;
@ -124,12 +126,14 @@ acpi_run_osc (
"Evaluate _OSC Set fails. Status = 0x%04x\n", status);
return status;
}
if (out_obj.type != ACPI_TYPE_BUFFER) {
out_obj = output.pointer;
if (out_obj->type != ACPI_TYPE_BUFFER) {
printk(KERN_DEBUG
"Evaluate _OSC returns wrong type\n");
return AE_TYPE;
status = AE_TYPE;
goto run_osc_out;
}
osc_dw0 = *((u32 *) out_obj.buffer.pointer);
osc_dw0 = *((u32 *) out_obj->buffer.pointer);
if (osc_dw0) {
if (osc_dw0 & OSC_REQUEST_ERROR)
printk(KERN_DEBUG "_OSC request fails\n");
@ -139,11 +143,17 @@ acpi_run_osc (
printk(KERN_DEBUG "_OSC invalid revision\n");
if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
printk(KERN_DEBUG "_OSC FW not grant req. control\n");
return AE_SUPPORT;
status = AE_SUPPORT;
goto run_osc_out;
}
return AE_ERROR;
status = AE_ERROR;
goto run_osc_out;
}
return AE_OK;
status = AE_OK;
run_osc_out:
kfree(output.pointer);
return status;
}
/**

View File

@ -589,7 +589,7 @@ static int pd6729_check_irq(int irq, int flags)
return 0;
}
static u_int __init pd6729_isa_scan(void)
static u_int __devinit pd6729_isa_scan(void)
{
u_int mask0, mask = 0;
int i;

View File

@ -141,13 +141,13 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
/* try the driver's ioctl interface */
if (ops->ioctl) {
err = ops->ioctl(class_dev->dev, cmd, arg);
if (err != -EINVAL)
if (err != -ENOIOCTLCMD)
return err;
}
/* if the driver does not provide the ioctl interface
* or if that particular ioctl was not implemented
* (-EINVAL), we will try to emulate here.
* (-ENOIOCTLCMD), we will try to emulate here.
*/
switch (cmd) {
@ -233,7 +233,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
break;
default:
err = -EINVAL;
err = -ENOTTY;
break;
}

View File

@ -247,7 +247,7 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
rtc_freq = arg;
return 0;
}
return -EINVAL;
return -ENOIOCTLCMD;
}
static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm)

View File

@ -71,7 +71,7 @@ static int test_rtc_ioctl(struct device *dev, unsigned int cmd,
return 0;
default:
return -EINVAL;
return -ENOIOCTLCMD;
}
}

View File

@ -270,7 +270,7 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
epoch = arg;
break;
default:
return -EINVAL;
return -ENOIOCTLCMD;
}
return 0;

View File

@ -4054,7 +4054,7 @@ static int st_probe(struct device *dev)
}
sdev_printk(KERN_WARNING, SDp,
"Attached scsi tape %s", tape_name(tpnt));
"Attached scsi tape %s\n", tape_name(tpnt));
printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n",
tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
queue_dma_alignment(SDp->request_queue) + 1);

View File

@ -1730,3 +1730,4 @@ static void __exit sunsu_exit(void)
module_init(sunsu_probe);
module_exit(sunsu_exit);
MODULE_LICENSE("GPL");

View File

@ -75,6 +75,18 @@ config SPI_BUTTERFLY
inexpensive battery powered microcontroller evaluation board.
This same cable can be used to flash new firmware.
config SPI_MPC83xx
tristate "Freescale MPC83xx SPI controller"
depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL
select SPI_BITBANG
help
This enables using the Freescale MPC83xx SPI controller in master
mode.
Note, this driver uniquely supports the SPI controller on the MPC83xx
family of PowerPC processors. The MPC83xx uses a simple set of shift
registers for data (opposed to the CPM based descriptor model).
config SPI_PXA2XX
tristate "PXA2xx SSP SPI master"
depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL
@ -83,11 +95,25 @@ config SPI_PXA2XX
The driver can be configured to use any SSP port and additional
documentation can be found a Documentation/spi/pxa2xx.
config SPI_S3C24XX_GPIO
tristate "Samsung S3C24XX series SPI by GPIO"
depends on SPI_MASTER && ARCH_S3C2410 && SPI_BITBANG && EXPERIMENTAL
help
SPI driver for Samsung S3C24XX series ARM SoCs using
GPIO lines to provide the SPI bus. This can be used where
the inbuilt hardware cannot provide the transfer mode, or
where the board is using non hardware connected pins.
#
# Add new SPI master controllers in alphabetical order above this line
#
config SPI_S3C24XX
tristate "Samsung S3C24XX series SPI"
depends on SPI_MASTER && ARCH_S3C2410 && EXPERIMENTAL
help
SPI driver for Samsung S3C24XX series ARM SoCs
#
# There are lots of SPI device types, with sensors and memory
# being probably the most widely used ones.

View File

@ -14,6 +14,9 @@ obj-$(CONFIG_SPI_MASTER) += spi.o
obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o
obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
# ... add above this line ...
# SPI protocol drivers (device/link on bus)

View File

@ -363,25 +363,30 @@ static void unmap_dma_buffers(struct driver_data *drv_data)
}
/* caller already set message->status; dma and pio irqs are blocked */
static void giveback(struct spi_message *message, struct driver_data *drv_data)
static void giveback(struct driver_data *drv_data)
{
struct spi_transfer* last_transfer;
unsigned long flags;
struct spi_message *msg;
last_transfer = list_entry(message->transfers.prev,
spin_lock_irqsave(&drv_data->lock, flags);
msg = drv_data->cur_msg;
drv_data->cur_msg = NULL;
drv_data->cur_transfer = NULL;
drv_data->cur_chip = NULL;
queue_work(drv_data->workqueue, &drv_data->pump_messages);
spin_unlock_irqrestore(&drv_data->lock, flags);
last_transfer = list_entry(msg->transfers.prev,
struct spi_transfer,
transfer_list);
if (!last_transfer->cs_change)
drv_data->cs_control(PXA2XX_CS_DEASSERT);
message->state = NULL;
if (message->complete)
message->complete(message->context);
drv_data->cur_msg = NULL;
drv_data->cur_transfer = NULL;
drv_data->cur_chip = NULL;
queue_work(drv_data->workqueue, &drv_data->pump_messages);
msg->state = NULL;
if (msg->complete)
msg->complete(msg->context);
}
static int wait_ssp_rx_stall(void *ioaddr)
@ -415,10 +420,11 @@ static void dma_handler(int channel, void *data, struct pt_regs *regs)
if (irq_status & DCSR_BUSERR) {
/* Disable interrupts, clear status and reset DMA */
write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
if (drv_data->ssp_type != PXA25x_SSP)
write_SSTO(0, reg);
write_SSSR(drv_data->clear_sr, reg);
write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
@ -454,8 +460,8 @@ static void dma_handler(int channel, void *data, struct pt_regs *regs)
"dma_handler: ssp rx stall failed\n");
/* Clear and disable interrupts on SSP and DMA channels*/
write_SSSR(drv_data->clear_sr, reg);
write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
write_SSSR(drv_data->clear_sr, reg);
DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
if (wait_dma_channel_stop(drv_data->rx_channel) == 0)
@ -497,10 +503,11 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data)
irq_status = read_SSSR(reg) & drv_data->mask_sr;
if (irq_status & SSSR_ROR) {
/* Clear and disable interrupts on SSP and DMA channels*/
write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
if (drv_data->ssp_type != PXA25x_SSP)
write_SSTO(0, reg);
write_SSSR(drv_data->clear_sr, reg);
write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
unmap_dma_buffers(drv_data);
@ -526,10 +533,10 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data)
if (irq_status & SSSR_TINT || drv_data->rx == drv_data->rx_end) {
/* Clear and disable interrupts on SSP and DMA channels*/
write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
if (drv_data->ssp_type != PXA25x_SSP)
write_SSTO(0, reg);
write_SSSR(drv_data->clear_sr, reg);
write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
@ -572,26 +579,30 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data)
static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
{
u32 irq_status;
struct spi_message *msg = drv_data->cur_msg;
void *reg = drv_data->ioaddr;
irqreturn_t handled = IRQ_NONE;
unsigned long limit = loops_per_jiffy << 1;
u32 irq_status;
u32 irq_mask = (read_SSCR1(reg) & SSCR1_TIE) ?
drv_data->mask_sr : drv_data->mask_sr & ~SSSR_TFS;
while ((irq_status = (read_SSSR(reg) & drv_data->mask_sr))) {
while ((irq_status = read_SSSR(reg) & irq_mask)) {
if (irq_status & SSSR_ROR) {
/* Clear and disable interrupts */
write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
if (drv_data->ssp_type != PXA25x_SSP)
write_SSTO(0, reg);
write_SSSR(drv_data->clear_sr, reg);
write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
if (flush(drv_data) == 0)
dev_err(&drv_data->pdev->dev,
"interrupt_transfer: flush fail\n");
/* Stop the SSP */
dev_warn(&drv_data->pdev->dev,
"interrupt_transfer: fifo overun\n");
@ -613,6 +624,7 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
if (drv_data->tx == drv_data->tx_end) {
/* Disable tx interrupt */
write_SSCR1(read_SSCR1(reg) & ~SSCR1_TIE, reg);
irq_mask = drv_data->mask_sr & ~SSSR_TFS;
/* PXA25x_SSP has no timeout, read trailing bytes */
if (drv_data->ssp_type == PXA25x_SSP) {
@ -630,10 +642,10 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
|| (drv_data->rx == drv_data->rx_end)) {
/* Clear timeout */
write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
if (drv_data->ssp_type != PXA25x_SSP)
write_SSTO(0, reg);
write_SSSR(drv_data->clear_sr, reg);
write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
/* Update total byte transfered */
msg->actual_length += drv_data->len;
@ -648,24 +660,29 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
/* Schedule transfer tasklet */
tasklet_schedule(&drv_data->pump_transfers);
return IRQ_HANDLED;
}
/* We did something */
handled = IRQ_HANDLED;
}
return handled;
/* We did something */
return IRQ_HANDLED;
}
static irqreturn_t ssp_int(int irq, void *dev_id, struct pt_regs *regs)
{
struct driver_data *drv_data = (struct driver_data *)dev_id;
void *reg = drv_data->ioaddr;
if (!drv_data->cur_msg) {
write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
if (drv_data->ssp_type != PXA25x_SSP)
write_SSTO(0, reg);
write_SSSR(drv_data->clear_sr, reg);
dev_err(&drv_data->pdev->dev, "bad message state "
"in interrupt handler\n");
"in interrupt handler");
/* Never fail */
return IRQ_HANDLED;
}
@ -694,14 +711,14 @@ static void pump_transfers(unsigned long data)
/* Handle for abort */
if (message->state == ERROR_STATE) {
message->status = -EIO;
giveback(message, drv_data);
giveback(drv_data);
return;
}
/* Handle end of message */
if (message->state == DONE_STATE) {
message->status = 0;
giveback(message, drv_data);
giveback(drv_data);
return;
}
@ -718,7 +735,7 @@ static void pump_transfers(unsigned long data)
if (flush(drv_data) == 0) {
dev_err(&drv_data->pdev->dev, "pump_transfers: flush failed\n");
message->status = -EIO;
giveback(message, drv_data);
giveback(drv_data);
return;
}
drv_data->n_bytes = chip->n_bytes;
@ -782,7 +799,7 @@ static void pump_transfers(unsigned long data)
cr0 = clk_div
| SSCR0_Motorola
| SSCR0_DataSize(bits & 0x0f)
| SSCR0_DataSize(bits > 16 ? bits - 16 : bits)
| SSCR0_SSE
| (bits > 16 ? SSCR0_EDSS : 0);
@ -890,8 +907,6 @@ static void pump_messages(void *data)
drv_data->cur_msg = list_entry(drv_data->queue.next,
struct spi_message, queue);
list_del_init(&drv_data->cur_msg->queue);
drv_data->busy = 1;
spin_unlock_irqrestore(&drv_data->lock, flags);
/* Initial message state*/
drv_data->cur_msg->state = START_STATE;
@ -905,6 +920,9 @@ static void pump_messages(void *data)
/* Mark as busy and launch transfers */
tasklet_schedule(&drv_data->pump_transfers);
drv_data->busy = 1;
spin_unlock_irqrestore(&drv_data->lock, flags);
}
static int transfer(struct spi_device *spi, struct spi_message *msg)
@ -958,7 +976,7 @@ static int setup(struct spi_device *spi)
chip->cs_control = null_cs_control;
chip->enable_dma = 0;
chip->timeout = 5;
chip->timeout = SSP_TIMEOUT(1000);
chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1);
chip->dma_burst_size = drv_data->master_info->enable_dma ?
DCMD_BURST8 : 0;
@ -971,7 +989,7 @@ static int setup(struct spi_device *spi)
if (chip_info->cs_control)
chip->cs_control = chip_info->cs_control;
chip->timeout = (chip_info->timeout_microsecs * 10000) / 2712;
chip->timeout = SSP_TIMEOUT(chip_info->timeout_microsecs);
chip->threshold = SSCR1_RxTresh(chip_info->rx_threshold)
| SSCR1_TxTresh(chip_info->tx_threshold);
@ -1013,7 +1031,8 @@ static int setup(struct spi_device *spi)
chip->cr0 = clk_div
| SSCR0_Motorola
| SSCR0_DataSize(spi->bits_per_word & 0x0f)
| SSCR0_DataSize(spi->bits_per_word > 16 ?
spi->bits_per_word - 16 : spi->bits_per_word)
| SSCR0_SSE
| (spi->bits_per_word > 16 ? SSCR0_EDSS : 0);
chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) << 4)
@ -1196,7 +1215,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
goto out_error_master_alloc;
}
drv_data->ioaddr = (void *)io_p2v(memory_resource->start);
drv_data->ioaddr = (void *)io_p2v((unsigned long)(memory_resource->start));
drv_data->ssdr_physical = memory_resource->start + 0x00000010;
if (platform_info->ssp_type == PXA25x_SSP) {
drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE;
@ -1218,7 +1237,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
goto out_error_master_alloc;
}
status = request_irq(irq, ssp_int, SA_INTERRUPT, dev->bus_id, drv_data);
status = request_irq(irq, ssp_int, 0, dev->bus_id, drv_data);
if (status < 0) {
dev_err(&pdev->dev, "can not get IRQ\n");
goto out_error_master_alloc;

View File

@ -338,18 +338,18 @@ static struct class spi_master_class = {
* spi_alloc_master - allocate SPI master controller
* @dev: the controller, possibly using the platform_bus
* @size: how much driver-private data to preallocate; the pointer to this
* memory is in the class_data field of the returned class_device,
* memory is in the class_data field of the returned class_device,
* accessible with spi_master_get_devdata().
*
* This call is used only by SPI master controller drivers, which are the
* only ones directly touching chip registers. It's how they allocate
* an spi_master structure, prior to calling spi_add_master().
* an spi_master structure, prior to calling spi_register_master().
*
* This must be called from context that can sleep. It returns the SPI
* master structure on success, else NULL.
*
* The caller is responsible for assigning the bus number and initializing
* the master's methods before calling spi_add_master(); and (after errors
* the master's methods before calling spi_register_master(); and (after errors
* adding the device) calling spi_master_put() to prevent a memory leak.
*/
struct spi_master * __init_or_module

View File

@ -321,6 +321,7 @@ static void butterfly_attach(struct parport *p)
* (firmware resets at45, acts as spi slave) or neither (we ignore
* both, AVR uses AT45). Here we expect firmware for the first option.
*/
pp->info[0].max_speed_hz = 15 * 1000 * 1000;
strcpy(pp->info[0].modalias, "mtd_dataflash");
pp->info[0].platform_data = &flash;

483
drivers/spi/spi_mpc83xx.c Normal file
View File

@ -0,0 +1,483 @@
/*
* MPC83xx SPI controller driver.
*
* Maintainer: Kumar Gala
*
* Copyright (C) 2006 Polycom, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/platform_device.h>
#include <linux/fsl_devices.h>
#include <asm/irq.h>
#include <asm/io.h>
/* SPI Controller registers */
struct mpc83xx_spi_reg {
u8 res1[0x20];
__be32 mode;
__be32 event;
__be32 mask;
__be32 command;
__be32 transmit;
__be32 receive;
};
/* SPI Controller mode register definitions */
#define SPMODE_CI_INACTIVEHIGH (1 << 29)
#define SPMODE_CP_BEGIN_EDGECLK (1 << 28)
#define SPMODE_DIV16 (1 << 27)
#define SPMODE_REV (1 << 26)
#define SPMODE_MS (1 << 25)
#define SPMODE_ENABLE (1 << 24)
#define SPMODE_LEN(x) ((x) << 20)
#define SPMODE_PM(x) ((x) << 16)
/*
* Default for SPI Mode:
* SPI MODE 0 (inactive low, phase middle, MSB, 8-bit length, slow clk
*/
#define SPMODE_INIT_VAL (SPMODE_CI_INACTIVEHIGH | SPMODE_DIV16 | SPMODE_REV | \
SPMODE_MS | SPMODE_LEN(7) | SPMODE_PM(0xf))
/* SPIE register values */
#define SPIE_NE 0x00000200 /* Not empty */
#define SPIE_NF 0x00000100 /* Not full */
/* SPIM register values */
#define SPIM_NE 0x00000200 /* Not empty */
#define SPIM_NF 0x00000100 /* Not full */
/* SPI Controller driver's private data. */
struct mpc83xx_spi {
/* bitbang has to be first */
struct spi_bitbang bitbang;
struct completion done;
struct mpc83xx_spi_reg __iomem *base;
/* rx & tx bufs from the spi_transfer */
const void *tx;
void *rx;
/* functions to deal with different sized buffers */
void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
u32(*get_tx) (struct mpc83xx_spi *);
unsigned int count;
u32 irq;
unsigned nsecs; /* (clock cycle time)/2 */
u32 sysclk;
void (*activate_cs) (u8 cs, u8 polarity);
void (*deactivate_cs) (u8 cs, u8 polarity);
};
static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val)
{
out_be32(reg, val);
}
static inline u32 mpc83xx_spi_read_reg(__be32 __iomem * reg)
{
return in_be32(reg);
}
#define MPC83XX_SPI_RX_BUF(type) \
void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \
{ \
type * rx = mpc83xx_spi->rx; \
*rx++ = (type)data; \
mpc83xx_spi->rx = rx; \
}
#define MPC83XX_SPI_TX_BUF(type) \
u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi) \
{ \
u32 data; \
const type * tx = mpc83xx_spi->tx; \
data = *tx++; \
mpc83xx_spi->tx = tx; \
return data; \
}
MPC83XX_SPI_RX_BUF(u8)
MPC83XX_SPI_RX_BUF(u16)
MPC83XX_SPI_RX_BUF(u32)
MPC83XX_SPI_TX_BUF(u8)
MPC83XX_SPI_TX_BUF(u16)
MPC83XX_SPI_TX_BUF(u32)
static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
{
struct mpc83xx_spi *mpc83xx_spi;
u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0;
mpc83xx_spi = spi_master_get_devdata(spi->master);
if (value == BITBANG_CS_INACTIVE) {
if (mpc83xx_spi->deactivate_cs)
mpc83xx_spi->deactivate_cs(spi->chip_select, pol);
}
if (value == BITBANG_CS_ACTIVE) {
u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
u32 len = spi->bits_per_word;
if (len == 32)
len = 0;
else
len = len - 1;
/* mask out bits we are going to set */
regval &= ~0x38ff0000;
if (spi->mode & SPI_CPHA)
regval |= SPMODE_CP_BEGIN_EDGECLK;
if (spi->mode & SPI_CPOL)
regval |= SPMODE_CI_INACTIVEHIGH;
regval |= SPMODE_LEN(len);
if ((mpc83xx_spi->sysclk / spi->max_speed_hz) >= 64) {
u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 64);
regval |= SPMODE_PM(pm) | SPMODE_DIV16;
} else {
u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 4);
regval |= SPMODE_PM(pm);
}
mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
if (mpc83xx_spi->activate_cs)
mpc83xx_spi->activate_cs(spi->chip_select, pol);
}
}
static
int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
{
struct mpc83xx_spi *mpc83xx_spi;
u32 regval;
u8 bits_per_word;
u32 hz;
mpc83xx_spi = spi_master_get_devdata(spi->master);
if (t) {
bits_per_word = t->bits_per_word;
hz = t->speed_hz;
} else {
bits_per_word = 0;
hz = 0;
}
/* spi_transfer level calls that work per-word */
if (!bits_per_word)
bits_per_word = spi->bits_per_word;
/* Make sure its a bit width we support [4..16, 32] */
if ((bits_per_word < 4)
|| ((bits_per_word > 16) && (bits_per_word != 32)))
return -EINVAL;
if (bits_per_word <= 8) {
mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
} else if (bits_per_word <= 16) {
mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u16;
mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u16;
} else if (bits_per_word <= 32) {
mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u32;
mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u32;
} else
return -EINVAL;
/* nsecs = (clock period)/2 */
if (!hz)
hz = spi->max_speed_hz;
mpc83xx_spi->nsecs = (1000000000 / 2) / hz;
if (mpc83xx_spi->nsecs > MAX_UDELAY_MS * 1000)
return -EINVAL;
if (bits_per_word == 32)
bits_per_word = 0;
else
bits_per_word = bits_per_word - 1;
regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
/* Mask out bits_per_wordgth */
regval &= 0xff0fffff;
regval |= SPMODE_LEN(bits_per_word);
mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
return 0;
}
static int mpc83xx_spi_setup(struct spi_device *spi)
{
struct spi_bitbang *bitbang;
struct mpc83xx_spi *mpc83xx_spi;
int retval;
if (!spi->max_speed_hz)
return -EINVAL;
bitbang = spi_master_get_devdata(spi->master);
mpc83xx_spi = spi_master_get_devdata(spi->master);
if (!spi->bits_per_word)
spi->bits_per_word = 8;
retval = mpc83xx_spi_setup_transfer(spi, NULL);
if (retval < 0)
return retval;
dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n",
__FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA),
spi->bits_per_word, 2 * mpc83xx_spi->nsecs);
/* NOTE we _need_ to call chipselect() early, ideally with adapter
* setup, unless the hardware defaults cooperate to avoid confusion
* between normal (active low) and inverted chipselects.
*/
/* deselect chip (low or high) */
spin_lock(&bitbang->lock);
if (!bitbang->busy) {
bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
ndelay(mpc83xx_spi->nsecs);
}
spin_unlock(&bitbang->lock);
return 0;
}
static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
{
struct mpc83xx_spi *mpc83xx_spi;
u32 word;
mpc83xx_spi = spi_master_get_devdata(spi->master);
mpc83xx_spi->tx = t->tx_buf;
mpc83xx_spi->rx = t->rx_buf;
mpc83xx_spi->count = t->len;
INIT_COMPLETION(mpc83xx_spi->done);
/* enable rx ints */
mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);
/* transmit word */
word = mpc83xx_spi->get_tx(mpc83xx_spi);
mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
wait_for_completion(&mpc83xx_spi->done);
/* disable rx ints */
mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
return t->len - mpc83xx_spi->count;
}
irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data,
struct pt_regs * ptregs)
{
struct mpc83xx_spi *mpc83xx_spi = context_data;
u32 event;
irqreturn_t ret = IRQ_NONE;
/* Get interrupt events(tx/rx) */
event = mpc83xx_spi_read_reg(&mpc83xx_spi->base->event);
/* We need handle RX first */
if (event & SPIE_NE) {
u32 rx_data = mpc83xx_spi_read_reg(&mpc83xx_spi->base->receive);
if (mpc83xx_spi->rx)
mpc83xx_spi->get_rx(rx_data, mpc83xx_spi);
ret = IRQ_HANDLED;
}
if ((event & SPIE_NF) == 0)
/* spin until TX is done */
while (((event =
mpc83xx_spi_read_reg(&mpc83xx_spi->base->event)) &
SPIE_NF) == 0)
cpu_relax();
mpc83xx_spi->count -= 1;
if (mpc83xx_spi->count) {
if (mpc83xx_spi->tx) {
u32 word = mpc83xx_spi->get_tx(mpc83xx_spi);
mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit,
word);
}
} else {
complete(&mpc83xx_spi->done);
}
/* Clear the events */
mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, event);
return ret;
}
static int __init mpc83xx_spi_probe(struct platform_device *dev)
{
struct spi_master *master;
struct mpc83xx_spi *mpc83xx_spi;
struct fsl_spi_platform_data *pdata;
struct resource *r;
u32 regval;
int ret = 0;
/* Get resources(memory, IRQ) associated with the device */
master = spi_alloc_master(&dev->dev, sizeof(struct mpc83xx_spi));
if (master == NULL) {
ret = -ENOMEM;
goto err;
}
platform_set_drvdata(dev, master);
pdata = dev->dev.platform_data;
if (pdata == NULL) {
ret = -ENODEV;
goto free_master;
}
r = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (r == NULL) {
ret = -ENODEV;
goto free_master;
}
mpc83xx_spi = spi_master_get_devdata(master);
mpc83xx_spi->bitbang.master = spi_master_get(master);
mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect;
mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer;
mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs;
mpc83xx_spi->sysclk = pdata->sysclk;
mpc83xx_spi->activate_cs = pdata->activate_cs;
mpc83xx_spi->deactivate_cs = pdata->deactivate_cs;
mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
mpc83xx_spi->bitbang.master->setup = mpc83xx_spi_setup;
init_completion(&mpc83xx_spi->done);
mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1);
if (mpc83xx_spi->base == NULL) {
ret = -ENOMEM;
goto put_master;
}
mpc83xx_spi->irq = platform_get_irq(dev, 0);
if (mpc83xx_spi->irq < 0) {
ret = -ENXIO;
goto unmap_io;
}
/* Register for SPI Interrupt */
ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq,
0, "mpc83xx_spi", mpc83xx_spi);
if (ret != 0)
goto unmap_io;
master->bus_num = pdata->bus_num;
master->num_chipselect = pdata->max_chipselect;
/* SPI controller initializations */
mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
mpc83xx_spi_write_reg(&mpc83xx_spi->base->command, 0);
mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, 0xffffffff);
/* Enable SPI interface */
regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE;
mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
ret = spi_bitbang_start(&mpc83xx_spi->bitbang);
if (ret != 0)
goto free_irq;
printk(KERN_INFO
"%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
dev->dev.bus_id, mpc83xx_spi->base, mpc83xx_spi->irq);
return ret;
free_irq:
free_irq(mpc83xx_spi->irq, mpc83xx_spi);
unmap_io:
iounmap(mpc83xx_spi->base);
put_master:
spi_master_put(master);
free_master:
kfree(master);
err:
return ret;
}
static int __devexit mpc83xx_spi_remove(struct platform_device *dev)
{
struct mpc83xx_spi *mpc83xx_spi;
struct spi_master *master;
master = platform_get_drvdata(dev);
mpc83xx_spi = spi_master_get_devdata(master);
spi_bitbang_stop(&mpc83xx_spi->bitbang);
free_irq(mpc83xx_spi->irq, mpc83xx_spi);
iounmap(mpc83xx_spi->base);
spi_master_put(mpc83xx_spi->bitbang.master);
return 0;
}
static struct platform_driver mpc83xx_spi_driver = {
.probe = mpc83xx_spi_probe,
.remove = __devexit_p(mpc83xx_spi_remove),
.driver = {
.name = "mpc83xx_spi",
},
};
static int __init mpc83xx_spi_init(void)
{
return platform_driver_register(&mpc83xx_spi_driver);
}
static void __exit mpc83xx_spi_exit(void)
{
platform_driver_unregister(&mpc83xx_spi_driver);
}
module_init(mpc83xx_spi_init);
module_exit(mpc83xx_spi_exit);
MODULE_AUTHOR("Kumar Gala");
MODULE_DESCRIPTION("Simple MPC83xx SPI Driver");
MODULE_LICENSE("GPL");

453
drivers/spi/spi_s3c24xx.c Normal file
View File

@ -0,0 +1,453 @@
/* linux/drivers/spi/spi_s3c24xx.c
*
* Copyright (c) 2006 Ben Dooks
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
//#define DEBUG
#include <linux/config.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/hardware.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-spi.h>
#include <asm/arch/spi.h>
struct s3c24xx_spi {
/* bitbang has to be first */
struct spi_bitbang bitbang;
struct completion done;
void __iomem *regs;
int irq;
int len;
int count;
/* data buffers */
const unsigned char *tx;
unsigned char *rx;
struct clk *clk;
struct resource *ioarea;
struct spi_master *master;
struct spi_device *curdev;
struct device *dev;
struct s3c2410_spi_info *pdata;
};
#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT)
#define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP)
static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev)
{
return spi_master_get_devdata(sdev->master);
}
static void s3c24xx_spi_chipsel(struct spi_device *spi, int value)
{
struct s3c24xx_spi *hw = to_hw(spi);
unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
unsigned int spcon;
switch (value) {
case BITBANG_CS_INACTIVE:
if (hw->pdata->set_cs)
hw->pdata->set_cs(hw->pdata, value, cspol);
else
s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol ^ 1);
break;
case BITBANG_CS_ACTIVE:
spcon = readb(hw->regs + S3C2410_SPCON);
if (spi->mode & SPI_CPHA)
spcon |= S3C2410_SPCON_CPHA_FMTB;
else
spcon &= ~S3C2410_SPCON_CPHA_FMTB;
if (spi->mode & SPI_CPOL)
spcon |= S3C2410_SPCON_CPOL_HIGH;
else
spcon &= ~S3C2410_SPCON_CPOL_HIGH;
spcon |= S3C2410_SPCON_ENSCK;
/* write new configration */
writeb(spcon, hw->regs + S3C2410_SPCON);
if (hw->pdata->set_cs)
hw->pdata->set_cs(hw->pdata, value, cspol);
else
s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol);
break;
}
}
static int s3c24xx_spi_setupxfer(struct spi_device *spi,
struct spi_transfer *t)
{
struct s3c24xx_spi *hw = to_hw(spi);
unsigned int bpw;
unsigned int hz;
unsigned int div;
bpw = t ? t->bits_per_word : spi->bits_per_word;
hz = t ? t->speed_hz : spi->max_speed_hz;
if (bpw != 8) {
dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw);
return -EINVAL;
}
div = clk_get_rate(hw->clk) / hz;
/* is clk = pclk / (2 * (pre+1)), or is it
* clk = (pclk * 2) / ( pre + 1) */
div = (div / 2) - 1;
if (div < 0)
div = 1;
if (div > 255)
div = 255;
dev_dbg(&spi->dev, "setting pre-scaler to %d (hz %d)\n", div, hz);
writeb(div, hw->regs + S3C2410_SPPRE);
spin_lock(&hw->bitbang.lock);
if (!hw->bitbang.busy) {
hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
/* need to ndelay for 0.5 clocktick ? */
}
spin_unlock(&hw->bitbang.lock);
return 0;
}
static int s3c24xx_spi_setup(struct spi_device *spi)
{
int ret;
if (!spi->bits_per_word)
spi->bits_per_word = 8;
if ((spi->mode & SPI_LSB_FIRST) != 0)
return -EINVAL;
ret = s3c24xx_spi_setupxfer(spi, NULL);
if (ret < 0) {
dev_err(&spi->dev, "setupxfer returned %d\n", ret);
return ret;
}
dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n",
__FUNCTION__, spi->mode, spi->bits_per_word,
spi->max_speed_hz);
return 0;
}
static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count)
{
return hw->tx ? hw->tx[count] : 0xff;
}
static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
{
struct s3c24xx_spi *hw = to_hw(spi);
dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
t->tx_buf, t->rx_buf, t->len);
hw->tx = t->tx_buf;
hw->rx = t->rx_buf;
hw->len = t->len;
hw->count = 0;
/* send the first byte */
writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT);
wait_for_completion(&hw->done);
return hw->count;
}
static irqreturn_t s3c24xx_spi_irq(int irq, void *dev, struct pt_regs *regs)
{
struct s3c24xx_spi *hw = dev;
unsigned int spsta = readb(hw->regs + S3C2410_SPSTA);
unsigned int count = hw->count;
if (spsta & S3C2410_SPSTA_DCOL) {
dev_dbg(hw->dev, "data-collision\n");
complete(&hw->done);
goto irq_done;
}
if (!(spsta & S3C2410_SPSTA_READY)) {
dev_dbg(hw->dev, "spi not ready for tx?\n");
complete(&hw->done);
goto irq_done;
}
hw->count++;
if (hw->rx)
hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);
count++;
if (count < hw->len)
writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT);
else
complete(&hw->done);
irq_done:
return IRQ_HANDLED;
}
static int s3c24xx_spi_probe(struct platform_device *pdev)
{
struct s3c24xx_spi *hw;
struct spi_master *master;
struct spi_board_info *bi;
struct resource *res;
int err = 0;
int i;
master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));
if (master == NULL) {
dev_err(&pdev->dev, "No memory for spi_master\n");
err = -ENOMEM;
goto err_nomem;
}
hw = spi_master_get_devdata(master);
memset(hw, 0, sizeof(struct s3c24xx_spi));
hw->master = spi_master_get(master);
hw->pdata = pdev->dev.platform_data;
hw->dev = &pdev->dev;
if (hw->pdata == NULL) {
dev_err(&pdev->dev, "No platform data supplied\n");
err = -ENOENT;
goto err_no_pdata;
}
platform_set_drvdata(pdev, hw);
init_completion(&hw->done);
/* setup the state for the bitbang driver */
hw->bitbang.master = hw->master;
hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer;
hw->bitbang.chipselect = s3c24xx_spi_chipsel;
hw->bitbang.txrx_bufs = s3c24xx_spi_txrx;
hw->bitbang.master->setup = s3c24xx_spi_setup;
dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
/* find and map our resources */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
err = -ENOENT;
goto err_no_iores;
}
hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1,
pdev->name);
if (hw->ioarea == NULL) {
dev_err(&pdev->dev, "Cannot reserve region\n");
err = -ENXIO;
goto err_no_iores;
}
hw->regs = ioremap(res->start, (res->end - res->start)+1);
if (hw->regs == NULL) {
dev_err(&pdev->dev, "Cannot map IO\n");
err = -ENXIO;
goto err_no_iomap;
}
hw->irq = platform_get_irq(pdev, 0);
if (hw->irq < 0) {
dev_err(&pdev->dev, "No IRQ specified\n");
err = -ENOENT;
goto err_no_irq;
}
err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw);
if (err) {
dev_err(&pdev->dev, "Cannot claim IRQ\n");
goto err_no_irq;
}
hw->clk = clk_get(&pdev->dev, "spi");
if (IS_ERR(hw->clk)) {
dev_err(&pdev->dev, "No clock for device\n");
err = PTR_ERR(hw->clk);
goto err_no_clk;
}
/* for the moment, permanently enable the clock */
clk_enable(hw->clk);
/* program defaults into the registers */
writeb(0xff, hw->regs + S3C2410_SPPRE);
writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);
writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON);
/* setup any gpio we can */
if (!hw->pdata->set_cs) {
s3c2410_gpio_setpin(hw->pdata->pin_cs, 1);
s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT);
}
/* register our spi controller */
err = spi_bitbang_start(&hw->bitbang);
if (err) {
dev_err(&pdev->dev, "Failed to register SPI master\n");
goto err_register;
}
dev_dbg(hw->dev, "shutdown=%d\n", hw->bitbang.shutdown);
/* register all the devices associated */
bi = &hw->pdata->board_info[0];
for (i = 0; i < hw->pdata->board_size; i++, bi++) {
dev_info(hw->dev, "registering %s\n", bi->modalias);
bi->controller_data = hw;
spi_new_device(master, bi);
}
return 0;
err_register:
clk_disable(hw->clk);
clk_put(hw->clk);
err_no_clk:
free_irq(hw->irq, hw);
err_no_irq:
iounmap(hw->regs);
err_no_iomap:
release_resource(hw->ioarea);
kfree(hw->ioarea);
err_no_iores:
err_no_pdata:
spi_master_put(hw->master);;
err_nomem:
return err;
}
static int s3c24xx_spi_remove(struct platform_device *dev)
{
struct s3c24xx_spi *hw = platform_get_drvdata(dev);
platform_set_drvdata(dev, NULL);
spi_unregister_master(hw->master);
clk_disable(hw->clk);
clk_put(hw->clk);
free_irq(hw->irq, hw);
iounmap(hw->regs);
release_resource(hw->ioarea);
kfree(hw->ioarea);
spi_master_put(hw->master);
return 0;
}
#ifdef CONFIG_PM
static int s3c24xx_spi_suspend(struct platform_device *pdev, pm_message_t msg)
{
struct s3c24xx_spi *hw = platform_get_drvdata(dev);
clk_disable(hw->clk);
return 0;
}
static int s3c24xx_spi_resume(struct platform_device *pdev)
{
struct s3c24xx_spi *hw = platform_get_drvdata(dev);
clk_enable(hw->clk);
return 0;
}
#else
#define s3c24xx_spi_suspend NULL
#define s3c24xx_spi_resume NULL
#endif
static struct platform_driver s3c24xx_spidrv = {
.probe = s3c24xx_spi_probe,
.remove = s3c24xx_spi_remove,
.suspend = s3c24xx_spi_suspend,
.resume = s3c24xx_spi_resume,
.driver = {
.name = "s3c2410-spi",
.owner = THIS_MODULE,
},
};
static int __init s3c24xx_spi_init(void)
{
return platform_driver_register(&s3c24xx_spidrv);
}
static void __exit s3c24xx_spi_exit(void)
{
platform_driver_unregister(&s3c24xx_spidrv);
}
module_init(s3c24xx_spi_init);
module_exit(s3c24xx_spi_exit);
MODULE_DESCRIPTION("S3C24XX SPI Driver");
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,188 @@
/* linux/drivers/spi/spi_s3c24xx_gpio.c
*
* Copyright (c) 2006 Ben Dooks
* Copyright (c) 2006 Simtec Electronics
*
* S3C24XX GPIO based SPI driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/spi-gpio.h>
#include <asm/arch/hardware.h>
struct s3c2410_spigpio {
struct spi_bitbang bitbang;
struct s3c2410_spigpio_info *info;
struct platform_device *dev;
};
static inline struct s3c2410_spigpio *spidev_to_sg(struct spi_device *spi)
{
return spi->controller_data;
}
static inline void setsck(struct spi_device *dev, int on)
{
struct s3c2410_spigpio *sg = spidev_to_sg(dev);
s3c2410_gpio_setpin(sg->info->pin_clk, on ? 1 : 0);
}
static inline void setmosi(struct spi_device *dev, int on)
{
struct s3c2410_spigpio *sg = spidev_to_sg(dev);
s3c2410_gpio_setpin(sg->info->pin_mosi, on ? 1 : 0);
}
static inline u32 getmiso(struct spi_device *dev)
{
struct s3c2410_spigpio *sg = spidev_to_sg(dev);
return s3c2410_gpio_getpin(sg->info->pin_miso) ? 1 : 0;
}
#define spidelay(x) ndelay(x)
#define EXPAND_BITBANG_TXRX
#include <linux/spi/spi_bitbang.h>
static u32 s3c2410_spigpio_txrx_mode0(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
}
static u32 s3c2410_spigpio_txrx_mode1(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
}
static void s3c2410_spigpio_chipselect(struct spi_device *dev, int value)
{
struct s3c2410_spigpio *sg = spidev_to_sg(dev);
if (sg->info && sg->info->chip_select)
(sg->info->chip_select)(sg->info, value);
}
static int s3c2410_spigpio_probe(struct platform_device *dev)
{
struct spi_master *master;
struct s3c2410_spigpio *sp;
int ret;
int i;
master = spi_alloc_master(&dev->dev, sizeof(struct s3c2410_spigpio));
if (master == NULL) {
dev_err(&dev->dev, "failed to allocate spi master\n");
ret = -ENOMEM;
goto err;
}
sp = spi_master_get_devdata(master);
platform_set_drvdata(dev, sp);
/* copy in the plkatform data */
sp->info = dev->dev.platform_data;
/* setup spi bitbang adaptor */
sp->bitbang.master = spi_master_get(master);
sp->bitbang.chipselect = s3c2410_spigpio_chipselect;
sp->bitbang.txrx_word[SPI_MODE_0] = s3c2410_spigpio_txrx_mode0;
sp->bitbang.txrx_word[SPI_MODE_1] = s3c2410_spigpio_txrx_mode1;
/* set state of spi pins */
s3c2410_gpio_setpin(sp->info->pin_clk, 0);
s3c2410_gpio_setpin(sp->info->pin_mosi, 0);
s3c2410_gpio_cfgpin(sp->info->pin_clk, S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(sp->info->pin_mosi, S3C2410_GPIO_OUTPUT);
s3c2410_gpio_cfgpin(sp->info->pin_miso, S3C2410_GPIO_INPUT);
ret = spi_bitbang_start(&sp->bitbang);
if (ret)
goto err_no_bitbang;
/* register the chips to go with the board */
for (i = 0; i < sp->info->board_size; i++) {
dev_info(&dev->dev, "registering %p: %s\n",
&sp->info->board_info[i],
sp->info->board_info[i].modalias);
sp->info->board_info[i].controller_data = sp;
spi_new_device(master, sp->info->board_info + i);
}
return 0;
err_no_bitbang:
spi_master_put(sp->bitbang.master);
err:
return ret;
}
static int s3c2410_spigpio_remove(struct platform_device *dev)
{
struct s3c2410_spigpio *sp = platform_get_drvdata(dev);
spi_bitbang_stop(&sp->bitbang);
spi_master_put(sp->bitbang.master);
return 0;
}
/* all gpio should be held over suspend/resume, so we should
* not need to deal with this
*/
#define s3c2410_spigpio_suspend NULL
#define s3c2410_spigpio_resume NULL
static struct platform_driver s3c2410_spigpio_drv = {
.probe = s3c2410_spigpio_probe,
.remove = s3c2410_spigpio_remove,
.suspend = s3c2410_spigpio_suspend,
.resume = s3c2410_spigpio_resume,
.driver = {
.name = "s3c24xx-spi-gpio",
.owner = THIS_MODULE,
},
};
static int __init s3c2410_spigpio_init(void)
{
return platform_driver_register(&s3c2410_spigpio_drv);
}
static void __exit s3c2410_spigpio_exit(void)
{
platform_driver_unregister(&s3c2410_spigpio_drv);
}
module_init(s3c2410_spigpio_init);
module_exit(s3c2410_spigpio_exit);
MODULE_DESCRIPTION("S3C24XX SPI Driver");
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_LICENSE("GPL");

View File

@ -317,6 +317,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
}
schedule();
set_current_state(TASK_INTERRUPTIBLE);
}
set_current_state(TASK_RUNNING);

View File

@ -76,8 +76,8 @@
*
* Experiment with v_offset to find out which works best for you.
*/
static u32 v_offset_default __initdata; /* For 32 MiB Aper size, 8 should be the default */
static u32 voffset __initdata = 0;
static u32 v_offset_default __devinitdata; /* For 32 MiB Aper size, 8 should be the default */
static u32 voffset __devinitdata;
static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor);
static int __devinit i810fb_init_pci (struct pci_dev *dev,

View File

@ -316,14 +316,24 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
case M_PIXEL_PLL_B:
case M_PIXEL_PLL_C:
{
u_int8_t tmp;
u_int8_t tmp, xpwrctrl;
unsigned long flags;
matroxfb_DAC_lock_irqsave(flags);
xpwrctrl = matroxfb_DAC_in(PMINFO M1064_XPWRCTRL);
matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl & ~M1064_XPWRCTRL_PANELPDN);
mga_outb(M_SEQ_INDEX, M_SEQ1);
mga_outb(M_SEQ_DATA, mga_inb(M_SEQ_DATA) | M_SEQ1_SCROFF);
tmp = matroxfb_DAC_in(PMINFO M1064_XPIXCLKCTRL);
tmp |= M1064_XPIXCLKCTRL_DIS;
if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) {
matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp | M1064_XPIXCLKCTRL_PLL_UP);
tmp |= M1064_XPIXCLKCTRL_PLL_UP;
}
matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp);
matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0);
matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl);
matroxfb_DAC_unlock_irqrestore(flags);
}
{
@ -418,6 +428,15 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
frequency to higher - with <= lowest wins, while
with < highest one wins */
if (delta <= deltaarray[idx-1]) {
/* all else being equal except VCO,
* choose VCO not near (within 1/16th or so) VCOmin
* (freqs near VCOmin aren't as stable)
*/
if (delta == deltaarray[idx-1]
&& vco != g450_mnp2vco(PMINFO mnparray[idx-1])
&& vco < (pi->vcomin * 17 / 16)) {
break;
}
mnparray[idx] = mnparray[idx-1];
deltaarray[idx] = deltaarray[idx-1];
} else {

View File

@ -40,6 +40,7 @@ void DAC1064_global_restore(WPMINFO2);
#define M1064_XCURCOL1RED 0x0C
#define M1064_XCURCOL1GREEN 0x0D
#define M1064_XCURCOL1BLUE 0x0E
#define M1064_XDVICLKCTRL 0x0F
#define M1064_XCURCOL2RED 0x10
#define M1064_XCURCOL2GREEN 0x11
#define M1064_XCURCOL2BLUE 0x12
@ -144,6 +145,7 @@ void DAC1064_global_restore(WPMINFO2);
#define M1064_XVIDPLLN 0x8F
#define M1064_XPWRCTRL 0xA0
#define M1064_XPWRCTRL_PANELPDN 0x04
#define M1064_XPANMODE 0xA2

Some files were not shown because too many files have changed in this diff Show More