diff options
Diffstat (limited to 'drivers')
219 files changed, 16684 insertions, 3590 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index 503d82569449..6d9d7fab77f5 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -15,6 +15,8 @@ obj-$(CONFIG_ACPI) += acpi/ | |||
15 | obj-$(CONFIG_PNP) += pnp/ | 15 | obj-$(CONFIG_PNP) += pnp/ |
16 | obj-$(CONFIG_ARM_AMBA) += amba/ | 16 | obj-$(CONFIG_ARM_AMBA) += amba/ |
17 | 17 | ||
18 | obj-$(CONFIG_XEN) += xen/ | ||
19 | |||
18 | # char/ comes before serial/ etc so that the VT console is the boot-time | 20 | # char/ comes before serial/ etc so that the VT console is the boot-time |
19 | # default. | 21 | # default. |
20 | obj-y += char/ | 22 | obj-y += char/ |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 88a6fc7fd271..58f1338981bc 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/jiffies.h> | 40 | #include <linux/jiffies.h> |
41 | #include <linux/kmod.h> | 41 | #include <linux/kmod.h> |
42 | #include <linux/seq_file.h> | 42 | #include <linux/seq_file.h> |
43 | #include <linux/reboot.h> | ||
43 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
44 | 45 | ||
45 | #include <acpi/acpi_bus.h> | 46 | #include <acpi/acpi_bus.h> |
@@ -59,7 +60,6 @@ | |||
59 | #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 | 60 | #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 |
60 | #define ACPI_THERMAL_NOTIFY_HOT 0xF1 | 61 | #define ACPI_THERMAL_NOTIFY_HOT 0xF1 |
61 | #define ACPI_THERMAL_MODE_ACTIVE 0x00 | 62 | #define ACPI_THERMAL_MODE_ACTIVE 0x00 |
62 | #define ACPI_THERMAL_PATH_POWEROFF "/sbin/poweroff" | ||
63 | 63 | ||
64 | #define ACPI_THERMAL_MAX_ACTIVE 10 | 64 | #define ACPI_THERMAL_MAX_ACTIVE 10 |
65 | #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 | 65 | #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 |
@@ -419,26 +419,6 @@ static int acpi_thermal_get_devices(struct acpi_thermal *tz) | |||
419 | return 0; | 419 | return 0; |
420 | } | 420 | } |
421 | 421 | ||
422 | static int acpi_thermal_call_usermode(char *path) | ||
423 | { | ||
424 | char *argv[2] = { NULL, NULL }; | ||
425 | char *envp[3] = { NULL, NULL, NULL }; | ||
426 | |||
427 | |||
428 | if (!path) | ||
429 | return -EINVAL; | ||
430 | |||
431 | argv[0] = path; | ||
432 | |||
433 | /* minimal command environment */ | ||
434 | envp[0] = "HOME=/"; | ||
435 | envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; | ||
436 | |||
437 | call_usermodehelper(argv[0], argv, envp, 0); | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | static int acpi_thermal_critical(struct acpi_thermal *tz) | 422 | static int acpi_thermal_critical(struct acpi_thermal *tz) |
443 | { | 423 | { |
444 | if (!tz || !tz->trips.critical.flags.valid) | 424 | if (!tz || !tz->trips.critical.flags.valid) |
@@ -456,7 +436,7 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) | |||
456 | acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, | 436 | acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, |
457 | tz->trips.critical.flags.enabled); | 437 | tz->trips.critical.flags.enabled); |
458 | 438 | ||
459 | acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF); | 439 | orderly_poweroff(true); |
460 | 440 | ||
461 | return 0; | 441 | return 0; |
462 | } | 442 | } |
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig index bb4ae6281491..bed9f58c2d5a 100644 --- a/drivers/atm/Kconfig +++ b/drivers/atm/Kconfig | |||
@@ -172,7 +172,7 @@ config ATM_ZATM_DEBUG | |||
172 | 172 | ||
173 | config ATM_NICSTAR | 173 | config ATM_NICSTAR |
174 | tristate "IDT 77201 (NICStAR) (ForeRunnerLE)" | 174 | tristate "IDT 77201 (NICStAR) (ForeRunnerLE)" |
175 | depends on PCI && !64BIT | 175 | depends on PCI && !64BIT && VIRT_TO_BUS |
176 | help | 176 | help |
177 | The NICStAR chipset family is used in a large number of ATM NICs for | 177 | The NICStAR chipset family is used in a large number of ATM NICs for |
178 | 25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE | 178 | 25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE |
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 77637e780d41..41b2204ebc6e 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c | |||
@@ -1738,7 +1738,8 @@ static int __devinit eni_do_init(struct atm_dev *dev) | |||
1738 | printk(KERN_ERR KERN_ERR DEV_LABEL "(itf %d): bad " | 1738 | printk(KERN_ERR KERN_ERR DEV_LABEL "(itf %d): bad " |
1739 | "magic - expected 0x%x, got 0x%x\n",dev->number, | 1739 | "magic - expected 0x%x, got 0x%x\n",dev->number, |
1740 | ENI155_MAGIC,(unsigned) readl(&eprom->magic)); | 1740 | ENI155_MAGIC,(unsigned) readl(&eprom->magic)); |
1741 | return -EINVAL; | 1741 | error = -EINVAL; |
1742 | goto unmap; | ||
1742 | } | 1743 | } |
1743 | } | 1744 | } |
1744 | eni_dev->phy = base+PHY_BASE; | 1745 | eni_dev->phy = base+PHY_BASE; |
@@ -1765,17 +1766,27 @@ static int __devinit eni_do_init(struct atm_dev *dev) | |||
1765 | printk(")\n"); | 1766 | printk(")\n"); |
1766 | printk(KERN_ERR DEV_LABEL "(itf %d): ERROR - wrong id 0x%x\n", | 1767 | printk(KERN_ERR DEV_LABEL "(itf %d): ERROR - wrong id 0x%x\n", |
1767 | dev->number,(unsigned) eni_in(MID_RES_ID_MCON)); | 1768 | dev->number,(unsigned) eni_in(MID_RES_ID_MCON)); |
1768 | return -EINVAL; | 1769 | error = -EINVAL; |
1770 | goto unmap; | ||
1769 | } | 1771 | } |
1770 | error = eni_dev->asic ? get_esi_asic(dev) : get_esi_fpga(dev,base); | 1772 | error = eni_dev->asic ? get_esi_asic(dev) : get_esi_fpga(dev,base); |
1771 | if (error) return error; | 1773 | if (error) |
1774 | goto unmap; | ||
1772 | for (i = 0; i < ESI_LEN; i++) | 1775 | for (i = 0; i < ESI_LEN; i++) |
1773 | printk("%s%02X",i ? "-" : "",dev->esi[i]); | 1776 | printk("%s%02X",i ? "-" : "",dev->esi[i]); |
1774 | printk(")\n"); | 1777 | printk(")\n"); |
1775 | printk(KERN_NOTICE DEV_LABEL "(itf %d): %s,%s\n",dev->number, | 1778 | printk(KERN_NOTICE DEV_LABEL "(itf %d): %s,%s\n",dev->number, |
1776 | eni_in(MID_RES_ID_MCON) & 0x200 ? "ASIC" : "FPGA", | 1779 | eni_in(MID_RES_ID_MCON) & 0x200 ? "ASIC" : "FPGA", |
1777 | media_name[eni_in(MID_RES_ID_MCON) & DAUGTHER_ID]); | 1780 | media_name[eni_in(MID_RES_ID_MCON) & DAUGTHER_ID]); |
1778 | return suni_init(dev); | 1781 | |
1782 | error = suni_init(dev); | ||
1783 | if (error) | ||
1784 | goto unmap; | ||
1785 | out: | ||
1786 | return error; | ||
1787 | unmap: | ||
1788 | iounmap(base); | ||
1789 | goto out; | ||
1779 | } | 1790 | } |
1780 | 1791 | ||
1781 | 1792 | ||
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 38b688f9f6a9..737cea49f872 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c | |||
@@ -1710,7 +1710,7 @@ static int __devinit fs_init (struct fs_dev *dev) | |||
1710 | /* This bit is documented as "RESERVED" */ | 1710 | /* This bit is documented as "RESERVED" */ |
1711 | if (isr & ISR_INIT_ERR) { | 1711 | if (isr & ISR_INIT_ERR) { |
1712 | printk (KERN_ERR "Error initializing the FS... \n"); | 1712 | printk (KERN_ERR "Error initializing the FS... \n"); |
1713 | return 1; | 1713 | goto unmap; |
1714 | } | 1714 | } |
1715 | if (isr & ISR_INIT) { | 1715 | if (isr & ISR_INIT) { |
1716 | fs_dprintk (FS_DEBUG_INIT, "Ha! Initialized OK!\n"); | 1716 | fs_dprintk (FS_DEBUG_INIT, "Ha! Initialized OK!\n"); |
@@ -1723,7 +1723,7 @@ static int __devinit fs_init (struct fs_dev *dev) | |||
1723 | 1723 | ||
1724 | if (!to) { | 1724 | if (!to) { |
1725 | printk (KERN_ERR "timeout initializing the FS... \n"); | 1725 | printk (KERN_ERR "timeout initializing the FS... \n"); |
1726 | return 1; | 1726 | goto unmap; |
1727 | } | 1727 | } |
1728 | 1728 | ||
1729 | /* XXX fix for fs155 */ | 1729 | /* XXX fix for fs155 */ |
@@ -1803,7 +1803,7 @@ static int __devinit fs_init (struct fs_dev *dev) | |||
1803 | if (!dev->atm_vccs) { | 1803 | if (!dev->atm_vccs) { |
1804 | printk (KERN_WARNING "Couldn't allocate memory for VCC buffers. Woops!\n"); | 1804 | printk (KERN_WARNING "Couldn't allocate memory for VCC buffers. Woops!\n"); |
1805 | /* XXX Clean up..... */ | 1805 | /* XXX Clean up..... */ |
1806 | return 1; | 1806 | goto unmap; |
1807 | } | 1807 | } |
1808 | 1808 | ||
1809 | dev->tx_inuse = kzalloc (dev->nchannels / 8 /* bits/byte */ , GFP_KERNEL); | 1809 | dev->tx_inuse = kzalloc (dev->nchannels / 8 /* bits/byte */ , GFP_KERNEL); |
@@ -1813,7 +1813,7 @@ static int __devinit fs_init (struct fs_dev *dev) | |||
1813 | if (!dev->tx_inuse) { | 1813 | if (!dev->tx_inuse) { |
1814 | printk (KERN_WARNING "Couldn't allocate memory for tx_inuse bits!\n"); | 1814 | printk (KERN_WARNING "Couldn't allocate memory for tx_inuse bits!\n"); |
1815 | /* XXX Clean up..... */ | 1815 | /* XXX Clean up..... */ |
1816 | return 1; | 1816 | goto unmap; |
1817 | } | 1817 | } |
1818 | /* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for both */ | 1818 | /* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for both */ |
1819 | /* -- RAS2 : FS50 only: Default is OK. */ | 1819 | /* -- RAS2 : FS50 only: Default is OK. */ |
@@ -1840,7 +1840,7 @@ static int __devinit fs_init (struct fs_dev *dev) | |||
1840 | if (request_irq (dev->irq, fs_irq, IRQF_SHARED, "firestream", dev)) { | 1840 | if (request_irq (dev->irq, fs_irq, IRQF_SHARED, "firestream", dev)) { |
1841 | printk (KERN_WARNING "couldn't get irq %d for firestream.\n", pci_dev->irq); | 1841 | printk (KERN_WARNING "couldn't get irq %d for firestream.\n", pci_dev->irq); |
1842 | /* XXX undo all previous stuff... */ | 1842 | /* XXX undo all previous stuff... */ |
1843 | return 1; | 1843 | goto unmap; |
1844 | } | 1844 | } |
1845 | fs_dprintk (FS_DEBUG_INIT, "Grabbed irq %d for dev at %p.\n", dev->irq, dev); | 1845 | fs_dprintk (FS_DEBUG_INIT, "Grabbed irq %d for dev at %p.\n", dev->irq, dev); |
1846 | 1846 | ||
@@ -1890,6 +1890,9 @@ static int __devinit fs_init (struct fs_dev *dev) | |||
1890 | 1890 | ||
1891 | func_exit (); | 1891 | func_exit (); |
1892 | return 0; | 1892 | return 0; |
1893 | unmap: | ||
1894 | iounmap(dev->base); | ||
1895 | return 1; | ||
1893 | } | 1896 | } |
1894 | 1897 | ||
1895 | static int __devinit firestream_init_one (struct pci_dev *pci_dev, | 1898 | static int __devinit firestream_init_one (struct pci_dev *pci_dev, |
@@ -2012,6 +2015,7 @@ static void __devexit firestream_remove_one (struct pci_dev *pdev) | |||
2012 | for (i=0;i < FS_NR_RX_QUEUES;i++) | 2015 | for (i=0;i < FS_NR_RX_QUEUES;i++) |
2013 | free_queue (dev, &dev->rx_rq[i]); | 2016 | free_queue (dev, &dev->rx_rq[i]); |
2014 | 2017 | ||
2018 | iounmap(dev->base); | ||
2015 | fs_dprintk (FS_DEBUG_ALLOC, "Free fs-dev: %p\n", dev); | 2019 | fs_dprintk (FS_DEBUG_ALLOC, "Free fs-dev: %p\n", dev); |
2016 | nxtdev = dev->next; | 2020 | nxtdev = dev->next; |
2017 | kfree (dev); | 2021 | kfree (dev); |
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 8f995ce8d73b..f8b1700f4c16 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c | |||
@@ -65,7 +65,7 @@ static char const rcsid[] = | |||
65 | static unsigned int vpibits = 1; | 65 | static unsigned int vpibits = 1; |
66 | 66 | ||
67 | 67 | ||
68 | #define CONFIG_ATM_IDT77252_SEND_IDLE 1 | 68 | #define ATM_IDT77252_SEND_IDLE 1 |
69 | 69 | ||
70 | 70 | ||
71 | /* | 71 | /* |
@@ -3404,7 +3404,7 @@ init_card(struct atm_dev *dev) | |||
3404 | conf = SAR_CFG_TX_FIFO_SIZE_9 | /* Use maximum fifo size */ | 3404 | conf = SAR_CFG_TX_FIFO_SIZE_9 | /* Use maximum fifo size */ |
3405 | SAR_CFG_RXSTQ_SIZE_8k | /* Receive Status Queue is 8k */ | 3405 | SAR_CFG_RXSTQ_SIZE_8k | /* Receive Status Queue is 8k */ |
3406 | SAR_CFG_IDLE_CLP | /* Set CLP on idle cells */ | 3406 | SAR_CFG_IDLE_CLP | /* Set CLP on idle cells */ |
3407 | #ifndef CONFIG_ATM_IDT77252_SEND_IDLE | 3407 | #ifndef ATM_IDT77252_SEND_IDLE |
3408 | SAR_CFG_NO_IDLE | /* Do not send idle cells */ | 3408 | SAR_CFG_NO_IDLE | /* Do not send idle cells */ |
3409 | #endif | 3409 | #endif |
3410 | 0; | 3410 | 0; |
@@ -3541,7 +3541,7 @@ init_card(struct atm_dev *dev) | |||
3541 | printk("%s: Linkrate on ATM line : %u bit/s, %u cell/s.\n", | 3541 | printk("%s: Linkrate on ATM line : %u bit/s, %u cell/s.\n", |
3542 | card->name, linkrate, card->link_pcr); | 3542 | card->name, linkrate, card->link_pcr); |
3543 | 3543 | ||
3544 | #ifdef CONFIG_ATM_IDT77252_SEND_IDLE | 3544 | #ifdef ATM_IDT77252_SEND_IDLE |
3545 | card->utopia_pcr = card->link_pcr; | 3545 | card->utopia_pcr = card->link_pcr; |
3546 | #else | 3546 | #else |
3547 | card->utopia_pcr = (160000000 / 8 / 54); | 3547 | card->utopia_pcr = (160000000 / 8 / 54); |
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index 0e2c1ae650e7..55fd1b4543fd 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c | |||
@@ -552,8 +552,8 @@ static inline void sram_write(const struct lanai_dev *lanai, | |||
552 | writel(val, sram_addr(lanai, offset)); | 552 | writel(val, sram_addr(lanai, offset)); |
553 | } | 553 | } |
554 | 554 | ||
555 | static int __init sram_test_word( | 555 | static int __devinit sram_test_word(const struct lanai_dev *lanai, |
556 | const struct lanai_dev *lanai, int offset, u32 pattern) | 556 | int offset, u32 pattern) |
557 | { | 557 | { |
558 | u32 readback; | 558 | u32 readback; |
559 | sram_write(lanai, pattern, offset); | 559 | sram_write(lanai, pattern, offset); |
diff --git a/drivers/atm/nicstarmac.c b/drivers/atm/nicstarmac.c index 480947f4e01e..842e26c45557 100644 --- a/drivers/atm/nicstarmac.c +++ b/drivers/atm/nicstarmac.c | |||
@@ -134,7 +134,7 @@ nicstar_read_eprom_status( virt_addr_t base ) | |||
134 | /* Send read instruction */ | 134 | /* Send read instruction */ |
135 | val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0; | 135 | val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0; |
136 | 136 | ||
137 | for (i=0; i<sizeof rdsrtab/sizeof rdsrtab[0]; i++) | 137 | for (i=0; i<ARRAY_SIZE(rdsrtab); i++) |
138 | { | 138 | { |
139 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, | 139 | NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, |
140 | (val | rdsrtab[i]) ); | 140 | (val | rdsrtab[i]) ); |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 8f65b88cf711..a4a311992408 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -427,4 +427,13 @@ config XILINX_SYSACE | |||
427 | help | 427 | help |
428 | Include support for the Xilinx SystemACE CompactFlash interface | 428 | Include support for the Xilinx SystemACE CompactFlash interface |
429 | 429 | ||
430 | config XEN_BLKDEV_FRONTEND | ||
431 | tristate "Xen virtual block device support" | ||
432 | depends on XEN | ||
433 | default y | ||
434 | help | ||
435 | This driver implements the front-end of the Xen virtual | ||
436 | block device driver. It communicates with a back-end driver | ||
437 | in another domain which drives the actual block device. | ||
438 | |||
430 | endif # BLK_DEV | 439 | endif # BLK_DEV |
diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 9ee08ab4ffa8..3e31532df0ed 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile | |||
@@ -29,3 +29,4 @@ obj-$(CONFIG_VIODASD) += viodasd.o | |||
29 | obj-$(CONFIG_BLK_DEV_SX8) += sx8.o | 29 | obj-$(CONFIG_BLK_DEV_SX8) += sx8.o |
30 | obj-$(CONFIG_BLK_DEV_UB) += ub.o | 30 | obj-$(CONFIG_BLK_DEV_UB) += ub.o |
31 | 31 | ||
32 | obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o | ||
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 0f5e3caf85d7..2288b55d916f 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c | |||
@@ -45,8 +45,6 @@ struct vdc_req_entry { | |||
45 | struct vdc_port { | 45 | struct vdc_port { |
46 | struct vio_driver_state vio; | 46 | struct vio_driver_state vio; |
47 | 47 | ||
48 | struct vdc *vp; | ||
49 | |||
50 | struct gendisk *disk; | 48 | struct gendisk *disk; |
51 | 49 | ||
52 | struct vdc_completion *cmp; | 50 | struct vdc_completion *cmp; |
@@ -72,8 +70,6 @@ struct vdc_port { | |||
72 | 70 | ||
73 | struct vio_disk_geom geom; | 71 | struct vio_disk_geom geom; |
74 | struct vio_disk_vtoc label; | 72 | struct vio_disk_vtoc label; |
75 | |||
76 | struct list_head list; | ||
77 | }; | 73 | }; |
78 | 74 | ||
79 | static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio) | 75 | static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio) |
@@ -81,15 +77,6 @@ static inline struct vdc_port *to_vdc_port(struct vio_driver_state *vio) | |||
81 | return container_of(vio, struct vdc_port, vio); | 77 | return container_of(vio, struct vdc_port, vio); |
82 | } | 78 | } |
83 | 79 | ||
84 | struct vdc { | ||
85 | /* Protects prot_list. */ | ||
86 | spinlock_t lock; | ||
87 | |||
88 | struct vio_dev *dev; | ||
89 | |||
90 | struct list_head port_list; | ||
91 | }; | ||
92 | |||
93 | /* Ordered from largest major to lowest */ | 80 | /* Ordered from largest major to lowest */ |
94 | static struct vio_version vdc_versions[] = { | 81 | static struct vio_version vdc_versions[] = { |
95 | { .major = 1, .minor = 0 }, | 82 | { .major = 1, .minor = 0 }, |
@@ -747,21 +734,23 @@ static struct vio_driver_ops vdc_vio_ops = { | |||
747 | .handshake_complete = vdc_handshake_complete, | 734 | .handshake_complete = vdc_handshake_complete, |
748 | }; | 735 | }; |
749 | 736 | ||
737 | static void print_version(void) | ||
738 | { | ||
739 | static int version_printed; | ||
740 | |||
741 | if (version_printed++ == 0) | ||
742 | printk(KERN_INFO "%s", version); | ||
743 | } | ||
744 | |||
750 | static int __devinit vdc_port_probe(struct vio_dev *vdev, | 745 | static int __devinit vdc_port_probe(struct vio_dev *vdev, |
751 | const struct vio_device_id *id) | 746 | const struct vio_device_id *id) |
752 | { | 747 | { |
753 | struct mdesc_handle *hp; | 748 | struct mdesc_handle *hp; |
754 | struct vdc_port *port; | 749 | struct vdc_port *port; |
755 | unsigned long flags; | ||
756 | struct vdc *vp; | ||
757 | const u64 *port_id; | 750 | const u64 *port_id; |
758 | int err; | 751 | int err; |
759 | 752 | ||
760 | vp = dev_get_drvdata(vdev->dev.parent); | 753 | print_version(); |
761 | if (!vp) { | ||
762 | printk(KERN_ERR PFX "Cannot find port parent vdc.\n"); | ||
763 | return -ENODEV; | ||
764 | } | ||
765 | 754 | ||
766 | hp = mdesc_grab(); | 755 | hp = mdesc_grab(); |
767 | 756 | ||
@@ -783,7 +772,6 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev, | |||
783 | goto err_out_release_mdesc; | 772 | goto err_out_release_mdesc; |
784 | } | 773 | } |
785 | 774 | ||
786 | port->vp = vp; | ||
787 | port->dev_no = *port_id; | 775 | port->dev_no = *port_id; |
788 | 776 | ||
789 | if (port->dev_no >= 26) | 777 | if (port->dev_no >= 26) |
@@ -818,12 +806,6 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev, | |||
818 | if (err) | 806 | if (err) |
819 | goto err_out_free_tx_ring; | 807 | goto err_out_free_tx_ring; |
820 | 808 | ||
821 | INIT_LIST_HEAD(&port->list); | ||
822 | |||
823 | spin_lock_irqsave(&vp->lock, flags); | ||
824 | list_add(&port->list, &vp->port_list); | ||
825 | spin_unlock_irqrestore(&vp->lock, flags); | ||
826 | |||
827 | dev_set_drvdata(&vdev->dev, port); | 809 | dev_set_drvdata(&vdev->dev, port); |
828 | 810 | ||
829 | mdesc_release(hp); | 811 | mdesc_release(hp); |
@@ -879,58 +861,6 @@ static struct vio_driver vdc_port_driver = { | |||
879 | } | 861 | } |
880 | }; | 862 | }; |
881 | 863 | ||
882 | static int __devinit vdc_probe(struct vio_dev *vdev, | ||
883 | const struct vio_device_id *id) | ||
884 | { | ||
885 | static int vdc_version_printed; | ||
886 | struct vdc *vp; | ||
887 | |||
888 | if (vdc_version_printed++ == 0) | ||
889 | printk(KERN_INFO "%s", version); | ||
890 | |||
891 | vp = kzalloc(sizeof(struct vdc), GFP_KERNEL); | ||
892 | if (!vp) | ||
893 | return -ENOMEM; | ||
894 | |||
895 | spin_lock_init(&vp->lock); | ||
896 | vp->dev = vdev; | ||
897 | INIT_LIST_HEAD(&vp->port_list); | ||
898 | |||
899 | dev_set_drvdata(&vdev->dev, vp); | ||
900 | |||
901 | return 0; | ||
902 | } | ||
903 | |||
904 | static int vdc_remove(struct vio_dev *vdev) | ||
905 | { | ||
906 | |||
907 | struct vdc *vp = dev_get_drvdata(&vdev->dev); | ||
908 | |||
909 | if (vp) { | ||
910 | kfree(vp); | ||
911 | dev_set_drvdata(&vdev->dev, NULL); | ||
912 | } | ||
913 | return 0; | ||
914 | } | ||
915 | |||
916 | static struct vio_device_id vdc_match[] = { | ||
917 | { | ||
918 | .type = "block", | ||
919 | }, | ||
920 | {}, | ||
921 | }; | ||
922 | MODULE_DEVICE_TABLE(vio, vdc_match); | ||
923 | |||
924 | static struct vio_driver vdc_driver = { | ||
925 | .id_table = vdc_match, | ||
926 | .probe = vdc_probe, | ||
927 | .remove = vdc_remove, | ||
928 | .driver = { | ||
929 | .name = "vdc", | ||
930 | .owner = THIS_MODULE, | ||
931 | } | ||
932 | }; | ||
933 | |||
934 | static int __init vdc_init(void) | 864 | static int __init vdc_init(void) |
935 | { | 865 | { |
936 | int err; | 866 | int err; |
@@ -940,19 +870,13 @@ static int __init vdc_init(void) | |||
940 | goto out_err; | 870 | goto out_err; |
941 | 871 | ||
942 | vdc_major = err; | 872 | vdc_major = err; |
943 | err = vio_register_driver(&vdc_driver); | ||
944 | if (err) | ||
945 | goto out_unregister_blkdev; | ||
946 | 873 | ||
947 | err = vio_register_driver(&vdc_port_driver); | 874 | err = vio_register_driver(&vdc_port_driver); |
948 | if (err) | 875 | if (err) |
949 | goto out_unregister_vdc; | 876 | goto out_unregister_blkdev; |
950 | 877 | ||
951 | return 0; | 878 | return 0; |
952 | 879 | ||
953 | out_unregister_vdc: | ||
954 | vio_unregister_driver(&vdc_driver); | ||
955 | |||
956 | out_unregister_blkdev: | 880 | out_unregister_blkdev: |
957 | unregister_blkdev(vdc_major, VDCBLK_NAME); | 881 | unregister_blkdev(vdc_major, VDCBLK_NAME); |
958 | vdc_major = 0; | 882 | vdc_major = 0; |
@@ -964,7 +888,6 @@ out_err: | |||
964 | static void __exit vdc_exit(void) | 888 | static void __exit vdc_exit(void) |
965 | { | 889 | { |
966 | vio_unregister_driver(&vdc_port_driver); | 890 | vio_unregister_driver(&vdc_port_driver); |
967 | vio_unregister_driver(&vdc_driver); | ||
968 | unregister_blkdev(vdc_major, VDCBLK_NAME); | 891 | unregister_blkdev(vdc_major, VDCBLK_NAME); |
969 | } | 892 | } |
970 | 893 | ||
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c new file mode 100644 index 000000000000..6746c29181f8 --- /dev/null +++ b/drivers/block/xen-blkfront.c | |||
@@ -0,0 +1,988 @@ | |||
1 | /* | ||
2 | * blkfront.c | ||
3 | * | ||
4 | * XenLinux virtual block device driver. | ||
5 | * | ||
6 | * Copyright (c) 2003-2004, Keir Fraser & Steve Hand | ||
7 | * Modifications by Mark A. Williamson are (c) Intel Research Cambridge | ||
8 | * Copyright (c) 2004, Christian Limpach | ||
9 | * Copyright (c) 2004, Andrew Warfield | ||
10 | * Copyright (c) 2005, Christopher Clark | ||
11 | * Copyright (c) 2005, XenSource Ltd | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License version 2 | ||
15 | * as published by the Free Software Foundation; or, when distributed | ||
16 | * separately from the Linux kernel or incorporated into other | ||
17 | * software packages, subject to the following license: | ||
18 | * | ||
19 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
20 | * of this source file (the "Software"), to deal in the Software without | ||
21 | * restriction, including without limitation the rights to use, copy, modify, | ||
22 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
23 | * and to permit persons to whom the Software is furnished to do so, subject to | ||
24 | * the following conditions: | ||
25 | * | ||
26 | * The above copyright notice and this permission notice shall be included in | ||
27 | * all copies or substantial portions of the Software. | ||
28 | * | ||
29 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
30 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
31 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
32 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
33 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
34 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
35 | * IN THE SOFTWARE. | ||
36 | */ | ||
37 | |||
38 | #include <linux/interrupt.h> | ||
39 | #include <linux/blkdev.h> | ||
40 | #include <linux/module.h> | ||
41 | |||
42 | #include <xen/xenbus.h> | ||
43 | #include <xen/grant_table.h> | ||
44 | #include <xen/events.h> | ||
45 | #include <xen/page.h> | ||
46 | |||
47 | #include <xen/interface/grant_table.h> | ||
48 | #include <xen/interface/io/blkif.h> | ||
49 | |||
50 | #include <asm/xen/hypervisor.h> | ||
51 | |||
52 | enum blkif_state { | ||
53 | BLKIF_STATE_DISCONNECTED, | ||
54 | BLKIF_STATE_CONNECTED, | ||
55 | BLKIF_STATE_SUSPENDED, | ||
56 | }; | ||
57 | |||
58 | struct blk_shadow { | ||
59 | struct blkif_request req; | ||
60 | unsigned long request; | ||
61 | unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | ||
62 | }; | ||
63 | |||
64 | static struct block_device_operations xlvbd_block_fops; | ||
65 | |||
66 | #define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE) | ||
67 | |||
68 | /* | ||
69 | * We have one of these per vbd, whether ide, scsi or 'other'. They | ||
70 | * hang in private_data off the gendisk structure. We may end up | ||
71 | * putting all kinds of interesting stuff here :-) | ||
72 | */ | ||
73 | struct blkfront_info | ||
74 | { | ||
75 | struct xenbus_device *xbdev; | ||
76 | dev_t dev; | ||
77 | struct gendisk *gd; | ||
78 | int vdevice; | ||
79 | blkif_vdev_t handle; | ||
80 | enum blkif_state connected; | ||
81 | int ring_ref; | ||
82 | struct blkif_front_ring ring; | ||
83 | unsigned int evtchn, irq; | ||
84 | struct request_queue *rq; | ||
85 | struct work_struct work; | ||
86 | struct gnttab_free_callback callback; | ||
87 | struct blk_shadow shadow[BLK_RING_SIZE]; | ||
88 | unsigned long shadow_free; | ||
89 | int feature_barrier; | ||
90 | |||
91 | /** | ||
92 | * The number of people holding this device open. We won't allow a | ||
93 | * hot-unplug unless this is 0. | ||
94 | */ | ||
95 | int users; | ||
96 | }; | ||
97 | |||
98 | static DEFINE_SPINLOCK(blkif_io_lock); | ||
99 | |||
100 | #define MAXIMUM_OUTSTANDING_BLOCK_REQS \ | ||
101 | (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLK_RING_SIZE) | ||
102 | #define GRANT_INVALID_REF 0 | ||
103 | |||
104 | #define PARTS_PER_DISK 16 | ||
105 | |||
106 | #define BLKIF_MAJOR(dev) ((dev)>>8) | ||
107 | #define BLKIF_MINOR(dev) ((dev) & 0xff) | ||
108 | |||
109 | #define DEV_NAME "xvd" /* name in /dev */ | ||
110 | |||
111 | /* Information about our VBDs. */ | ||
112 | #define MAX_VBDS 64 | ||
113 | static LIST_HEAD(vbds_list); | ||
114 | |||
115 | static int get_id_from_freelist(struct blkfront_info *info) | ||
116 | { | ||
117 | unsigned long free = info->shadow_free; | ||
118 | BUG_ON(free > BLK_RING_SIZE); | ||
119 | info->shadow_free = info->shadow[free].req.id; | ||
120 | info->shadow[free].req.id = 0x0fffffee; /* debug */ | ||
121 | return free; | ||
122 | } | ||
123 | |||
124 | static void add_id_to_freelist(struct blkfront_info *info, | ||
125 | unsigned long id) | ||
126 | { | ||
127 | info->shadow[id].req.id = info->shadow_free; | ||
128 | info->shadow[id].request = 0; | ||
129 | info->shadow_free = id; | ||
130 | } | ||
131 | |||
132 | static void blkif_restart_queue_callback(void *arg) | ||
133 | { | ||
134 | struct blkfront_info *info = (struct blkfront_info *)arg; | ||
135 | schedule_work(&info->work); | ||
136 | } | ||
137 | |||
138 | /* | ||
139 | * blkif_queue_request | ||
140 | * | ||
141 | * request block io | ||
142 | * | ||
143 | * id: for guest use only. | ||
144 | * operation: BLKIF_OP_{READ,WRITE,PROBE} | ||
145 | * buffer: buffer to read/write into. this should be a | ||
146 | * virtual address in the guest os. | ||
147 | */ | ||
148 | static int blkif_queue_request(struct request *req) | ||
149 | { | ||
150 | struct blkfront_info *info = req->rq_disk->private_data; | ||
151 | unsigned long buffer_mfn; | ||
152 | struct blkif_request *ring_req; | ||
153 | struct bio *bio; | ||
154 | struct bio_vec *bvec; | ||
155 | int idx; | ||
156 | unsigned long id; | ||
157 | unsigned int fsect, lsect; | ||
158 | int ref; | ||
159 | grant_ref_t gref_head; | ||
160 | |||
161 | if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) | ||
162 | return 1; | ||
163 | |||
164 | if (gnttab_alloc_grant_references( | ||
165 | BLKIF_MAX_SEGMENTS_PER_REQUEST, &gref_head) < 0) { | ||
166 | gnttab_request_free_callback( | ||
167 | &info->callback, | ||
168 | blkif_restart_queue_callback, | ||
169 | info, | ||
170 | BLKIF_MAX_SEGMENTS_PER_REQUEST); | ||
171 | return 1; | ||
172 | } | ||
173 | |||
174 | /* Fill out a communications ring structure. */ | ||
175 | ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt); | ||
176 | id = get_id_from_freelist(info); | ||
177 | info->shadow[id].request = (unsigned long)req; | ||
178 | |||
179 | ring_req->id = id; | ||
180 | ring_req->sector_number = (blkif_sector_t)req->sector; | ||
181 | ring_req->handle = info->handle; | ||
182 | |||
183 | ring_req->operation = rq_data_dir(req) ? | ||
184 | BLKIF_OP_WRITE : BLKIF_OP_READ; | ||
185 | if (blk_barrier_rq(req)) | ||
186 | ring_req->operation = BLKIF_OP_WRITE_BARRIER; | ||
187 | |||
188 | ring_req->nr_segments = 0; | ||
189 | rq_for_each_bio (bio, req) { | ||
190 | bio_for_each_segment (bvec, bio, idx) { | ||
191 | BUG_ON(ring_req->nr_segments | ||
192 | == BLKIF_MAX_SEGMENTS_PER_REQUEST); | ||
193 | buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page)); | ||
194 | fsect = bvec->bv_offset >> 9; | ||
195 | lsect = fsect + (bvec->bv_len >> 9) - 1; | ||
196 | /* install a grant reference. */ | ||
197 | ref = gnttab_claim_grant_reference(&gref_head); | ||
198 | BUG_ON(ref == -ENOSPC); | ||
199 | |||
200 | gnttab_grant_foreign_access_ref( | ||
201 | ref, | ||
202 | info->xbdev->otherend_id, | ||
203 | buffer_mfn, | ||
204 | rq_data_dir(req) ); | ||
205 | |||
206 | info->shadow[id].frame[ring_req->nr_segments] = | ||
207 | mfn_to_pfn(buffer_mfn); | ||
208 | |||
209 | ring_req->seg[ring_req->nr_segments] = | ||
210 | (struct blkif_request_segment) { | ||
211 | .gref = ref, | ||
212 | .first_sect = fsect, | ||
213 | .last_sect = lsect }; | ||
214 | |||
215 | ring_req->nr_segments++; | ||
216 | } | ||
217 | } | ||
218 | |||
219 | info->ring.req_prod_pvt++; | ||
220 | |||
221 | /* Keep a private copy so we can reissue requests when recovering. */ | ||
222 | info->shadow[id].req = *ring_req; | ||
223 | |||
224 | gnttab_free_grant_references(gref_head); | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | |||
230 | static inline void flush_requests(struct blkfront_info *info) | ||
231 | { | ||
232 | int notify; | ||
233 | |||
234 | RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->ring, notify); | ||
235 | |||
236 | if (notify) | ||
237 | notify_remote_via_irq(info->irq); | ||
238 | } | ||
239 | |||
240 | /* | ||
241 | * do_blkif_request | ||
242 | * read a block; request is in a request queue | ||
243 | */ | ||
244 | static void do_blkif_request(request_queue_t *rq) | ||
245 | { | ||
246 | struct blkfront_info *info = NULL; | ||
247 | struct request *req; | ||
248 | int queued; | ||
249 | |||
250 | pr_debug("Entered do_blkif_request\n"); | ||
251 | |||
252 | queued = 0; | ||
253 | |||
254 | while ((req = elv_next_request(rq)) != NULL) { | ||
255 | info = req->rq_disk->private_data; | ||
256 | if (!blk_fs_request(req)) { | ||
257 | end_request(req, 0); | ||
258 | continue; | ||
259 | } | ||
260 | |||
261 | if (RING_FULL(&info->ring)) | ||
262 | goto wait; | ||
263 | |||
264 | pr_debug("do_blk_req %p: cmd %p, sec %lx, " | ||
265 | "(%u/%li) buffer:%p [%s]\n", | ||
266 | req, req->cmd, (unsigned long)req->sector, | ||
267 | req->current_nr_sectors, | ||
268 | req->nr_sectors, req->buffer, | ||
269 | rq_data_dir(req) ? "write" : "read"); | ||
270 | |||
271 | |||
272 | blkdev_dequeue_request(req); | ||
273 | if (blkif_queue_request(req)) { | ||
274 | blk_requeue_request(rq, req); | ||
275 | wait: | ||
276 | /* Avoid pointless unplugs. */ | ||
277 | blk_stop_queue(rq); | ||
278 | break; | ||
279 | } | ||
280 | |||
281 | queued++; | ||
282 | } | ||
283 | |||
284 | if (queued != 0) | ||
285 | flush_requests(info); | ||
286 | } | ||
287 | |||
288 | static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) | ||
289 | { | ||
290 | request_queue_t *rq; | ||
291 | |||
292 | rq = blk_init_queue(do_blkif_request, &blkif_io_lock); | ||
293 | if (rq == NULL) | ||
294 | return -1; | ||
295 | |||
296 | elevator_init(rq, "noop"); | ||
297 | |||
298 | /* Hard sector size and max sectors impersonate the equiv. hardware. */ | ||
299 | blk_queue_hardsect_size(rq, sector_size); | ||
300 | blk_queue_max_sectors(rq, 512); | ||
301 | |||
302 | /* Each segment in a request is up to an aligned page in size. */ | ||
303 | blk_queue_segment_boundary(rq, PAGE_SIZE - 1); | ||
304 | blk_queue_max_segment_size(rq, PAGE_SIZE); | ||
305 | |||
306 | /* Ensure a merged request will fit in a single I/O ring slot. */ | ||
307 | blk_queue_max_phys_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST); | ||
308 | blk_queue_max_hw_segments(rq, BLKIF_MAX_SEGMENTS_PER_REQUEST); | ||
309 | |||
310 | /* Make sure buffer addresses are sector-aligned. */ | ||
311 | blk_queue_dma_alignment(rq, 511); | ||
312 | |||
313 | gd->queue = rq; | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | |||
319 | static int xlvbd_barrier(struct blkfront_info *info) | ||
320 | { | ||
321 | int err; | ||
322 | |||
323 | err = blk_queue_ordered(info->rq, | ||
324 | info->feature_barrier ? QUEUE_ORDERED_DRAIN : QUEUE_ORDERED_NONE, | ||
325 | NULL); | ||
326 | |||
327 | if (err) | ||
328 | return err; | ||
329 | |||
330 | printk(KERN_INFO "blkfront: %s: barriers %s\n", | ||
331 | info->gd->disk_name, | ||
332 | info->feature_barrier ? "enabled" : "disabled"); | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | |||
337 | static int xlvbd_alloc_gendisk(int minor, blkif_sector_t capacity, | ||
338 | int vdevice, u16 vdisk_info, u16 sector_size, | ||
339 | struct blkfront_info *info) | ||
340 | { | ||
341 | struct gendisk *gd; | ||
342 | int nr_minors = 1; | ||
343 | int err = -ENODEV; | ||
344 | |||
345 | BUG_ON(info->gd != NULL); | ||
346 | BUG_ON(info->rq != NULL); | ||
347 | |||
348 | if ((minor % PARTS_PER_DISK) == 0) | ||
349 | nr_minors = PARTS_PER_DISK; | ||
350 | |||
351 | gd = alloc_disk(nr_minors); | ||
352 | if (gd == NULL) | ||
353 | goto out; | ||
354 | |||
355 | if (nr_minors > 1) | ||
356 | sprintf(gd->disk_name, "%s%c", DEV_NAME, | ||
357 | 'a' + minor / PARTS_PER_DISK); | ||
358 | else | ||
359 | sprintf(gd->disk_name, "%s%c%d", DEV_NAME, | ||
360 | 'a' + minor / PARTS_PER_DISK, | ||
361 | minor % PARTS_PER_DISK); | ||
362 | |||
363 | gd->major = XENVBD_MAJOR; | ||
364 | gd->first_minor = minor; | ||
365 | gd->fops = &xlvbd_block_fops; | ||
366 | gd->private_data = info; | ||
367 | gd->driverfs_dev = &(info->xbdev->dev); | ||
368 | set_capacity(gd, capacity); | ||
369 | |||
370 | if (xlvbd_init_blk_queue(gd, sector_size)) { | ||
371 | del_gendisk(gd); | ||
372 | goto out; | ||
373 | } | ||
374 | |||
375 | info->rq = gd->queue; | ||
376 | info->gd = gd; | ||
377 | |||
378 | if (info->feature_barrier) | ||
379 | xlvbd_barrier(info); | ||
380 | |||
381 | if (vdisk_info & VDISK_READONLY) | ||
382 | set_disk_ro(gd, 1); | ||
383 | |||
384 | if (vdisk_info & VDISK_REMOVABLE) | ||
385 | gd->flags |= GENHD_FL_REMOVABLE; | ||
386 | |||
387 | if (vdisk_info & VDISK_CDROM) | ||
388 | gd->flags |= GENHD_FL_CD; | ||
389 | |||
390 | return 0; | ||
391 | |||
392 | out: | ||
393 | return err; | ||
394 | } | ||
395 | |||
396 | static void kick_pending_request_queues(struct blkfront_info *info) | ||
397 | { | ||
398 | if (!RING_FULL(&info->ring)) { | ||
399 | /* Re-enable calldowns. */ | ||
400 | blk_start_queue(info->rq); | ||
401 | /* Kick things off immediately. */ | ||
402 | do_blkif_request(info->rq); | ||
403 | } | ||
404 | } | ||
405 | |||
406 | static void blkif_restart_queue(struct work_struct *work) | ||
407 | { | ||
408 | struct blkfront_info *info = container_of(work, struct blkfront_info, work); | ||
409 | |||
410 | spin_lock_irq(&blkif_io_lock); | ||
411 | if (info->connected == BLKIF_STATE_CONNECTED) | ||
412 | kick_pending_request_queues(info); | ||
413 | spin_unlock_irq(&blkif_io_lock); | ||
414 | } | ||
415 | |||
416 | static void blkif_free(struct blkfront_info *info, int suspend) | ||
417 | { | ||
418 | /* Prevent new requests being issued until we fix things up. */ | ||
419 | spin_lock_irq(&blkif_io_lock); | ||
420 | info->connected = suspend ? | ||
421 | BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED; | ||
422 | /* No more blkif_request(). */ | ||
423 | if (info->rq) | ||
424 | blk_stop_queue(info->rq); | ||
425 | /* No more gnttab callback work. */ | ||
426 | gnttab_cancel_free_callback(&info->callback); | ||
427 | spin_unlock_irq(&blkif_io_lock); | ||
428 | |||
429 | /* Flush gnttab callback work. Must be done with no locks held. */ | ||
430 | flush_scheduled_work(); | ||
431 | |||
432 | /* Free resources associated with old device channel. */ | ||
433 | if (info->ring_ref != GRANT_INVALID_REF) { | ||
434 | gnttab_end_foreign_access(info->ring_ref, 0, | ||
435 | (unsigned long)info->ring.sring); | ||
436 | info->ring_ref = GRANT_INVALID_REF; | ||
437 | info->ring.sring = NULL; | ||
438 | } | ||
439 | if (info->irq) | ||
440 | unbind_from_irqhandler(info->irq, info); | ||
441 | info->evtchn = info->irq = 0; | ||
442 | |||
443 | } | ||
444 | |||
445 | static void blkif_completion(struct blk_shadow *s) | ||
446 | { | ||
447 | int i; | ||
448 | for (i = 0; i < s->req.nr_segments; i++) | ||
449 | gnttab_end_foreign_access(s->req.seg[i].gref, 0, 0UL); | ||
450 | } | ||
451 | |||
452 | static irqreturn_t blkif_interrupt(int irq, void *dev_id) | ||
453 | { | ||
454 | struct request *req; | ||
455 | struct blkif_response *bret; | ||
456 | RING_IDX i, rp; | ||
457 | unsigned long flags; | ||
458 | struct blkfront_info *info = (struct blkfront_info *)dev_id; | ||
459 | int uptodate; | ||
460 | |||
461 | spin_lock_irqsave(&blkif_io_lock, flags); | ||
462 | |||
463 | if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) { | ||
464 | spin_unlock_irqrestore(&blkif_io_lock, flags); | ||
465 | return IRQ_HANDLED; | ||
466 | } | ||
467 | |||
468 | again: | ||
469 | rp = info->ring.sring->rsp_prod; | ||
470 | rmb(); /* Ensure we see queued responses up to 'rp'. */ | ||
471 | |||
472 | for (i = info->ring.rsp_cons; i != rp; i++) { | ||
473 | unsigned long id; | ||
474 | int ret; | ||
475 | |||
476 | bret = RING_GET_RESPONSE(&info->ring, i); | ||
477 | id = bret->id; | ||
478 | req = (struct request *)info->shadow[id].request; | ||
479 | |||
480 | blkif_completion(&info->shadow[id]); | ||
481 | |||
482 | add_id_to_freelist(info, id); | ||
483 | |||
484 | uptodate = (bret->status == BLKIF_RSP_OKAY); | ||
485 | switch (bret->operation) { | ||
486 | case BLKIF_OP_WRITE_BARRIER: | ||
487 | if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { | ||
488 | printk(KERN_WARNING "blkfront: %s: write barrier op failed\n", | ||
489 | info->gd->disk_name); | ||
490 | uptodate = -EOPNOTSUPP; | ||
491 | info->feature_barrier = 0; | ||
492 | xlvbd_barrier(info); | ||
493 | } | ||
494 | /* fall through */ | ||
495 | case BLKIF_OP_READ: | ||
496 | case BLKIF_OP_WRITE: | ||
497 | if (unlikely(bret->status != BLKIF_RSP_OKAY)) | ||
498 | dev_dbg(&info->xbdev->dev, "Bad return from blkdev data " | ||
499 | "request: %x\n", bret->status); | ||
500 | |||
501 | ret = end_that_request_first(req, uptodate, | ||
502 | req->hard_nr_sectors); | ||
503 | BUG_ON(ret); | ||
504 | end_that_request_last(req, uptodate); | ||
505 | break; | ||
506 | default: | ||
507 | BUG(); | ||
508 | } | ||
509 | } | ||
510 | |||
511 | info->ring.rsp_cons = i; | ||
512 | |||
513 | if (i != info->ring.req_prod_pvt) { | ||
514 | int more_to_do; | ||
515 | RING_FINAL_CHECK_FOR_RESPONSES(&info->ring, more_to_do); | ||
516 | if (more_to_do) | ||
517 | goto again; | ||
518 | } else | ||
519 | info->ring.sring->rsp_event = i + 1; | ||
520 | |||
521 | kick_pending_request_queues(info); | ||
522 | |||
523 | spin_unlock_irqrestore(&blkif_io_lock, flags); | ||
524 | |||
525 | return IRQ_HANDLED; | ||
526 | } | ||
527 | |||
528 | |||
529 | static int setup_blkring(struct xenbus_device *dev, | ||
530 | struct blkfront_info *info) | ||
531 | { | ||
532 | struct blkif_sring *sring; | ||
533 | int err; | ||
534 | |||
535 | info->ring_ref = GRANT_INVALID_REF; | ||
536 | |||
537 | sring = (struct blkif_sring *)__get_free_page(GFP_KERNEL); | ||
538 | if (!sring) { | ||
539 | xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); | ||
540 | return -ENOMEM; | ||
541 | } | ||
542 | SHARED_RING_INIT(sring); | ||
543 | FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE); | ||
544 | |||
545 | err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring)); | ||
546 | if (err < 0) { | ||
547 | free_page((unsigned long)sring); | ||
548 | info->ring.sring = NULL; | ||
549 | goto fail; | ||
550 | } | ||
551 | info->ring_ref = err; | ||
552 | |||
553 | err = xenbus_alloc_evtchn(dev, &info->evtchn); | ||
554 | if (err) | ||
555 | goto fail; | ||
556 | |||
557 | err = bind_evtchn_to_irqhandler(info->evtchn, | ||
558 | blkif_interrupt, | ||
559 | IRQF_SAMPLE_RANDOM, "blkif", info); | ||
560 | if (err <= 0) { | ||
561 | xenbus_dev_fatal(dev, err, | ||
562 | "bind_evtchn_to_irqhandler failed"); | ||
563 | goto fail; | ||
564 | } | ||
565 | info->irq = err; | ||
566 | |||
567 | return 0; | ||
568 | fail: | ||
569 | blkif_free(info, 0); | ||
570 | return err; | ||
571 | } | ||
572 | |||
573 | |||
574 | /* Common code used when first setting up, and when resuming. */ | ||
575 | static int talk_to_backend(struct xenbus_device *dev, | ||
576 | struct blkfront_info *info) | ||
577 | { | ||
578 | const char *message = NULL; | ||
579 | struct xenbus_transaction xbt; | ||
580 | int err; | ||
581 | |||
582 | /* Create shared ring, alloc event channel. */ | ||
583 | err = setup_blkring(dev, info); | ||
584 | if (err) | ||
585 | goto out; | ||
586 | |||
587 | again: | ||
588 | err = xenbus_transaction_start(&xbt); | ||
589 | if (err) { | ||
590 | xenbus_dev_fatal(dev, err, "starting transaction"); | ||
591 | goto destroy_blkring; | ||
592 | } | ||
593 | |||
594 | err = xenbus_printf(xbt, dev->nodename, | ||
595 | "ring-ref", "%u", info->ring_ref); | ||
596 | if (err) { | ||
597 | message = "writing ring-ref"; | ||
598 | goto abort_transaction; | ||
599 | } | ||
600 | err = xenbus_printf(xbt, dev->nodename, | ||
601 | "event-channel", "%u", info->evtchn); | ||
602 | if (err) { | ||
603 | message = "writing event-channel"; | ||
604 | goto abort_transaction; | ||
605 | } | ||
606 | |||
607 | err = xenbus_transaction_end(xbt, 0); | ||
608 | if (err) { | ||
609 | if (err == -EAGAIN) | ||
610 | goto again; | ||
611 | xenbus_dev_fatal(dev, err, "completing transaction"); | ||
612 | goto destroy_blkring; | ||
613 | } | ||
614 | |||
615 | xenbus_switch_state(dev, XenbusStateInitialised); | ||
616 | |||
617 | return 0; | ||
618 | |||
619 | abort_transaction: | ||
620 | xenbus_transaction_end(xbt, 1); | ||
621 | if (message) | ||
622 | xenbus_dev_fatal(dev, err, "%s", message); | ||
623 | destroy_blkring: | ||
624 | blkif_free(info, 0); | ||
625 | out: | ||
626 | return err; | ||
627 | } | ||
628 | |||
629 | |||
630 | /** | ||
631 | * Entry point to this code when a new device is created. Allocate the basic | ||
632 | * structures and the ring buffer for communication with the backend, and | ||
633 | * inform the backend of the appropriate details for those. Switch to | ||
634 | * Initialised state. | ||
635 | */ | ||
636 | static int blkfront_probe(struct xenbus_device *dev, | ||
637 | const struct xenbus_device_id *id) | ||
638 | { | ||
639 | int err, vdevice, i; | ||
640 | struct blkfront_info *info; | ||
641 | |||
642 | /* FIXME: Use dynamic device id if this is not set. */ | ||
643 | err = xenbus_scanf(XBT_NIL, dev->nodename, | ||
644 | "virtual-device", "%i", &vdevice); | ||
645 | if (err != 1) { | ||
646 | xenbus_dev_fatal(dev, err, "reading virtual-device"); | ||
647 | return err; | ||
648 | } | ||
649 | |||
650 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
651 | if (!info) { | ||
652 | xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); | ||
653 | return -ENOMEM; | ||
654 | } | ||
655 | |||
656 | info->xbdev = dev; | ||
657 | info->vdevice = vdevice; | ||
658 | info->connected = BLKIF_STATE_DISCONNECTED; | ||
659 | INIT_WORK(&info->work, blkif_restart_queue); | ||
660 | |||
661 | for (i = 0; i < BLK_RING_SIZE; i++) | ||
662 | info->shadow[i].req.id = i+1; | ||
663 | info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff; | ||
664 | |||
665 | /* Front end dir is a number, which is used as the id. */ | ||
666 | info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0); | ||
667 | dev->dev.driver_data = info; | ||
668 | |||
669 | err = talk_to_backend(dev, info); | ||
670 | if (err) { | ||
671 | kfree(info); | ||
672 | dev->dev.driver_data = NULL; | ||
673 | return err; | ||
674 | } | ||
675 | |||
676 | return 0; | ||
677 | } | ||
678 | |||
679 | |||
680 | static int blkif_recover(struct blkfront_info *info) | ||
681 | { | ||
682 | int i; | ||
683 | struct blkif_request *req; | ||
684 | struct blk_shadow *copy; | ||
685 | int j; | ||
686 | |||
687 | /* Stage 1: Make a safe copy of the shadow state. */ | ||
688 | copy = kmalloc(sizeof(info->shadow), GFP_KERNEL); | ||
689 | if (!copy) | ||
690 | return -ENOMEM; | ||
691 | memcpy(copy, info->shadow, sizeof(info->shadow)); | ||
692 | |||
693 | /* Stage 2: Set up free list. */ | ||
694 | memset(&info->shadow, 0, sizeof(info->shadow)); | ||
695 | for (i = 0; i < BLK_RING_SIZE; i++) | ||
696 | info->shadow[i].req.id = i+1; | ||
697 | info->shadow_free = info->ring.req_prod_pvt; | ||
698 | info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff; | ||
699 | |||
700 | /* Stage 3: Find pending requests and requeue them. */ | ||
701 | for (i = 0; i < BLK_RING_SIZE; i++) { | ||
702 | /* Not in use? */ | ||
703 | if (copy[i].request == 0) | ||
704 | continue; | ||
705 | |||
706 | /* Grab a request slot and copy shadow state into it. */ | ||
707 | req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt); | ||
708 | *req = copy[i].req; | ||
709 | |||
710 | /* We get a new request id, and must reset the shadow state. */ | ||
711 | req->id = get_id_from_freelist(info); | ||
712 | memcpy(&info->shadow[req->id], ©[i], sizeof(copy[i])); | ||
713 | |||
714 | /* Rewrite any grant references invalidated by susp/resume. */ | ||
715 | for (j = 0; j < req->nr_segments; j++) | ||
716 | gnttab_grant_foreign_access_ref( | ||
717 | req->seg[j].gref, | ||
718 | info->xbdev->otherend_id, | ||
719 | pfn_to_mfn(info->shadow[req->id].frame[j]), | ||
720 | rq_data_dir( | ||
721 | (struct request *) | ||
722 | info->shadow[req->id].request)); | ||
723 | info->shadow[req->id].req = *req; | ||
724 | |||
725 | info->ring.req_prod_pvt++; | ||
726 | } | ||
727 | |||
728 | kfree(copy); | ||
729 | |||
730 | xenbus_switch_state(info->xbdev, XenbusStateConnected); | ||
731 | |||
732 | spin_lock_irq(&blkif_io_lock); | ||
733 | |||
734 | /* Now safe for us to use the shared ring */ | ||
735 | info->connected = BLKIF_STATE_CONNECTED; | ||
736 | |||
737 | /* Send off requeued requests */ | ||
738 | flush_requests(info); | ||
739 | |||
740 | /* Kick any other new requests queued since we resumed */ | ||
741 | kick_pending_request_queues(info); | ||
742 | |||
743 | spin_unlock_irq(&blkif_io_lock); | ||
744 | |||
745 | return 0; | ||
746 | } | ||
747 | |||
748 | /** | ||
749 | * We are reconnecting to the backend, due to a suspend/resume, or a backend | ||
750 | * driver restart. We tear down our blkif structure and recreate it, but | ||
751 | * leave the device-layer structures intact so that this is transparent to the | ||
752 | * rest of the kernel. | ||
753 | */ | ||
754 | static int blkfront_resume(struct xenbus_device *dev) | ||
755 | { | ||
756 | struct blkfront_info *info = dev->dev.driver_data; | ||
757 | int err; | ||
758 | |||
759 | dev_dbg(&dev->dev, "blkfront_resume: %s\n", dev->nodename); | ||
760 | |||
761 | blkif_free(info, info->connected == BLKIF_STATE_CONNECTED); | ||
762 | |||
763 | err = talk_to_backend(dev, info); | ||
764 | if (info->connected == BLKIF_STATE_SUSPENDED && !err) | ||
765 | err = blkif_recover(info); | ||
766 | |||
767 | return err; | ||
768 | } | ||
769 | |||
770 | |||
771 | /* | ||
772 | * Invoked when the backend is finally 'ready' (and has told produced | ||
773 | * the details about the physical device - #sectors, size, etc). | ||
774 | */ | ||
775 | static void blkfront_connect(struct blkfront_info *info) | ||
776 | { | ||
777 | unsigned long long sectors; | ||
778 | unsigned long sector_size; | ||
779 | unsigned int binfo; | ||
780 | int err; | ||
781 | |||
782 | if ((info->connected == BLKIF_STATE_CONNECTED) || | ||
783 | (info->connected == BLKIF_STATE_SUSPENDED) ) | ||
784 | return; | ||
785 | |||
786 | dev_dbg(&info->xbdev->dev, "%s:%s.\n", | ||
787 | __func__, info->xbdev->otherend); | ||
788 | |||
789 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | ||
790 | "sectors", "%llu", §ors, | ||
791 | "info", "%u", &binfo, | ||
792 | "sector-size", "%lu", §or_size, | ||
793 | NULL); | ||
794 | if (err) { | ||
795 | xenbus_dev_fatal(info->xbdev, err, | ||
796 | "reading backend fields at %s", | ||
797 | info->xbdev->otherend); | ||
798 | return; | ||
799 | } | ||
800 | |||
801 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | ||
802 | "feature-barrier", "%lu", &info->feature_barrier, | ||
803 | NULL); | ||
804 | if (err) | ||
805 | info->feature_barrier = 0; | ||
806 | |||
807 | err = xlvbd_alloc_gendisk(BLKIF_MINOR(info->vdevice), | ||
808 | sectors, info->vdevice, | ||
809 | binfo, sector_size, info); | ||
810 | if (err) { | ||
811 | xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", | ||
812 | info->xbdev->otherend); | ||
813 | return; | ||
814 | } | ||
815 | |||
816 | xenbus_switch_state(info->xbdev, XenbusStateConnected); | ||
817 | |||
818 | /* Kick pending requests. */ | ||
819 | spin_lock_irq(&blkif_io_lock); | ||
820 | info->connected = BLKIF_STATE_CONNECTED; | ||
821 | kick_pending_request_queues(info); | ||
822 | spin_unlock_irq(&blkif_io_lock); | ||
823 | |||
824 | add_disk(info->gd); | ||
825 | } | ||
826 | |||
827 | /** | ||
828 | * Handle the change of state of the backend to Closing. We must delete our | ||
829 | * device-layer structures now, to ensure that writes are flushed through to | ||
830 | * the backend. Once is this done, we can switch to Closed in | ||
831 | * acknowledgement. | ||
832 | */ | ||
833 | static void blkfront_closing(struct xenbus_device *dev) | ||
834 | { | ||
835 | struct blkfront_info *info = dev->dev.driver_data; | ||
836 | unsigned long flags; | ||
837 | |||
838 | dev_dbg(&dev->dev, "blkfront_closing: %s removed\n", dev->nodename); | ||
839 | |||
840 | if (info->rq == NULL) | ||
841 | goto out; | ||
842 | |||
843 | spin_lock_irqsave(&blkif_io_lock, flags); | ||
844 | |||
845 | del_gendisk(info->gd); | ||
846 | |||
847 | /* No more blkif_request(). */ | ||
848 | blk_stop_queue(info->rq); | ||
849 | |||
850 | /* No more gnttab callback work. */ | ||
851 | gnttab_cancel_free_callback(&info->callback); | ||
852 | spin_unlock_irqrestore(&blkif_io_lock, flags); | ||
853 | |||
854 | /* Flush gnttab callback work. Must be done with no locks held. */ | ||
855 | flush_scheduled_work(); | ||
856 | |||
857 | blk_cleanup_queue(info->rq); | ||
858 | info->rq = NULL; | ||
859 | |||
860 | out: | ||
861 | xenbus_frontend_closed(dev); | ||
862 | } | ||
863 | |||
864 | /** | ||
865 | * Callback received when the backend's state changes. | ||
866 | */ | ||
867 | static void backend_changed(struct xenbus_device *dev, | ||
868 | enum xenbus_state backend_state) | ||
869 | { | ||
870 | struct blkfront_info *info = dev->dev.driver_data; | ||
871 | struct block_device *bd; | ||
872 | |||
873 | dev_dbg(&dev->dev, "blkfront:backend_changed.\n"); | ||
874 | |||
875 | switch (backend_state) { | ||
876 | case XenbusStateInitialising: | ||
877 | case XenbusStateInitWait: | ||
878 | case XenbusStateInitialised: | ||
879 | case XenbusStateUnknown: | ||
880 | case XenbusStateClosed: | ||
881 | break; | ||
882 | |||
883 | case XenbusStateConnected: | ||
884 | blkfront_connect(info); | ||
885 | break; | ||
886 | |||
887 | case XenbusStateClosing: | ||
888 | bd = bdget(info->dev); | ||
889 | if (bd == NULL) | ||
890 | xenbus_dev_fatal(dev, -ENODEV, "bdget failed"); | ||
891 | |||
892 | mutex_lock(&bd->bd_mutex); | ||
893 | if (info->users > 0) | ||
894 | xenbus_dev_error(dev, -EBUSY, | ||
895 | "Device in use; refusing to close"); | ||
896 | else | ||
897 | blkfront_closing(dev); | ||
898 | mutex_unlock(&bd->bd_mutex); | ||
899 | bdput(bd); | ||
900 | break; | ||
901 | } | ||
902 | } | ||
903 | |||
904 | static int blkfront_remove(struct xenbus_device *dev) | ||
905 | { | ||
906 | struct blkfront_info *info = dev->dev.driver_data; | ||
907 | |||
908 | dev_dbg(&dev->dev, "blkfront_remove: %s removed\n", dev->nodename); | ||
909 | |||
910 | blkif_free(info, 0); | ||
911 | |||
912 | kfree(info); | ||
913 | |||
914 | return 0; | ||
915 | } | ||
916 | |||
917 | static int blkif_open(struct inode *inode, struct file *filep) | ||
918 | { | ||
919 | struct blkfront_info *info = inode->i_bdev->bd_disk->private_data; | ||
920 | info->users++; | ||
921 | return 0; | ||
922 | } | ||
923 | |||
924 | static int blkif_release(struct inode *inode, struct file *filep) | ||
925 | { | ||
926 | struct blkfront_info *info = inode->i_bdev->bd_disk->private_data; | ||
927 | info->users--; | ||
928 | if (info->users == 0) { | ||
929 | /* Check whether we have been instructed to close. We will | ||
930 | have ignored this request initially, as the device was | ||
931 | still mounted. */ | ||
932 | struct xenbus_device *dev = info->xbdev; | ||
933 | enum xenbus_state state = xenbus_read_driver_state(dev->otherend); | ||
934 | |||
935 | if (state == XenbusStateClosing) | ||
936 | blkfront_closing(dev); | ||
937 | } | ||
938 | return 0; | ||
939 | } | ||
940 | |||
941 | static struct block_device_operations xlvbd_block_fops = | ||
942 | { | ||
943 | .owner = THIS_MODULE, | ||
944 | .open = blkif_open, | ||
945 | .release = blkif_release, | ||
946 | }; | ||
947 | |||
948 | |||
949 | static struct xenbus_device_id blkfront_ids[] = { | ||
950 | { "vbd" }, | ||
951 | { "" } | ||
952 | }; | ||
953 | |||
954 | static struct xenbus_driver blkfront = { | ||
955 | .name = "vbd", | ||
956 | .owner = THIS_MODULE, | ||
957 | .ids = blkfront_ids, | ||
958 | .probe = blkfront_probe, | ||
959 | .remove = blkfront_remove, | ||
960 | .resume = blkfront_resume, | ||
961 | .otherend_changed = backend_changed, | ||
962 | }; | ||
963 | |||
964 | static int __init xlblk_init(void) | ||
965 | { | ||
966 | if (!is_running_on_xen()) | ||
967 | return -ENODEV; | ||
968 | |||
969 | if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) { | ||
970 | printk(KERN_WARNING "xen_blk: can't get major %d with name %s\n", | ||
971 | XENVBD_MAJOR, DEV_NAME); | ||
972 | return -ENODEV; | ||
973 | } | ||
974 | |||
975 | return xenbus_register_frontend(&blkfront); | ||
976 | } | ||
977 | module_init(xlblk_init); | ||
978 | |||
979 | |||
980 | static void xlblk_exit(void) | ||
981 | { | ||
982 | return xenbus_unregister_driver(&blkfront); | ||
983 | } | ||
984 | module_exit(xlblk_exit); | ||
985 | |||
986 | MODULE_DESCRIPTION("Xen virtual block device frontend"); | ||
987 | MODULE_LICENSE("GPL"); | ||
988 | MODULE_ALIAS_BLOCKDEV_MAJOR(XENVBD_MAJOR); | ||
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 97bd71bc3aea..9e8f21410d2d 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -604,6 +604,14 @@ config HVC_BEAT | |||
604 | help | 604 | help |
605 | Toshiba's Cell Reference Set Beat Console device driver | 605 | Toshiba's Cell Reference Set Beat Console device driver |
606 | 606 | ||
607 | config HVC_XEN | ||
608 | bool "Xen Hypervisor Console support" | ||
609 | depends on XEN | ||
610 | select HVC_DRIVER | ||
611 | default y | ||
612 | help | ||
613 | Xen virtual console device driver | ||
614 | |||
607 | config HVCS | 615 | config HVCS |
608 | tristate "IBM Hypervisor Virtual Console Server support" | 616 | tristate "IBM Hypervisor Virtual Console Server support" |
609 | depends on PPC_PSERIES | 617 | depends on PPC_PSERIES |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index f2996a95eb07..8852b8d643cf 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -48,6 +48,7 @@ obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o | |||
48 | obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o | 48 | obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o |
49 | obj-$(CONFIG_HVC_BEAT) += hvc_beat.o | 49 | obj-$(CONFIG_HVC_BEAT) += hvc_beat.o |
50 | obj-$(CONFIG_HVC_DRIVER) += hvc_console.o | 50 | obj-$(CONFIG_HVC_DRIVER) += hvc_console.o |
51 | obj-$(CONFIG_HVC_XEN) += hvc_xen.o | ||
51 | obj-$(CONFIG_RAW_DRIVER) += raw.o | 52 | obj-$(CONFIG_RAW_DRIVER) += raw.o |
52 | obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o | 53 | obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o |
53 | obj-$(CONFIG_MSPEC) += mspec.o | 54 | obj-$(CONFIG_MSPEC) += mspec.o |
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c new file mode 100644 index 000000000000..dd68f8541c2d --- /dev/null +++ b/drivers/char/hvc_xen.c | |||
@@ -0,0 +1,159 @@ | |||
1 | /* | ||
2 | * xen console driver interface to hvc_console.c | ||
3 | * | ||
4 | * (c) 2007 Gerd Hoffmann <kraxel@suse.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/console.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/types.h> | ||
26 | |||
27 | #include <asm/xen/hypervisor.h> | ||
28 | #include <xen/page.h> | ||
29 | #include <xen/events.h> | ||
30 | #include <xen/interface/io/console.h> | ||
31 | #include <xen/hvc-console.h> | ||
32 | |||
33 | #include "hvc_console.h" | ||
34 | |||
35 | #define HVC_COOKIE 0x58656e /* "Xen" in hex */ | ||
36 | |||
37 | static struct hvc_struct *hvc; | ||
38 | static int xencons_irq; | ||
39 | |||
40 | /* ------------------------------------------------------------------ */ | ||
41 | |||
42 | static inline struct xencons_interface *xencons_interface(void) | ||
43 | { | ||
44 | return mfn_to_virt(xen_start_info->console.domU.mfn); | ||
45 | } | ||
46 | |||
47 | static inline void notify_daemon(void) | ||
48 | { | ||
49 | /* Use evtchn: this is called early, before irq is set up. */ | ||
50 | notify_remote_via_evtchn(xen_start_info->console.domU.evtchn); | ||
51 | } | ||
52 | |||
53 | static int write_console(uint32_t vtermno, const char *data, int len) | ||
54 | { | ||
55 | struct xencons_interface *intf = xencons_interface(); | ||
56 | XENCONS_RING_IDX cons, prod; | ||
57 | int sent = 0; | ||
58 | |||
59 | cons = intf->out_cons; | ||
60 | prod = intf->out_prod; | ||
61 | mb(); /* update queue values before going on */ | ||
62 | BUG_ON((prod - cons) > sizeof(intf->out)); | ||
63 | |||
64 | while ((sent < len) && ((prod - cons) < sizeof(intf->out))) | ||
65 | intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++]; | ||
66 | |||
67 | wmb(); /* write ring before updating pointer */ | ||
68 | intf->out_prod = prod; | ||
69 | |||
70 | notify_daemon(); | ||
71 | return sent; | ||
72 | } | ||
73 | |||
74 | static int read_console(uint32_t vtermno, char *buf, int len) | ||
75 | { | ||
76 | struct xencons_interface *intf = xencons_interface(); | ||
77 | XENCONS_RING_IDX cons, prod; | ||
78 | int recv = 0; | ||
79 | |||
80 | cons = intf->in_cons; | ||
81 | prod = intf->in_prod; | ||
82 | mb(); /* get pointers before reading ring */ | ||
83 | BUG_ON((prod - cons) > sizeof(intf->in)); | ||
84 | |||
85 | while (cons != prod && recv < len) | ||
86 | buf[recv++] = intf->in[MASK_XENCONS_IDX(cons++, intf->in)]; | ||
87 | |||
88 | mb(); /* read ring before consuming */ | ||
89 | intf->in_cons = cons; | ||
90 | |||
91 | notify_daemon(); | ||
92 | return recv; | ||
93 | } | ||
94 | |||
95 | static struct hv_ops hvc_ops = { | ||
96 | .get_chars = read_console, | ||
97 | .put_chars = write_console, | ||
98 | }; | ||
99 | |||
100 | static int __init xen_init(void) | ||
101 | { | ||
102 | struct hvc_struct *hp; | ||
103 | |||
104 | if (!is_running_on_xen()) | ||
105 | return 0; | ||
106 | |||
107 | xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); | ||
108 | if (xencons_irq < 0) | ||
109 | xencons_irq = 0 /* NO_IRQ */; | ||
110 | hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256); | ||
111 | if (IS_ERR(hp)) | ||
112 | return PTR_ERR(hp); | ||
113 | |||
114 | hvc = hp; | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static void __exit xen_fini(void) | ||
119 | { | ||
120 | if (hvc) | ||
121 | hvc_remove(hvc); | ||
122 | } | ||
123 | |||
124 | static int xen_cons_init(void) | ||
125 | { | ||
126 | if (!is_running_on_xen()) | ||
127 | return 0; | ||
128 | |||
129 | hvc_instantiate(HVC_COOKIE, 0, &hvc_ops); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | module_init(xen_init); | ||
134 | module_exit(xen_fini); | ||
135 | console_initcall(xen_cons_init); | ||
136 | |||
137 | static void xenboot_write_console(struct console *console, const char *string, | ||
138 | unsigned len) | ||
139 | { | ||
140 | unsigned int linelen, off = 0; | ||
141 | const char *pos; | ||
142 | |||
143 | while (off < len && NULL != (pos = strchr(string+off, '\n'))) { | ||
144 | linelen = pos-string+off; | ||
145 | if (off + linelen > len) | ||
146 | break; | ||
147 | write_console(0, string+off, linelen); | ||
148 | write_console(0, "\r\n", 2); | ||
149 | off += linelen + 1; | ||
150 | } | ||
151 | if (off < len) | ||
152 | write_console(0, string+off, len-off); | ||
153 | } | ||
154 | |||
155 | struct console xenboot_console = { | ||
156 | .name = "xenboot", | ||
157 | .write = xenboot_write_console, | ||
158 | .flags = CON_PRINTBUFFER | CON_BOOT, | ||
159 | }; | ||
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index dbb22403979f..3d90fc002097 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -1770,7 +1770,8 @@ static int call_critical_overtemp(void) | |||
1770 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin", | 1770 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin", |
1771 | NULL }; | 1771 | NULL }; |
1772 | 1772 | ||
1773 | return call_usermodehelper(critical_overtemp_path, argv, envp, 0); | 1773 | return call_usermodehelper(critical_overtemp_path, |
1774 | argv, envp, UMH_WAIT_EXEC); | ||
1774 | } | 1775 | } |
1775 | 1776 | ||
1776 | 1777 | ||
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index e18d265d5d33..516d943227e2 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c | |||
@@ -80,7 +80,8 @@ int wf_critical_overtemp(void) | |||
80 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin", | 80 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin", |
81 | NULL }; | 81 | NULL }; |
82 | 82 | ||
83 | return call_usermodehelper(critical_overtemp_path, argv, envp, 0); | 83 | return call_usermodehelper(critical_overtemp_path, |
84 | argv, envp, UMH_WAIT_EXEC); | ||
84 | } | 85 | } |
85 | EXPORT_SYMBOL_GPL(wf_critical_overtemp); | 86 | EXPORT_SYMBOL_GPL(wf_critical_overtemp); |
86 | 87 | ||
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 624b21cef5b3..d9d033e07e19 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig | |||
@@ -80,8 +80,12 @@ config VIDEO_BUF_DVB | |||
80 | config VIDEO_BTCX | 80 | config VIDEO_BTCX |
81 | tristate | 81 | tristate |
82 | 82 | ||
83 | config VIDEO_IR_I2C | ||
84 | tristate | ||
85 | |||
83 | config VIDEO_IR | 86 | config VIDEO_IR |
84 | tristate | 87 | tristate |
88 | select VIDEO_IR_I2C if I2C | ||
85 | 89 | ||
86 | config VIDEO_TVEEPROM | 90 | config VIDEO_TVEEPROM |
87 | tristate | 91 | tristate |
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index fcb194135627..fe447a06e24e 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c | |||
@@ -107,21 +107,20 @@ void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, | |||
107 | } | 107 | } |
108 | 108 | ||
109 | /* -------------------------------------------------------------------------- */ | 109 | /* -------------------------------------------------------------------------- */ |
110 | 110 | /* extract mask bits out of data and pack them into the result */ | |
111 | u32 ir_extract_bits(u32 data, u32 mask) | 111 | u32 ir_extract_bits(u32 data, u32 mask) |
112 | { | 112 | { |
113 | int mbit, vbit; | 113 | u32 vbit = 1, value = 0; |
114 | u32 value; | 114 | |
115 | do { | ||
116 | if (mask&1) { | ||
117 | if (data&1) | ||
118 | value |= vbit; | ||
119 | vbit<<=1; | ||
120 | } | ||
121 | data>>=1; | ||
122 | } while (mask>>=1); | ||
115 | 123 | ||
116 | value = 0; | ||
117 | vbit = 0; | ||
118 | for (mbit = 0; mbit < 32; mbit++) { | ||
119 | if (!(mask & ((u32)1 << mbit))) | ||
120 | continue; | ||
121 | if (data & ((u32)1 << mbit)) | ||
122 | value |= (1 << vbit); | ||
123 | vbit++; | ||
124 | } | ||
125 | return value; | 124 | return value; |
126 | } | 125 | } |
127 | 126 | ||
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c index ef3e54cd9407..ba6701e97671 100644 --- a/drivers/media/common/saa7146_core.c +++ b/drivers/media/common/saa7146_core.c | |||
@@ -27,7 +27,7 @@ static int saa7146_num; | |||
27 | 27 | ||
28 | unsigned int saa7146_debug; | 28 | unsigned int saa7146_debug; |
29 | 29 | ||
30 | module_param(saa7146_debug, int, 0644); | 30 | module_param(saa7146_debug, uint, 0644); |
31 | MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)"); | 31 | MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)"); |
32 | 32 | ||
33 | #if 0 | 33 | #if 0 |
@@ -130,10 +130,10 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) | |||
130 | /********************************************************************************/ | 130 | /********************************************************************************/ |
131 | /* common page table functions */ | 131 | /* common page table functions */ |
132 | 132 | ||
133 | char *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt) | 133 | void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt) |
134 | { | 134 | { |
135 | int pages = (length+PAGE_SIZE-1)/PAGE_SIZE; | 135 | int pages = (length+PAGE_SIZE-1)/PAGE_SIZE; |
136 | char *mem = vmalloc_32(length); | 136 | void *mem = vmalloc_32(length); |
137 | int slen = 0; | 137 | int slen = 0; |
138 | 138 | ||
139 | if (NULL == mem) | 139 | if (NULL == mem) |
@@ -168,7 +168,7 @@ err_null: | |||
168 | return NULL; | 168 | return NULL; |
169 | } | 169 | } |
170 | 170 | ||
171 | void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, char *mem, struct saa7146_pgtable *pt) | 171 | void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, void *mem, struct saa7146_pgtable *pt) |
172 | { | 172 | { |
173 | pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE); | 173 | pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE); |
174 | saa7146_pgtable_free(pci, pt); | 174 | saa7146_pgtable_free(pci, pt); |
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index e3d04a4cef4d..664280c78ff2 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
@@ -889,9 +889,9 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int | |||
889 | 889 | ||
890 | DEB_EE(("VIDIOC_QUERYCAP\n")); | 890 | DEB_EE(("VIDIOC_QUERYCAP\n")); |
891 | 891 | ||
892 | strcpy(cap->driver, "saa7146 v4l2"); | 892 | strcpy((char *)cap->driver, "saa7146 v4l2"); |
893 | strlcpy(cap->card, dev->ext->name, sizeof(cap->card)); | 893 | strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); |
894 | sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); | 894 | sprintf((char *)cap->bus_info,"PCI:%s", pci_name(dev->pci)); |
895 | cap->version = SAA7146_VERSION_CODE; | 895 | cap->version = SAA7146_VERSION_CODE; |
896 | cap->capabilities = | 896 | cap->capabilities = |
897 | V4L2_CAP_VIDEO_CAPTURE | | 897 | V4L2_CAP_VIDEO_CAPTURE | |
@@ -968,7 +968,7 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int | |||
968 | } | 968 | } |
969 | memset(f,0,sizeof(*f)); | 969 | memset(f,0,sizeof(*f)); |
970 | f->index = index; | 970 | f->index = index; |
971 | strlcpy(f->description,formats[index].name,sizeof(f->description)); | 971 | strlcpy((char *)f->description,formats[index].name,sizeof(f->description)); |
972 | f->pixelformat = formats[index].pixelformat; | 972 | f->pixelformat = formats[index].pixelformat; |
973 | break; | 973 | break; |
974 | } | 974 | } |
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig index a0dcd59da76e..3197aeb61d1f 100644 --- a/drivers/media/dvb/b2c2/Kconfig +++ b/drivers/media/dvb/b2c2/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | config DVB_B2C2_FLEXCOP | 1 | config DVB_B2C2_FLEXCOP |
2 | tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters" | 2 | tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters" |
3 | depends on DVB_CORE && I2C | 3 | depends on DVB_CORE && I2C |
4 | select DVB_PLL | 4 | select DVB_PLL if !DVB_FE_CUSTOMISE |
5 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | 5 | select DVB_STV0299 if !DVB_FE_CUSTOMISE |
6 | select DVB_MT352 if !DVB_FE_CUSTOMISE | 6 | select DVB_MT352 if !DVB_FE_CUSTOMISE |
7 | select DVB_MT312 if !DVB_FE_CUSTOMISE | 7 | select DVB_MT312 if !DVB_FE_CUSTOMISE |
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile index bff00b58bf65..e97ff60a1eff 100644 --- a/drivers/media/dvb/b2c2/Makefile +++ b/drivers/media/dvb/b2c2/Makefile | |||
@@ -12,4 +12,4 @@ obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o | |||
12 | b2c2-flexcop-usb-objs = flexcop-usb.o | 12 | b2c2-flexcop-usb-objs = flexcop-usb.o |
13 | obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o | 13 | obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o |
14 | 14 | ||
15 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | 15 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ |
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index b02c2fd65baa..0378fd646591 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
@@ -500,13 +500,13 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
500 | /* try the air atsc 2nd generation (nxt2002) */ | 500 | /* try the air atsc 2nd generation (nxt2002) */ |
501 | if ((fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, &fc->i2c_adap)) != NULL) { | 501 | if ((fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, &fc->i2c_adap)) != NULL) { |
502 | fc->dev_type = FC_AIR_ATSC2; | 502 | fc->dev_type = FC_AIR_ATSC2; |
503 | dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, &dvb_pll_samsung_tbmv); | 503 | dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV); |
504 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); | 504 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); |
505 | } else | 505 | } else |
506 | /* try the air atsc 3nd generation (lgdt3303) */ | 506 | /* try the air atsc 3nd generation (lgdt3303) */ |
507 | if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { | 507 | if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { |
508 | fc->dev_type = FC_AIR_ATSC3; | 508 | fc->dev_type = FC_AIR_ATSC3; |
509 | dvb_attach(dvb_pll_attach, fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_lg_tdvs_h06xf); | 509 | dvb_attach(dvb_pll_attach, fc->fe, 0x61, &fc->i2c_adap, DVB_PLL_LG_TDVS_H06XF); |
510 | info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); | 510 | info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); |
511 | } else | 511 | } else |
512 | /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ | 512 | /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ |
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig index cfd6fb729a61..ea666174e988 100644 --- a/drivers/media/dvb/bt8xx/Kconfig +++ b/drivers/media/dvb/bt8xx/Kconfig | |||
@@ -7,7 +7,7 @@ config DVB_BT8XX | |||
7 | select DVB_CX24110 if !DVB_FE_CUSTOMISE | 7 | select DVB_CX24110 if !DVB_FE_CUSTOMISE |
8 | select DVB_OR51211 if !DVB_FE_CUSTOMISE | 8 | select DVB_OR51211 if !DVB_FE_CUSTOMISE |
9 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | 9 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE |
10 | select DVB_PLL | 10 | select DVB_PLL if !DVB_FE_CUSTOMISE |
11 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | 11 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE |
12 | select FW_LOADER | 12 | select FW_LOADER |
13 | help | 13 | help |
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile index 9d197efb481d..84cf70504d17 100644 --- a/drivers/media/dvb/bt8xx/Makefile +++ b/drivers/media/dvb/bt8xx/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o | 1 | obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o |
2 | 2 | ||
3 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video/bt8xx -Idrivers/media/dvb/frontends | 3 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video/bt8xx -Idrivers/media/dvb/frontends |
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index e908e3cf1e50..b7a17e69ca4d 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -1652,7 +1652,7 @@ static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_paramet | |||
1652 | static int dst_tune_frontend(struct dvb_frontend* fe, | 1652 | static int dst_tune_frontend(struct dvb_frontend* fe, |
1653 | struct dvb_frontend_parameters* p, | 1653 | struct dvb_frontend_parameters* p, |
1654 | unsigned int mode_flags, | 1654 | unsigned int mode_flags, |
1655 | int *delay, | 1655 | unsigned int *delay, |
1656 | fe_status_t *status) | 1656 | fe_status_t *status) |
1657 | { | 1657 | { |
1658 | struct dst_state *state = fe->demodulator_priv; | 1658 | struct dst_state *state = fe->demodulator_priv; |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 4f1c09bee538..67613eb6fa3d 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c | |||
@@ -611,7 +611,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
611 | card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter); | 611 | card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter); |
612 | if (card->fe != NULL) { | 612 | if (card->fe != NULL) { |
613 | dvb_attach(dvb_pll_attach, card->fe, 0x61, | 613 | dvb_attach(dvb_pll_attach, card->fe, 0x61, |
614 | card->i2c_adapter, &dvb_pll_lg_tdvs_h06xf); | 614 | card->i2c_adapter, DVB_PLL_LG_TDVS_H06XF); |
615 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); | 615 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); |
616 | } | 616 | } |
617 | break; | 617 | break; |
@@ -692,6 +692,9 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
692 | 692 | ||
693 | case BTTV_BOARD_PC_HDTV: | 693 | case BTTV_BOARD_PC_HDTV: |
694 | card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter); | 694 | card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter); |
695 | if (card->fe != NULL) | ||
696 | dvb_attach(dvb_pll_attach, card->fe, 0x61, | ||
697 | card->i2c_adapter, DVB_PLL_FCV1236D); | ||
695 | break; | 698 | break; |
696 | } | 699 | } |
697 | 700 | ||
diff --git a/drivers/media/dvb/cinergyT2/Makefile b/drivers/media/dvb/cinergyT2/Makefile index c51aece20f9f..d762d8cb0cf1 100644 --- a/drivers/media/dvb/cinergyT2/Makefile +++ b/drivers/media/dvb/cinergyT2/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | obj-$(CONFIG_DVB_CINERGYT2) += cinergyT2.o | 1 | obj-$(CONFIG_DVB_CINERGYT2) += cinergyT2.o |
2 | 2 | ||
3 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ | 3 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ |
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index b40af48a2edb..5a1449f485cf 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -829,7 +829,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) | |||
829 | input_dev->id.vendor = cinergyt2->udev->descriptor.idVendor; | 829 | input_dev->id.vendor = cinergyt2->udev->descriptor.idVendor; |
830 | input_dev->id.product = cinergyt2->udev->descriptor.idProduct; | 830 | input_dev->id.product = cinergyt2->udev->descriptor.idProduct; |
831 | input_dev->id.version = 1; | 831 | input_dev->id.version = 1; |
832 | input_dev->cdev.dev = &cinergyt2->udev->dev; | 832 | input_dev->dev.parent = &cinergyt2->udev->dev; |
833 | 833 | ||
834 | err = input_register_device(input_dev); | 834 | err = input_register_device(input_dev); |
835 | if (err) { | 835 | if (err) { |
@@ -1000,18 +1000,15 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) | |||
1000 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem)) | 1000 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem)) |
1001 | return -ERESTARTSYS; | 1001 | return -ERESTARTSYS; |
1002 | 1002 | ||
1003 | if (1) { | 1003 | cinergyt2_suspend_rc(cinergyt2); |
1004 | cinergyt2_suspend_rc(cinergyt2); | 1004 | cancel_rearming_delayed_work(&cinergyt2->query_work); |
1005 | cancel_rearming_delayed_work(&cinergyt2->query_work); | ||
1006 | 1005 | ||
1007 | mutex_lock(&cinergyt2->sem); | 1006 | mutex_lock(&cinergyt2->sem); |
1008 | if (cinergyt2->streaming) | 1007 | if (cinergyt2->streaming) |
1009 | cinergyt2_stop_stream_xfer(cinergyt2); | 1008 | cinergyt2_stop_stream_xfer(cinergyt2); |
1010 | cinergyt2_sleep(cinergyt2, 1); | 1009 | cinergyt2_sleep(cinergyt2, 1); |
1011 | mutex_unlock(&cinergyt2->sem); | 1010 | mutex_unlock(&cinergyt2->sem); |
1012 | } | ||
1013 | 1011 | ||
1014 | mutex_unlock(&cinergyt2->wq_sem); | ||
1015 | return 0; | 1012 | return 0; |
1016 | } | 1013 | } |
1017 | 1014 | ||
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 275df65fde99..5394de2e4ce0 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c | |||
@@ -97,7 +97,7 @@ static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src, | |||
97 | if (avail > todo) | 97 | if (avail > todo) |
98 | avail = todo; | 98 | avail = todo; |
99 | 99 | ||
100 | ret = dvb_ringbuffer_read(src, buf, avail, 1); | 100 | ret = dvb_ringbuffer_read(src, (u8 *)buf, avail, 1); |
101 | if (ret < 0) | 101 | if (ret < 0) |
102 | break; | 102 | break; |
103 | 103 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 2a03bf53cb29..4fadddb264d6 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c | |||
@@ -175,7 +175,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * e | |||
175 | * @param nlen Number of bytes in needle. | 175 | * @param nlen Number of bytes in needle. |
176 | * @return Pointer into haystack needle was found at, or NULL if not found. | 176 | * @return Pointer into haystack needle was found at, or NULL if not found. |
177 | */ | 177 | */ |
178 | static u8 *findstr(u8 * haystack, int hlen, u8 * needle, int nlen) | 178 | static char *findstr(char * haystack, int hlen, char * needle, int nlen) |
179 | { | 179 | { |
180 | int i; | 180 | int i; |
181 | 181 | ||
@@ -482,7 +482,7 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) | |||
482 | } | 482 | } |
483 | 483 | ||
484 | /* check it contains the correct DVB string */ | 484 | /* check it contains the correct DVB string */ |
485 | dvb_str = findstr(tuple, tupleLength, "DVB_CI_V", 8); | 485 | dvb_str = findstr((char *)tuple, tupleLength, "DVB_CI_V", 8); |
486 | if (dvb_str == NULL) | 486 | if (dvb_str == NULL) |
487 | return -EINVAL; | 487 | return -EINVAL; |
488 | if (tupleLength < ((dvb_str - (char *) tuple) + 12)) | 488 | if (tupleLength < ((dvb_str - (char *) tuple) + 12)) |
@@ -513,8 +513,8 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) | |||
513 | ca->slot_info[slot].config_option = tuple[0] & 0x3f; | 513 | ca->slot_info[slot].config_option = tuple[0] & 0x3f; |
514 | 514 | ||
515 | /* OK, check it contains the correct strings */ | 515 | /* OK, check it contains the correct strings */ |
516 | if ((findstr(tuple, tupleLength, "DVB_HOST", 8) == NULL) || | 516 | if ((findstr((char *)tuple, tupleLength, "DVB_HOST", 8) == NULL) || |
517 | (findstr(tuple, tupleLength, "DVB_CI_MODULE", 13) == NULL)) | 517 | (findstr((char *)tuple, tupleLength, "DVB_CI_MODULE", 13) == NULL)) |
518 | break; | 518 | break; |
519 | 519 | ||
520 | got_cftableentry = 1; | 520 | got_cftableentry = 1; |
@@ -1300,7 +1300,7 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, | |||
1300 | struct dvb_ca_private *ca = dvbdev->priv; | 1300 | struct dvb_ca_private *ca = dvbdev->priv; |
1301 | u8 slot, connection_id; | 1301 | u8 slot, connection_id; |
1302 | int status; | 1302 | int status; |
1303 | char fragbuf[HOST_LINK_BUF_SIZE]; | 1303 | u8 fragbuf[HOST_LINK_BUF_SIZE]; |
1304 | int fragpos = 0; | 1304 | int fragpos = 0; |
1305 | int fraglen; | 1305 | int fraglen; |
1306 | unsigned long timeout; | 1306 | unsigned long timeout; |
@@ -1486,7 +1486,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, | |||
1486 | } | 1486 | } |
1487 | 1487 | ||
1488 | if ((status = dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 2, | 1488 | if ((status = dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 2, |
1489 | buf + pktlen, fraglen, 1)) < 0) { | 1489 | (u8 *)buf + pktlen, fraglen, 1)) < 0) { |
1490 | goto exit; | 1490 | goto exit; |
1491 | } | 1491 | } |
1492 | pktlen += fraglen; | 1492 | pktlen += fraglen; |
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index 6d8d1c3df863..cb6987fce26c 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c | |||
@@ -1068,7 +1068,7 @@ static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count) | |||
1068 | 1068 | ||
1069 | if (mutex_lock_interruptible(&dvbdemux->mutex)) | 1069 | if (mutex_lock_interruptible(&dvbdemux->mutex)) |
1070 | return -ERESTARTSYS; | 1070 | return -ERESTARTSYS; |
1071 | dvb_dmx_swfilter(dvbdemux, buf, count); | 1071 | dvb_dmx_swfilter(dvbdemux, (u8 *)buf, count); |
1072 | mutex_unlock(&dvbdemux->mutex); | 1072 | mutex_unlock(&dvbdemux->mutex); |
1073 | 1073 | ||
1074 | if (signal_pending(current)) | 1074 | if (signal_pending(current)) |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index f233d78bc364..a770a87b9a93 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h | |||
@@ -103,7 +103,7 @@ struct dvb_frontend_ops { | |||
103 | int (*tune)(struct dvb_frontend* fe, | 103 | int (*tune)(struct dvb_frontend* fe, |
104 | struct dvb_frontend_parameters* params, | 104 | struct dvb_frontend_parameters* params, |
105 | unsigned int mode_flags, | 105 | unsigned int mode_flags, |
106 | int *delay, | 106 | unsigned int *delay, |
107 | fe_status_t *status); | 107 | fe_status_t *status); |
108 | /* get frontend tuning algorithm from the module */ | 108 | /* get frontend tuning algorithm from the module */ |
109 | int (*get_frontend_algo)(struct dvb_frontend *fe); | 109 | int (*get_frontend_algo)(struct dvb_frontend *fe); |
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 4ebf33a5ffa2..acf026342ec5 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
@@ -347,7 +347,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
347 | { | 347 | { |
348 | struct dvb_net_priv *priv = dev->priv; | 348 | struct dvb_net_priv *priv = dev->priv; |
349 | unsigned long skipped = 0L; | 349 | unsigned long skipped = 0L; |
350 | u8 *ts, *ts_end, *from_where = NULL, ts_remain = 0, how_much = 0, new_ts = 1; | 350 | const u8 *ts, *ts_end, *from_where = NULL; |
351 | u8 ts_remain = 0, how_much = 0, new_ts = 1; | ||
351 | struct ethhdr *ethh = NULL; | 352 | struct ethhdr *ethh = NULL; |
352 | 353 | ||
353 | #ifdef ULE_DEBUG | 354 | #ifdef ULE_DEBUG |
@@ -364,7 +365,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
364 | /* For all TS cells in current buffer. | 365 | /* For all TS cells in current buffer. |
365 | * Appearently, we are called for every single TS cell. | 366 | * Appearently, we are called for every single TS cell. |
366 | */ | 367 | */ |
367 | for (ts = (char *)buf, ts_end = (char *)buf + buf_len; ts < ts_end; /* no default incr. */ ) { | 368 | for (ts = buf, ts_end = buf + buf_len; ts < ts_end; /* no default incr. */ ) { |
368 | 369 | ||
369 | if (new_ts) { | 370 | if (new_ts) { |
370 | /* We are about to process a new TS cell. */ | 371 | /* We are about to process a new TS cell. */ |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index a9fa3337dd81..9ef0c00605ee 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -208,7 +208,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | |||
208 | if ((id = dvbdev_get_free_id (adap, type)) < 0){ | 208 | if ((id = dvbdev_get_free_id (adap, type)) < 0){ |
209 | mutex_unlock(&dvbdev_register_lock); | 209 | mutex_unlock(&dvbdev_register_lock); |
210 | *pdvbdev = NULL; | 210 | *pdvbdev = NULL; |
211 | printk ("%s: could get find free device id...\n", __FUNCTION__); | 211 | printk(KERN_ERR "%s: couldn't find free device id\n", __FUNCTION__); |
212 | return -ENFILE; | 212 | return -ENFILE; |
213 | } | 213 | } |
214 | 214 | ||
@@ -252,7 +252,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | |||
252 | return PTR_ERR(clsdev); | 252 | return PTR_ERR(clsdev); |
253 | } | 253 | } |
254 | 254 | ||
255 | dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", | 255 | dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", |
256 | adap->num, dnames[type], id, nums2minor(adap->num, type, id), | 256 | adap->num, dnames[type], id, nums2minor(adap->num, type, id), |
257 | nums2minor(adap->num, type, id)); | 257 | nums2minor(adap->num, type, id)); |
258 | 258 | ||
@@ -311,7 +311,7 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu | |||
311 | memset (adap, 0, sizeof(struct dvb_adapter)); | 311 | memset (adap, 0, sizeof(struct dvb_adapter)); |
312 | INIT_LIST_HEAD (&adap->device_list); | 312 | INIT_LIST_HEAD (&adap->device_list); |
313 | 313 | ||
314 | printk ("DVB: registering new adapter (%s).\n", name); | 314 | printk(KERN_INFO "DVB: registering new adapter (%s)\n", name); |
315 | 315 | ||
316 | adap->num = num; | 316 | adap->num = num; |
317 | adap->name = name; | 317 | adap->name = name; |
@@ -407,13 +407,13 @@ static int __init init_dvbdev(void) | |||
407 | dev_t dev = MKDEV(DVB_MAJOR, 0); | 407 | dev_t dev = MKDEV(DVB_MAJOR, 0); |
408 | 408 | ||
409 | if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) { | 409 | if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) { |
410 | printk("dvb-core: unable to get major %d\n", DVB_MAJOR); | 410 | printk(KERN_ERR "dvb-core: unable to get major %d\n", DVB_MAJOR); |
411 | return retval; | 411 | return retval; |
412 | } | 412 | } |
413 | 413 | ||
414 | cdev_init(&dvb_device_cdev, &dvb_device_fops); | 414 | cdev_init(&dvb_device_cdev, &dvb_device_fops); |
415 | if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) { | 415 | if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) { |
416 | printk("dvb-core: unable to get major %d\n", DVB_MAJOR); | 416 | printk(KERN_ERR "dvb-core: unable register character device\n"); |
417 | goto error; | 417 | goto error; |
418 | } | 418 | } |
419 | 419 | ||
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 54488737a08f..40e41f2f5afe 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -2,7 +2,6 @@ config DVB_USB | |||
2 | tristate "Support for various USB DVB devices" | 2 | tristate "Support for various USB DVB devices" |
3 | depends on DVB_CORE && USB && I2C | 3 | depends on DVB_CORE && USB && I2C |
4 | select FW_LOADER | 4 | select FW_LOADER |
5 | select DVB_PLL | ||
6 | help | 5 | help |
7 | By enabling this you will be able to choose the various supported | 6 | By enabling this you will be able to choose the various supported |
8 | USB1.1 and USB2.0 DVB devices. | 7 | USB1.1 and USB2.0 DVB devices. |
@@ -27,13 +26,14 @@ config DVB_USB_A800 | |||
27 | depends on DVB_USB | 26 | depends on DVB_USB |
28 | select DVB_DIB3000MC | 27 | select DVB_DIB3000MC |
29 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE | 28 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
29 | select DVB_PLL if !DVB_FE_CUSTOMISE | ||
30 | help | 30 | help |
31 | Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. | 31 | Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. |
32 | 32 | ||
33 | config DVB_USB_DIBUSB_MB | 33 | config DVB_USB_DIBUSB_MB |
34 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" | 34 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" |
35 | depends on DVB_USB | 35 | depends on DVB_USB |
36 | select DVB_PLL | 36 | select DVB_PLL if !DVB_FE_CUSTOMISE |
37 | select DVB_DIB3000MB | 37 | select DVB_DIB3000MB |
38 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE | 38 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
39 | help | 39 | help |
@@ -89,7 +89,7 @@ config DVB_USB_DIB0700 | |||
89 | config DVB_USB_UMT_010 | 89 | config DVB_USB_UMT_010 |
90 | tristate "HanfTek UMT-010 DVB-T USB2.0 support" | 90 | tristate "HanfTek UMT-010 DVB-T USB2.0 support" |
91 | depends on DVB_USB | 91 | depends on DVB_USB |
92 | select DVB_PLL | 92 | select DVB_PLL if !DVB_FE_CUSTOMISE |
93 | select DVB_DIB3000MC | 93 | select DVB_DIB3000MC |
94 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE | 94 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
95 | help | 95 | help |
@@ -98,7 +98,7 @@ config DVB_USB_UMT_010 | |||
98 | config DVB_USB_CXUSB | 98 | config DVB_USB_CXUSB |
99 | tristate "Conexant USB2.0 hybrid reference design support" | 99 | tristate "Conexant USB2.0 hybrid reference design support" |
100 | depends on DVB_USB | 100 | depends on DVB_USB |
101 | select DVB_PLL | 101 | select DVB_PLL if !DVB_FE_CUSTOMISE |
102 | select DVB_CX22702 if !DVB_FE_CUSTOMISE | 102 | select DVB_CX22702 if !DVB_FE_CUSTOMISE |
103 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | 103 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE |
104 | select DVB_MT352 if !DVB_FE_CUSTOMISE | 104 | select DVB_MT352 if !DVB_FE_CUSTOMISE |
@@ -142,7 +142,7 @@ config DVB_USB_AU6610 | |||
142 | config DVB_USB_DIGITV | 142 | config DVB_USB_DIGITV |
143 | tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" | 143 | tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" |
144 | depends on DVB_USB | 144 | depends on DVB_USB |
145 | select DVB_PLL | 145 | select DVB_PLL if !DVB_FE_CUSTOMISE |
146 | select DVB_NXT6000 if !DVB_FE_CUSTOMISE | 146 | select DVB_NXT6000 if !DVB_FE_CUSTOMISE |
147 | select DVB_MT352 if !DVB_FE_CUSTOMISE | 147 | select DVB_MT352 if !DVB_FE_CUSTOMISE |
148 | help | 148 | help |
@@ -188,6 +188,7 @@ config DVB_USB_NOVA_T_USB2 | |||
188 | depends on DVB_USB | 188 | depends on DVB_USB |
189 | select DVB_DIB3000MC | 189 | select DVB_DIB3000MC |
190 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE | 190 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
191 | select DVB_PLL if !DVB_FE_CUSTOMISE | ||
191 | help | 192 | help |
192 | Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. | 193 | Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. |
193 | 194 | ||
@@ -216,5 +217,23 @@ config DVB_USB_OPERA1 | |||
216 | tristate "Opera1 DVB-S USB2.0 receiver" | 217 | tristate "Opera1 DVB-S USB2.0 receiver" |
217 | depends on DVB_USB | 218 | depends on DVB_USB |
218 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | 219 | select DVB_STV0299 if !DVB_FE_CUSTOMISE |
220 | select DVB_PLL if !DVB_FE_CUSTOMISE | ||
219 | help | 221 | help |
220 | Say Y here to support the Opera DVB-S USB2.0 receiver. | 222 | Say Y here to support the Opera DVB-S USB2.0 receiver. |
223 | |||
224 | config DVB_USB_AF9005 | ||
225 | tristate "Afatech AF9005 DVB-T USB1.1 support" | ||
226 | depends on DVB_USB && EXPERIMENTAL | ||
227 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE | ||
228 | select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE | ||
229 | help | ||
230 | Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver | ||
231 | and the TerraTec Cinergy T USB XE (Rev.1) | ||
232 | |||
233 | config DVB_USB_AF9005_REMOTE | ||
234 | tristate "Afatech AF9005 default remote control support" | ||
235 | depends on DVB_USB_AF9005 | ||
236 | help | ||
237 | Say Y here to support the default remote control decoding for the | ||
238 | Afatech AF9005 based receiver. | ||
239 | |||
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 976f840cc904..73ac0a93fdeb 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile | |||
@@ -55,4 +55,10 @@ dvb-usb-opera-objs = opera1.o | |||
55 | obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o | 55 | obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o |
56 | 56 | ||
57 | 57 | ||
58 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | 58 | dvb-usb-af9005-objs = af9005.o af9005-fe.o |
59 | obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o | ||
60 | |||
61 | dvb-usb-af9005-remote-objs = af9005-remote.o | ||
62 | obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o | ||
63 | |||
64 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | ||
diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c new file mode 100644 index 000000000000..7195c9461524 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/af9005-fe.c | |||
@@ -0,0 +1,1503 @@ | |||
1 | /* Frontend part of the Linux driver for the Afatech 9005 | ||
2 | * USB1.1 DVB-T receiver. | ||
3 | * | ||
4 | * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) | ||
5 | * | ||
6 | * Thanks to Afatech who kindly provided information. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * see Documentation/dvb/README.dvb-usb for more information | ||
23 | */ | ||
24 | #include "af9005.h" | ||
25 | #include "af9005-script.h" | ||
26 | #include "mt2060.h" | ||
27 | #include "qt1010.h" | ||
28 | #include <asm/div64.h> | ||
29 | |||
30 | struct af9005_fe_state { | ||
31 | struct dvb_usb_device *d; | ||
32 | struct dvb_frontend *tuner; | ||
33 | |||
34 | fe_status_t stat; | ||
35 | |||
36 | /* retraining parameters */ | ||
37 | u32 original_fcw; | ||
38 | u16 original_rf_top; | ||
39 | u16 original_if_top; | ||
40 | u16 original_if_min; | ||
41 | u16 original_aci0_if_top; | ||
42 | u16 original_aci1_if_top; | ||
43 | u16 original_aci0_if_min; | ||
44 | u8 original_if_unplug_th; | ||
45 | u8 original_rf_unplug_th; | ||
46 | u8 original_dtop_if_unplug_th; | ||
47 | u8 original_dtop_rf_unplug_th; | ||
48 | |||
49 | /* statistics */ | ||
50 | u32 pre_vit_error_count; | ||
51 | u32 pre_vit_bit_count; | ||
52 | u32 ber; | ||
53 | u32 post_vit_error_count; | ||
54 | u32 post_vit_bit_count; | ||
55 | u32 unc; | ||
56 | u16 abort_count; | ||
57 | |||
58 | int opened; | ||
59 | int strong; | ||
60 | unsigned long next_status_check; | ||
61 | struct dvb_frontend frontend; | ||
62 | }; | ||
63 | |||
64 | static int af9005_write_word_agc(struct dvb_usb_device *d, u16 reghi, | ||
65 | u16 reglo, u8 pos, u8 len, u16 value) | ||
66 | { | ||
67 | int ret; | ||
68 | u8 temp; | ||
69 | |||
70 | if ((ret = af9005_write_ofdm_register(d, reglo, (u8) (value & 0xff)))) | ||
71 | return ret; | ||
72 | temp = (u8) ((value & 0x0300) >> 8); | ||
73 | return af9005_write_register_bits(d, reghi, pos, len, | ||
74 | (u8) ((value & 0x300) >> 8)); | ||
75 | } | ||
76 | |||
77 | static int af9005_read_word_agc(struct dvb_usb_device *d, u16 reghi, | ||
78 | u16 reglo, u8 pos, u8 len, u16 * value) | ||
79 | { | ||
80 | int ret; | ||
81 | u8 temp0, temp1; | ||
82 | |||
83 | if ((ret = af9005_read_ofdm_register(d, reglo, &temp0))) | ||
84 | return ret; | ||
85 | if ((ret = af9005_read_ofdm_register(d, reghi, &temp1))) | ||
86 | return ret; | ||
87 | switch (pos) { | ||
88 | case 0: | ||
89 | *value = ((u16) (temp1 & 0x03) << 8) + (u16) temp0; | ||
90 | break; | ||
91 | case 2: | ||
92 | *value = ((u16) (temp1 & 0x0C) << 6) + (u16) temp0; | ||
93 | break; | ||
94 | case 4: | ||
95 | *value = ((u16) (temp1 & 0x30) << 4) + (u16) temp0; | ||
96 | break; | ||
97 | case 6: | ||
98 | *value = ((u16) (temp1 & 0xC0) << 2) + (u16) temp0; | ||
99 | break; | ||
100 | default: | ||
101 | err("invalid pos in read word agc"); | ||
102 | return -EINVAL; | ||
103 | } | ||
104 | return 0; | ||
105 | |||
106 | } | ||
107 | |||
108 | static int af9005_is_fecmon_available(struct dvb_frontend *fe, int *available) | ||
109 | { | ||
110 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
111 | int ret; | ||
112 | u8 temp; | ||
113 | |||
114 | *available = false; | ||
115 | |||
116 | ret = af9005_read_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en, | ||
117 | fec_vtb_rsd_mon_en_pos, | ||
118 | fec_vtb_rsd_mon_en_len, &temp); | ||
119 | if (ret) | ||
120 | return ret; | ||
121 | if (temp & 1) { | ||
122 | ret = | ||
123 | af9005_read_register_bits(state->d, | ||
124 | xd_p_reg_ofsm_read_rbc_en, | ||
125 | reg_ofsm_read_rbc_en_pos, | ||
126 | reg_ofsm_read_rbc_en_len, &temp); | ||
127 | if (ret) | ||
128 | return ret; | ||
129 | if ((temp & 1) == 0) | ||
130 | *available = true; | ||
131 | |||
132 | } | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int af9005_get_post_vit_err_cw_count(struct dvb_frontend *fe, | ||
137 | u32 * post_err_count, | ||
138 | u32 * post_cw_count, | ||
139 | u16 * abort_count) | ||
140 | { | ||
141 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
142 | int ret; | ||
143 | u32 err_count; | ||
144 | u32 cw_count; | ||
145 | u8 temp, temp0, temp1, temp2; | ||
146 | u16 loc_abort_count; | ||
147 | |||
148 | *post_err_count = 0; | ||
149 | *post_cw_count = 0; | ||
150 | |||
151 | /* check if error bit count is ready */ | ||
152 | ret = | ||
153 | af9005_read_register_bits(state->d, xd_r_fec_rsd_ber_rdy, | ||
154 | fec_rsd_ber_rdy_pos, fec_rsd_ber_rdy_len, | ||
155 | &temp); | ||
156 | if (ret) | ||
157 | return ret; | ||
158 | if (!temp) { | ||
159 | deb_info("rsd counter not ready\n"); | ||
160 | return 100; | ||
161 | } | ||
162 | /* get abort count */ | ||
163 | ret = | ||
164 | af9005_read_ofdm_register(state->d, | ||
165 | xd_r_fec_rsd_abort_packet_cnt_7_0, | ||
166 | &temp0); | ||
167 | if (ret) | ||
168 | return ret; | ||
169 | ret = | ||
170 | af9005_read_ofdm_register(state->d, | ||
171 | xd_r_fec_rsd_abort_packet_cnt_15_8, | ||
172 | &temp1); | ||
173 | if (ret) | ||
174 | return ret; | ||
175 | loc_abort_count = ((u16) temp1 << 8) + temp0; | ||
176 | |||
177 | /* get error count */ | ||
178 | ret = | ||
179 | af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_7_0, | ||
180 | &temp0); | ||
181 | if (ret) | ||
182 | return ret; | ||
183 | ret = | ||
184 | af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_15_8, | ||
185 | &temp1); | ||
186 | if (ret) | ||
187 | return ret; | ||
188 | ret = | ||
189 | af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_23_16, | ||
190 | &temp2); | ||
191 | if (ret) | ||
192 | return ret; | ||
193 | err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0; | ||
194 | *post_err_count = err_count - (u32) loc_abort_count *8 * 8; | ||
195 | |||
196 | /* get RSD packet number */ | ||
197 | ret = | ||
198 | af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0, | ||
199 | &temp0); | ||
200 | if (ret) | ||
201 | return ret; | ||
202 | ret = | ||
203 | af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8, | ||
204 | &temp1); | ||
205 | if (ret) | ||
206 | return ret; | ||
207 | cw_count = ((u32) temp1 << 8) + temp0; | ||
208 | if (cw_count == 0) { | ||
209 | err("wrong RSD packet count"); | ||
210 | return -EIO; | ||
211 | } | ||
212 | deb_info("POST abort count %d err count %d rsd packets %d\n", | ||
213 | loc_abort_count, err_count, cw_count); | ||
214 | *post_cw_count = cw_count - (u32) loc_abort_count; | ||
215 | *abort_count = loc_abort_count; | ||
216 | return 0; | ||
217 | |||
218 | } | ||
219 | |||
220 | static int af9005_get_post_vit_ber(struct dvb_frontend *fe, | ||
221 | u32 * post_err_count, u32 * post_cw_count, | ||
222 | u16 * abort_count) | ||
223 | { | ||
224 | u32 loc_cw_count = 0, loc_err_count; | ||
225 | u16 loc_abort_count; | ||
226 | int ret; | ||
227 | |||
228 | ret = | ||
229 | af9005_get_post_vit_err_cw_count(fe, &loc_err_count, &loc_cw_count, | ||
230 | &loc_abort_count); | ||
231 | if (ret) | ||
232 | return ret; | ||
233 | *post_err_count = loc_err_count; | ||
234 | *post_cw_count = loc_cw_count * 204 * 8; | ||
235 | *abort_count = loc_abort_count; | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe, | ||
241 | u32 * pre_err_count, | ||
242 | u32 * pre_bit_count) | ||
243 | { | ||
244 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
245 | u8 temp, temp0, temp1, temp2; | ||
246 | u32 super_frame_count, x, bits; | ||
247 | int ret; | ||
248 | |||
249 | ret = | ||
250 | af9005_read_register_bits(state->d, xd_r_fec_vtb_ber_rdy, | ||
251 | fec_vtb_ber_rdy_pos, fec_vtb_ber_rdy_len, | ||
252 | &temp); | ||
253 | if (ret) | ||
254 | return ret; | ||
255 | if (!temp) { | ||
256 | deb_info("viterbi counter not ready\n"); | ||
257 | return 101; /* ERR_APO_VTB_COUNTER_NOT_READY; */ | ||
258 | } | ||
259 | ret = | ||
260 | af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_7_0, | ||
261 | &temp0); | ||
262 | if (ret) | ||
263 | return ret; | ||
264 | ret = | ||
265 | af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_15_8, | ||
266 | &temp1); | ||
267 | if (ret) | ||
268 | return ret; | ||
269 | ret = | ||
270 | af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_23_16, | ||
271 | &temp2); | ||
272 | if (ret) | ||
273 | return ret; | ||
274 | *pre_err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0; | ||
275 | |||
276 | ret = | ||
277 | af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0, | ||
278 | &temp0); | ||
279 | if (ret) | ||
280 | return ret; | ||
281 | ret = | ||
282 | af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8, | ||
283 | &temp1); | ||
284 | if (ret) | ||
285 | return ret; | ||
286 | super_frame_count = ((u32) temp1 << 8) + temp0; | ||
287 | if (super_frame_count == 0) { | ||
288 | deb_info("super frame count 0\n"); | ||
289 | return 102; | ||
290 | } | ||
291 | |||
292 | /* read fft mode */ | ||
293 | ret = | ||
294 | af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod, | ||
295 | reg_tpsd_txmod_pos, reg_tpsd_txmod_len, | ||
296 | &temp); | ||
297 | if (ret) | ||
298 | return ret; | ||
299 | if (temp == 0) { | ||
300 | /* 2K */ | ||
301 | x = 1512; | ||
302 | } else if (temp == 1) { | ||
303 | /* 8k */ | ||
304 | x = 6048; | ||
305 | } else { | ||
306 | err("Invalid fft mode"); | ||
307 | return -EINVAL; | ||
308 | } | ||
309 | |||
310 | /* read constellation mode */ | ||
311 | ret = | ||
312 | af9005_read_register_bits(state->d, xd_g_reg_tpsd_const, | ||
313 | reg_tpsd_const_pos, reg_tpsd_const_len, | ||
314 | &temp); | ||
315 | if (ret) | ||
316 | return ret; | ||
317 | switch (temp) { | ||
318 | case 0: /* QPSK */ | ||
319 | bits = 2; | ||
320 | break; | ||
321 | case 1: /* QAM_16 */ | ||
322 | bits = 4; | ||
323 | break; | ||
324 | case 2: /* QAM_64 */ | ||
325 | bits = 6; | ||
326 | break; | ||
327 | default: | ||
328 | err("invalid constellation mode"); | ||
329 | return -EINVAL; | ||
330 | } | ||
331 | *pre_bit_count = super_frame_count * 68 * 4 * x * bits; | ||
332 | deb_info("PRE err count %d frame count %d bit count %d\n", | ||
333 | *pre_err_count, super_frame_count, *pre_bit_count); | ||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static int af9005_reset_pre_viterbi(struct dvb_frontend *fe) | ||
338 | { | ||
339 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
340 | int ret; | ||
341 | |||
342 | /* set super frame count to 1 */ | ||
343 | ret = | ||
344 | af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0, | ||
345 | 1 & 0xff); | ||
346 | if (ret) | ||
347 | return ret; | ||
348 | af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8, | ||
349 | 1 >> 8); | ||
350 | if (ret) | ||
351 | return ret; | ||
352 | /* reset pre viterbi error count */ | ||
353 | ret = | ||
354 | af9005_write_register_bits(state->d, xd_p_fec_vtb_ber_rst, | ||
355 | fec_vtb_ber_rst_pos, fec_vtb_ber_rst_len, | ||
356 | 1); | ||
357 | |||
358 | return ret; | ||
359 | } | ||
360 | |||
361 | static int af9005_reset_post_viterbi(struct dvb_frontend *fe) | ||
362 | { | ||
363 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
364 | int ret; | ||
365 | |||
366 | /* set packet unit */ | ||
367 | ret = | ||
368 | af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0, | ||
369 | 10000 & 0xff); | ||
370 | if (ret) | ||
371 | return ret; | ||
372 | ret = | ||
373 | af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8, | ||
374 | 10000 >> 8); | ||
375 | if (ret) | ||
376 | return ret; | ||
377 | /* reset post viterbi error count */ | ||
378 | ret = | ||
379 | af9005_write_register_bits(state->d, xd_p_fec_rsd_ber_rst, | ||
380 | fec_rsd_ber_rst_pos, fec_rsd_ber_rst_len, | ||
381 | 1); | ||
382 | |||
383 | return ret; | ||
384 | } | ||
385 | |||
386 | static int af9005_get_statistic(struct dvb_frontend *fe) | ||
387 | { | ||
388 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
389 | int ret, fecavailable; | ||
390 | u64 numerator, denominator; | ||
391 | |||
392 | deb_info("GET STATISTIC\n"); | ||
393 | ret = af9005_is_fecmon_available(fe, &fecavailable); | ||
394 | if (ret) | ||
395 | return ret; | ||
396 | if (!fecavailable) { | ||
397 | deb_info("fecmon not available\n"); | ||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | ret = af9005_get_pre_vit_err_bit_count(fe, &state->pre_vit_error_count, | ||
402 | &state->pre_vit_bit_count); | ||
403 | if (ret == 0) { | ||
404 | af9005_reset_pre_viterbi(fe); | ||
405 | if (state->pre_vit_bit_count > 0) { | ||
406 | /* according to v 0.0.4 of the dvb api ber should be a multiple | ||
407 | of 10E-9 so we have to multiply the error count by | ||
408 | 10E9=1000000000 */ | ||
409 | numerator = | ||
410 | (u64) state->pre_vit_error_count * (u64) 1000000000; | ||
411 | denominator = (u64) state->pre_vit_bit_count; | ||
412 | state->ber = do_div(numerator, denominator); | ||
413 | } else { | ||
414 | state->ber = 0xffffffff; | ||
415 | } | ||
416 | } | ||
417 | |||
418 | ret = af9005_get_post_vit_ber(fe, &state->post_vit_error_count, | ||
419 | &state->post_vit_bit_count, | ||
420 | &state->abort_count); | ||
421 | if (ret == 0) { | ||
422 | ret = af9005_reset_post_viterbi(fe); | ||
423 | state->unc += state->abort_count; | ||
424 | if (ret) | ||
425 | return ret; | ||
426 | } | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static int af9005_fe_refresh_state(struct dvb_frontend *fe) | ||
431 | { | ||
432 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
433 | if (time_after(jiffies, state->next_status_check)) { | ||
434 | deb_info("REFRESH STATE\n"); | ||
435 | |||
436 | /* statistics */ | ||
437 | if (af9005_get_statistic(fe)) | ||
438 | err("get_statistic_failed"); | ||
439 | state->next_status_check = jiffies + 250 * HZ / 1000; | ||
440 | } | ||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat) | ||
445 | { | ||
446 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
447 | u8 temp; | ||
448 | int ret; | ||
449 | |||
450 | if (state->tuner == NULL) | ||
451 | return -ENODEV; | ||
452 | |||
453 | *stat = 0; | ||
454 | ret = af9005_read_register_bits(state->d, xd_p_agc_lock, | ||
455 | agc_lock_pos, agc_lock_len, &temp); | ||
456 | if (ret) | ||
457 | return ret; | ||
458 | if (temp) | ||
459 | *stat |= FE_HAS_SIGNAL; | ||
460 | |||
461 | ret = af9005_read_register_bits(state->d, xd_p_fd_tpsd_lock, | ||
462 | fd_tpsd_lock_pos, fd_tpsd_lock_len, | ||
463 | &temp); | ||
464 | if (ret) | ||
465 | return ret; | ||
466 | if (temp) | ||
467 | *stat |= FE_HAS_CARRIER; | ||
468 | |||
469 | ret = af9005_read_register_bits(state->d, | ||
470 | xd_r_mp2if_sync_byte_locked, | ||
471 | mp2if_sync_byte_locked_pos, | ||
472 | mp2if_sync_byte_locked_pos, &temp); | ||
473 | if (ret) | ||
474 | return ret; | ||
475 | if (temp) | ||
476 | *stat |= FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK; | ||
477 | if (state->opened) | ||
478 | af9005_led_control(state->d, *stat & FE_HAS_LOCK); | ||
479 | |||
480 | ret = | ||
481 | af9005_read_register_bits(state->d, xd_p_reg_strong_sginal_detected, | ||
482 | reg_strong_sginal_detected_pos, | ||
483 | reg_strong_sginal_detected_len, &temp); | ||
484 | if (ret) | ||
485 | return ret; | ||
486 | if (temp != state->strong) { | ||
487 | deb_info("adjust for strong signal %d\n", temp); | ||
488 | state->strong = temp; | ||
489 | } | ||
490 | return 0; | ||
491 | } | ||
492 | |||
493 | static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber) | ||
494 | { | ||
495 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
496 | if (state->tuner == NULL) | ||
497 | return -ENODEV; | ||
498 | af9005_fe_refresh_state(fe); | ||
499 | *ber = state->ber; | ||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) | ||
504 | { | ||
505 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
506 | if (state->tuner == NULL) | ||
507 | return -ENODEV; | ||
508 | af9005_fe_refresh_state(fe); | ||
509 | *unc = state->unc; | ||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | static int af9005_fe_read_signal_strength(struct dvb_frontend *fe, | ||
514 | u16 * strength) | ||
515 | { | ||
516 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
517 | int ret; | ||
518 | u8 if_gain, rf_gain; | ||
519 | |||
520 | if (state->tuner == NULL) | ||
521 | return -ENODEV; | ||
522 | ret = | ||
523 | af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain, | ||
524 | &rf_gain); | ||
525 | if (ret) | ||
526 | return ret; | ||
527 | ret = | ||
528 | af9005_read_ofdm_register(state->d, xd_r_reg_aagc_if_gain, | ||
529 | &if_gain); | ||
530 | if (ret) | ||
531 | return ret; | ||
532 | /* this value has no real meaning, but i don't have the tables that relate | ||
533 | the rf and if gain with the dbm, so I just scale the value */ | ||
534 | *strength = (512 - rf_gain - if_gain) << 7; | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr) | ||
539 | { | ||
540 | /* the snr can be derived from the ber and the constellation | ||
541 | but I don't think this kind of complex calculations belong | ||
542 | in the driver. I may be wrong.... */ | ||
543 | return -ENOSYS; | ||
544 | } | ||
545 | |||
546 | static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) | ||
547 | { | ||
548 | u8 temp0, temp1, temp2, temp3, buf[4]; | ||
549 | int ret; | ||
550 | u32 NS_coeff1_2048Nu; | ||
551 | u32 NS_coeff1_8191Nu; | ||
552 | u32 NS_coeff1_8192Nu; | ||
553 | u32 NS_coeff1_8193Nu; | ||
554 | u32 NS_coeff2_2k; | ||
555 | u32 NS_coeff2_8k; | ||
556 | |||
557 | switch (bw) { | ||
558 | case BANDWIDTH_6_MHZ: | ||
559 | NS_coeff1_2048Nu = 0x2ADB6DC; | ||
560 | NS_coeff1_8191Nu = 0xAB7313; | ||
561 | NS_coeff1_8192Nu = 0xAB6DB7; | ||
562 | NS_coeff1_8193Nu = 0xAB685C; | ||
563 | NS_coeff2_2k = 0x156DB6E; | ||
564 | NS_coeff2_8k = 0x55B6DC; | ||
565 | break; | ||
566 | |||
567 | case BANDWIDTH_7_MHZ: | ||
568 | NS_coeff1_2048Nu = 0x3200001; | ||
569 | NS_coeff1_8191Nu = 0xC80640; | ||
570 | NS_coeff1_8192Nu = 0xC80000; | ||
571 | NS_coeff1_8193Nu = 0xC7F9C0; | ||
572 | NS_coeff2_2k = 0x1900000; | ||
573 | NS_coeff2_8k = 0x640000; | ||
574 | break; | ||
575 | |||
576 | case BANDWIDTH_8_MHZ: | ||
577 | NS_coeff1_2048Nu = 0x3924926; | ||
578 | NS_coeff1_8191Nu = 0xE4996E; | ||
579 | NS_coeff1_8192Nu = 0xE49249; | ||
580 | NS_coeff1_8193Nu = 0xE48B25; | ||
581 | NS_coeff2_2k = 0x1C92493; | ||
582 | NS_coeff2_8k = 0x724925; | ||
583 | break; | ||
584 | default: | ||
585 | err("Invalid bandwith %d.", bw); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | |||
589 | /* | ||
590 | * write NS_coeff1_2048Nu | ||
591 | */ | ||
592 | |||
593 | temp0 = (u8) (NS_coeff1_2048Nu & 0x000000FF); | ||
594 | temp1 = (u8) ((NS_coeff1_2048Nu & 0x0000FF00) >> 8); | ||
595 | temp2 = (u8) ((NS_coeff1_2048Nu & 0x00FF0000) >> 16); | ||
596 | temp3 = (u8) ((NS_coeff1_2048Nu & 0x03000000) >> 24); | ||
597 | |||
598 | /* big endian to make 8051 happy */ | ||
599 | buf[0] = temp3; | ||
600 | buf[1] = temp2; | ||
601 | buf[2] = temp1; | ||
602 | buf[3] = temp0; | ||
603 | |||
604 | /* cfoe_NS_2k_coeff1_25_24 */ | ||
605 | ret = af9005_write_ofdm_register(d, 0xAE00, buf[0]); | ||
606 | if (ret) | ||
607 | return ret; | ||
608 | |||
609 | /* cfoe_NS_2k_coeff1_23_16 */ | ||
610 | ret = af9005_write_ofdm_register(d, 0xAE01, buf[1]); | ||
611 | if (ret) | ||
612 | return ret; | ||
613 | |||
614 | /* cfoe_NS_2k_coeff1_15_8 */ | ||
615 | ret = af9005_write_ofdm_register(d, 0xAE02, buf[2]); | ||
616 | if (ret) | ||
617 | return ret; | ||
618 | |||
619 | /* cfoe_NS_2k_coeff1_7_0 */ | ||
620 | ret = af9005_write_ofdm_register(d, 0xAE03, buf[3]); | ||
621 | if (ret) | ||
622 | return ret; | ||
623 | |||
624 | /* | ||
625 | * write NS_coeff2_2k | ||
626 | */ | ||
627 | |||
628 | temp0 = (u8) ((NS_coeff2_2k & 0x0000003F)); | ||
629 | temp1 = (u8) ((NS_coeff2_2k & 0x00003FC0) >> 6); | ||
630 | temp2 = (u8) ((NS_coeff2_2k & 0x003FC000) >> 14); | ||
631 | temp3 = (u8) ((NS_coeff2_2k & 0x01C00000) >> 22); | ||
632 | |||
633 | /* big endian to make 8051 happy */ | ||
634 | buf[0] = temp3; | ||
635 | buf[1] = temp2; | ||
636 | buf[2] = temp1; | ||
637 | buf[3] = temp0; | ||
638 | |||
639 | ret = af9005_write_ofdm_register(d, 0xAE04, buf[0]); | ||
640 | if (ret) | ||
641 | return ret; | ||
642 | |||
643 | ret = af9005_write_ofdm_register(d, 0xAE05, buf[1]); | ||
644 | if (ret) | ||
645 | return ret; | ||
646 | |||
647 | ret = af9005_write_ofdm_register(d, 0xAE06, buf[2]); | ||
648 | if (ret) | ||
649 | return ret; | ||
650 | |||
651 | ret = af9005_write_ofdm_register(d, 0xAE07, buf[3]); | ||
652 | if (ret) | ||
653 | return ret; | ||
654 | |||
655 | /* | ||
656 | * write NS_coeff1_8191Nu | ||
657 | */ | ||
658 | |||
659 | temp0 = (u8) ((NS_coeff1_8191Nu & 0x000000FF)); | ||
660 | temp1 = (u8) ((NS_coeff1_8191Nu & 0x0000FF00) >> 8); | ||
661 | temp2 = (u8) ((NS_coeff1_8191Nu & 0x00FFC000) >> 16); | ||
662 | temp3 = (u8) ((NS_coeff1_8191Nu & 0x03000000) >> 24); | ||
663 | |||
664 | /* big endian to make 8051 happy */ | ||
665 | buf[0] = temp3; | ||
666 | buf[1] = temp2; | ||
667 | buf[2] = temp1; | ||
668 | buf[3] = temp0; | ||
669 | |||
670 | ret = af9005_write_ofdm_register(d, 0xAE08, buf[0]); | ||
671 | if (ret) | ||
672 | return ret; | ||
673 | |||
674 | ret = af9005_write_ofdm_register(d, 0xAE09, buf[1]); | ||
675 | if (ret) | ||
676 | return ret; | ||
677 | |||
678 | ret = af9005_write_ofdm_register(d, 0xAE0A, buf[2]); | ||
679 | if (ret) | ||
680 | return ret; | ||
681 | |||
682 | ret = af9005_write_ofdm_register(d, 0xAE0B, buf[3]); | ||
683 | if (ret) | ||
684 | return ret; | ||
685 | |||
686 | /* | ||
687 | * write NS_coeff1_8192Nu | ||
688 | */ | ||
689 | |||
690 | temp0 = (u8) (NS_coeff1_8192Nu & 0x000000FF); | ||
691 | temp1 = (u8) ((NS_coeff1_8192Nu & 0x0000FF00) >> 8); | ||
692 | temp2 = (u8) ((NS_coeff1_8192Nu & 0x00FFC000) >> 16); | ||
693 | temp3 = (u8) ((NS_coeff1_8192Nu & 0x03000000) >> 24); | ||
694 | |||
695 | /* big endian to make 8051 happy */ | ||
696 | buf[0] = temp3; | ||
697 | buf[1] = temp2; | ||
698 | buf[2] = temp1; | ||
699 | buf[3] = temp0; | ||
700 | |||
701 | ret = af9005_write_ofdm_register(d, 0xAE0C, buf[0]); | ||
702 | if (ret) | ||
703 | return ret; | ||
704 | |||
705 | ret = af9005_write_ofdm_register(d, 0xAE0D, buf[1]); | ||
706 | if (ret) | ||
707 | return ret; | ||
708 | |||
709 | ret = af9005_write_ofdm_register(d, 0xAE0E, buf[2]); | ||
710 | if (ret) | ||
711 | return ret; | ||
712 | |||
713 | ret = af9005_write_ofdm_register(d, 0xAE0F, buf[3]); | ||
714 | if (ret) | ||
715 | return ret; | ||
716 | |||
717 | /* | ||
718 | * write NS_coeff1_8193Nu | ||
719 | */ | ||
720 | |||
721 | temp0 = (u8) ((NS_coeff1_8193Nu & 0x000000FF)); | ||
722 | temp1 = (u8) ((NS_coeff1_8193Nu & 0x0000FF00) >> 8); | ||
723 | temp2 = (u8) ((NS_coeff1_8193Nu & 0x00FFC000) >> 16); | ||
724 | temp3 = (u8) ((NS_coeff1_8193Nu & 0x03000000) >> 24); | ||
725 | |||
726 | /* big endian to make 8051 happy */ | ||
727 | buf[0] = temp3; | ||
728 | buf[1] = temp2; | ||
729 | buf[2] = temp1; | ||
730 | buf[3] = temp0; | ||
731 | |||
732 | ret = af9005_write_ofdm_register(d, 0xAE10, buf[0]); | ||
733 | if (ret) | ||
734 | return ret; | ||
735 | |||
736 | ret = af9005_write_ofdm_register(d, 0xAE11, buf[1]); | ||
737 | if (ret) | ||
738 | return ret; | ||
739 | |||
740 | ret = af9005_write_ofdm_register(d, 0xAE12, buf[2]); | ||
741 | if (ret) | ||
742 | return ret; | ||
743 | |||
744 | ret = af9005_write_ofdm_register(d, 0xAE13, buf[3]); | ||
745 | if (ret) | ||
746 | return ret; | ||
747 | |||
748 | /* | ||
749 | * write NS_coeff2_8k | ||
750 | */ | ||
751 | |||
752 | temp0 = (u8) ((NS_coeff2_8k & 0x0000003F)); | ||
753 | temp1 = (u8) ((NS_coeff2_8k & 0x00003FC0) >> 6); | ||
754 | temp2 = (u8) ((NS_coeff2_8k & 0x003FC000) >> 14); | ||
755 | temp3 = (u8) ((NS_coeff2_8k & 0x01C00000) >> 22); | ||
756 | |||
757 | /* big endian to make 8051 happy */ | ||
758 | buf[0] = temp3; | ||
759 | buf[1] = temp2; | ||
760 | buf[2] = temp1; | ||
761 | buf[3] = temp0; | ||
762 | |||
763 | ret = af9005_write_ofdm_register(d, 0xAE14, buf[0]); | ||
764 | if (ret) | ||
765 | return ret; | ||
766 | |||
767 | ret = af9005_write_ofdm_register(d, 0xAE15, buf[1]); | ||
768 | if (ret) | ||
769 | return ret; | ||
770 | |||
771 | ret = af9005_write_ofdm_register(d, 0xAE16, buf[2]); | ||
772 | if (ret) | ||
773 | return ret; | ||
774 | |||
775 | ret = af9005_write_ofdm_register(d, 0xAE17, buf[3]); | ||
776 | return ret; | ||
777 | |||
778 | } | ||
779 | |||
780 | static int af9005_fe_select_bw(struct dvb_usb_device *d, fe_bandwidth_t bw) | ||
781 | { | ||
782 | u8 temp; | ||
783 | switch (bw) { | ||
784 | case BANDWIDTH_6_MHZ: | ||
785 | temp = 0; | ||
786 | break; | ||
787 | case BANDWIDTH_7_MHZ: | ||
788 | temp = 1; | ||
789 | break; | ||
790 | case BANDWIDTH_8_MHZ: | ||
791 | temp = 2; | ||
792 | break; | ||
793 | default: | ||
794 | err("Invalid bandwith %d.", bw); | ||
795 | return -EINVAL; | ||
796 | } | ||
797 | return af9005_write_register_bits(d, xd_g_reg_bw, reg_bw_pos, | ||
798 | reg_bw_len, temp); | ||
799 | } | ||
800 | |||
801 | static int af9005_fe_power(struct dvb_frontend *fe, int on) | ||
802 | { | ||
803 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
804 | u8 temp = on; | ||
805 | int ret; | ||
806 | deb_info("power %s tuner\n", on ? "on" : "off"); | ||
807 | ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0); | ||
808 | return ret; | ||
809 | } | ||
810 | |||
811 | static struct mt2060_config af9005_mt2060_config = { | ||
812 | 0xC0 | ||
813 | }; | ||
814 | |||
815 | static struct qt1010_config af9005_qt1010_config = { | ||
816 | 0xC4 | ||
817 | }; | ||
818 | |||
819 | static int af9005_fe_init(struct dvb_frontend *fe) | ||
820 | { | ||
821 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
822 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
823 | int ret, i, scriptlen; | ||
824 | u8 temp, temp0 = 0, temp1 = 0, temp2 = 0; | ||
825 | u8 buf[2]; | ||
826 | u16 if1; | ||
827 | |||
828 | deb_info("in af9005_fe_init\n"); | ||
829 | |||
830 | /* reset */ | ||
831 | deb_info("reset\n"); | ||
832 | if ((ret = | ||
833 | af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst_en, | ||
834 | 4, 1, 0x01))) | ||
835 | return ret; | ||
836 | if ((ret = af9005_write_ofdm_register(state->d, APO_REG_RESET, 0))) | ||
837 | return ret; | ||
838 | /* clear ofdm reset */ | ||
839 | deb_info("clear ofdm reset\n"); | ||
840 | for (i = 0; i < 150; i++) { | ||
841 | if ((ret = | ||
842 | af9005_read_ofdm_register(state->d, | ||
843 | xd_I2C_reg_ofdm_rst, &temp))) | ||
844 | return ret; | ||
845 | if (temp & (regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos)) | ||
846 | break; | ||
847 | msleep(10); | ||
848 | } | ||
849 | if (i == 150) | ||
850 | return -ETIMEDOUT; | ||
851 | |||
852 | /*FIXME in the dump | ||
853 | write B200 A9 | ||
854 | write xd_g_reg_ofsm_clk 7 | ||
855 | read eepr c6 (2) | ||
856 | read eepr c7 (2) | ||
857 | misc ctrl 3 -> 1 | ||
858 | read eepr ca (6) | ||
859 | write xd_g_reg_ofsm_clk 0 | ||
860 | write B200 a1 | ||
861 | */ | ||
862 | ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa9); | ||
863 | if (ret) | ||
864 | return ret; | ||
865 | ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x07); | ||
866 | if (ret) | ||
867 | return ret; | ||
868 | temp = 0x01; | ||
869 | ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0); | ||
870 | if (ret) | ||
871 | return ret; | ||
872 | ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x00); | ||
873 | if (ret) | ||
874 | return ret; | ||
875 | ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa1); | ||
876 | if (ret) | ||
877 | return ret; | ||
878 | |||
879 | temp = regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos; | ||
880 | if ((ret = | ||
881 | af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, | ||
882 | reg_ofdm_rst_pos, reg_ofdm_rst_len, 1))) | ||
883 | return ret; | ||
884 | if ((ret = | ||
885 | af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, | ||
886 | reg_ofdm_rst_pos, reg_ofdm_rst_len, 0))) | ||
887 | return ret; | ||
888 | |||
889 | if (ret) | ||
890 | return ret; | ||
891 | /* don't know what register aefc is, but this is what the windows driver does */ | ||
892 | ret = af9005_write_ofdm_register(state->d, 0xaefc, 0); | ||
893 | if (ret) | ||
894 | return ret; | ||
895 | |||
896 | /* set stand alone chip */ | ||
897 | deb_info("set stand alone chip\n"); | ||
898 | if ((ret = | ||
899 | af9005_write_register_bits(state->d, xd_p_reg_dca_stand_alone, | ||
900 | reg_dca_stand_alone_pos, | ||
901 | reg_dca_stand_alone_len, 1))) | ||
902 | return ret; | ||
903 | |||
904 | /* set dca upper & lower chip */ | ||
905 | deb_info("set dca upper & lower chip\n"); | ||
906 | if ((ret = | ||
907 | af9005_write_register_bits(state->d, xd_p_reg_dca_upper_chip, | ||
908 | reg_dca_upper_chip_pos, | ||
909 | reg_dca_upper_chip_len, 0))) | ||
910 | return ret; | ||
911 | if ((ret = | ||
912 | af9005_write_register_bits(state->d, xd_p_reg_dca_lower_chip, | ||
913 | reg_dca_lower_chip_pos, | ||
914 | reg_dca_lower_chip_len, 0))) | ||
915 | return ret; | ||
916 | |||
917 | /* set 2wire master clock to 0x14 (for 60KHz) */ | ||
918 | deb_info("set 2wire master clock to 0x14 (for 60KHz)\n"); | ||
919 | if ((ret = | ||
920 | af9005_write_ofdm_register(state->d, xd_I2C_i2c_m_period, 0x14))) | ||
921 | return ret; | ||
922 | |||
923 | /* clear dca enable chip */ | ||
924 | deb_info("clear dca enable chip\n"); | ||
925 | if ((ret = | ||
926 | af9005_write_register_bits(state->d, xd_p_reg_dca_en, | ||
927 | reg_dca_en_pos, reg_dca_en_len, 0))) | ||
928 | return ret; | ||
929 | /* FIXME these are register bits, but I don't know which ones */ | ||
930 | ret = af9005_write_ofdm_register(state->d, 0xa16c, 1); | ||
931 | if (ret) | ||
932 | return ret; | ||
933 | ret = af9005_write_ofdm_register(state->d, 0xa3c1, 0); | ||
934 | if (ret) | ||
935 | return ret; | ||
936 | |||
937 | /* init other parameters: program cfoe and select bandwith */ | ||
938 | deb_info("program cfoe\n"); | ||
939 | if ((ret = af9005_fe_program_cfoe(state->d, BANDWIDTH_6_MHZ))) | ||
940 | return ret; | ||
941 | /* set read-update bit for constellation */ | ||
942 | deb_info("set read-update bit for constellation\n"); | ||
943 | if ((ret = | ||
944 | af9005_write_register_bits(state->d, xd_p_reg_feq_read_update, | ||
945 | reg_feq_read_update_pos, | ||
946 | reg_feq_read_update_len, 1))) | ||
947 | return ret; | ||
948 | |||
949 | /* sample code has a set MPEG TS code here | ||
950 | but sniffing reveals that it doesn't do it */ | ||
951 | |||
952 | /* set read-update bit to 1 for DCA constellation */ | ||
953 | deb_info("set read-update bit 1 for DCA constellation\n"); | ||
954 | if ((ret = | ||
955 | af9005_write_register_bits(state->d, xd_p_reg_dca_read_update, | ||
956 | reg_dca_read_update_pos, | ||
957 | reg_dca_read_update_len, 1))) | ||
958 | return ret; | ||
959 | |||
960 | /* enable fec monitor */ | ||
961 | deb_info("enable fec monitor\n"); | ||
962 | if ((ret = | ||
963 | af9005_write_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en, | ||
964 | fec_vtb_rsd_mon_en_pos, | ||
965 | fec_vtb_rsd_mon_en_len, 1))) | ||
966 | return ret; | ||
967 | |||
968 | /* FIXME should be register bits, I don't know which ones */ | ||
969 | ret = af9005_write_ofdm_register(state->d, 0xa601, 0); | ||
970 | |||
971 | /* set api_retrain_never_freeze */ | ||
972 | deb_info("set api_retrain_never_freeze\n"); | ||
973 | if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01))) | ||
974 | return ret; | ||
975 | |||
976 | /* load init script */ | ||
977 | deb_info("load init script\n"); | ||
978 | scriptlen = sizeof(script) / sizeof(RegDesc); | ||
979 | for (i = 0; i < scriptlen; i++) { | ||
980 | if ((ret = | ||
981 | af9005_write_register_bits(state->d, script[i].reg, | ||
982 | script[i].pos, | ||
983 | script[i].len, script[i].val))) | ||
984 | return ret; | ||
985 | /* save 3 bytes of original fcw */ | ||
986 | if (script[i].reg == 0xae18) | ||
987 | temp2 = script[i].val; | ||
988 | if (script[i].reg == 0xae19) | ||
989 | temp1 = script[i].val; | ||
990 | if (script[i].reg == 0xae1a) | ||
991 | temp0 = script[i].val; | ||
992 | |||
993 | /* save original unplug threshold */ | ||
994 | if (script[i].reg == xd_p_reg_unplug_th) | ||
995 | state->original_if_unplug_th = script[i].val; | ||
996 | if (script[i].reg == xd_p_reg_unplug_rf_gain_th) | ||
997 | state->original_rf_unplug_th = script[i].val; | ||
998 | if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th) | ||
999 | state->original_dtop_if_unplug_th = script[i].val; | ||
1000 | if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th) | ||
1001 | state->original_dtop_rf_unplug_th = script[i].val; | ||
1002 | |||
1003 | } | ||
1004 | state->original_fcw = | ||
1005 | ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0; | ||
1006 | |||
1007 | |||
1008 | /* save original TOPs */ | ||
1009 | deb_info("save original TOPs\n"); | ||
1010 | |||
1011 | /* RF TOP */ | ||
1012 | ret = | ||
1013 | af9005_read_word_agc(state->d, | ||
1014 | xd_p_reg_aagc_rf_top_numerator_9_8, | ||
1015 | xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2, | ||
1016 | &state->original_rf_top); | ||
1017 | if (ret) | ||
1018 | return ret; | ||
1019 | |||
1020 | /* IF TOP */ | ||
1021 | ret = | ||
1022 | af9005_read_word_agc(state->d, | ||
1023 | xd_p_reg_aagc_if_top_numerator_9_8, | ||
1024 | xd_p_reg_aagc_if_top_numerator_7_0, 0, 2, | ||
1025 | &state->original_if_top); | ||
1026 | if (ret) | ||
1027 | return ret; | ||
1028 | |||
1029 | /* ACI 0 IF TOP */ | ||
1030 | ret = | ||
1031 | af9005_read_word_agc(state->d, 0xA60E, 0xA60A, 4, 2, | ||
1032 | &state->original_aci0_if_top); | ||
1033 | if (ret) | ||
1034 | return ret; | ||
1035 | |||
1036 | /* ACI 1 IF TOP */ | ||
1037 | ret = | ||
1038 | af9005_read_word_agc(state->d, 0xA60E, 0xA60B, 6, 2, | ||
1039 | &state->original_aci1_if_top); | ||
1040 | if (ret) | ||
1041 | return ret; | ||
1042 | |||
1043 | /* attach tuner and init */ | ||
1044 | if (state->tuner == NULL) { | ||
1045 | /* read tuner and board id from eeprom */ | ||
1046 | ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2); | ||
1047 | if (ret) { | ||
1048 | err("Impossible to read EEPROM\n"); | ||
1049 | return ret; | ||
1050 | } | ||
1051 | deb_info("Tuner id %d, board id %d\n", buf[0], buf[1]); | ||
1052 | switch (buf[0]) { | ||
1053 | case 2: /* MT2060 */ | ||
1054 | /* read if1 from eeprom */ | ||
1055 | ret = af9005_read_eeprom(adap->dev, 0xc8, buf, 2); | ||
1056 | if (ret) { | ||
1057 | err("Impossible to read EEPROM\n"); | ||
1058 | return ret; | ||
1059 | } | ||
1060 | if1 = (u16) (buf[0] << 8) + buf[1]; | ||
1061 | state->tuner = | ||
1062 | dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap, | ||
1063 | &af9005_mt2060_config, if1); | ||
1064 | if (state->tuner == NULL) { | ||
1065 | deb_info("MT2060 attach failed\n"); | ||
1066 | return -ENODEV; | ||
1067 | } | ||
1068 | break; | ||
1069 | case 3: /* QT1010 */ | ||
1070 | case 9: /* QT1010B */ | ||
1071 | state->tuner = | ||
1072 | dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap, | ||
1073 | &af9005_qt1010_config); | ||
1074 | if (state->tuner == NULL) { | ||
1075 | deb_info("QT1010 attach failed\n"); | ||
1076 | return -ENODEV; | ||
1077 | } | ||
1078 | break; | ||
1079 | default: | ||
1080 | err("Unsupported tuner type %d", buf[0]); | ||
1081 | return -ENODEV; | ||
1082 | } | ||
1083 | ret = state->tuner->ops.tuner_ops.init(state->tuner); | ||
1084 | if (ret) | ||
1085 | return ret; | ||
1086 | } | ||
1087 | |||
1088 | deb_info("profit!\n"); | ||
1089 | return 0; | ||
1090 | } | ||
1091 | |||
1092 | static int af9005_fe_sleep(struct dvb_frontend *fe) | ||
1093 | { | ||
1094 | return af9005_fe_power(fe, 0); | ||
1095 | } | ||
1096 | |||
1097 | static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) | ||
1098 | { | ||
1099 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
1100 | |||
1101 | if (acquire) { | ||
1102 | state->opened++; | ||
1103 | } else { | ||
1104 | |||
1105 | state->opened--; | ||
1106 | if (!state->opened) | ||
1107 | af9005_led_control(state->d, 0); | ||
1108 | } | ||
1109 | return 0; | ||
1110 | } | ||
1111 | |||
1112 | static int af9005_fe_set_frontend(struct dvb_frontend *fe, | ||
1113 | struct dvb_frontend_parameters *fep) | ||
1114 | { | ||
1115 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
1116 | int ret; | ||
1117 | u8 temp, temp0, temp1, temp2; | ||
1118 | |||
1119 | deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency, | ||
1120 | fep->u.ofdm.bandwidth); | ||
1121 | if (state->tuner == NULL) { | ||
1122 | err("Tuner not attached"); | ||
1123 | return -ENODEV; | ||
1124 | } | ||
1125 | |||
1126 | deb_info("turn off led\n"); | ||
1127 | /* not in the log */ | ||
1128 | ret = af9005_led_control(state->d, 0); | ||
1129 | if (ret) | ||
1130 | return ret; | ||
1131 | /* not sure about the bits */ | ||
1132 | ret = af9005_write_register_bits(state->d, XD_MP2IF_MISC, 2, 1, 0); | ||
1133 | if (ret) | ||
1134 | return ret; | ||
1135 | |||
1136 | /* set FCW to default value */ | ||
1137 | deb_info("set FCW to default value\n"); | ||
1138 | temp0 = (u8) (state->original_fcw & 0x000000ff); | ||
1139 | temp1 = (u8) ((state->original_fcw & 0x0000ff00) >> 8); | ||
1140 | temp2 = (u8) ((state->original_fcw & 0x00ff0000) >> 16); | ||
1141 | ret = af9005_write_ofdm_register(state->d, 0xae1a, temp0); | ||
1142 | if (ret) | ||
1143 | return ret; | ||
1144 | ret = af9005_write_ofdm_register(state->d, 0xae19, temp1); | ||
1145 | if (ret) | ||
1146 | return ret; | ||
1147 | ret = af9005_write_ofdm_register(state->d, 0xae18, temp2); | ||
1148 | if (ret) | ||
1149 | return ret; | ||
1150 | |||
1151 | /* restore original TOPs */ | ||
1152 | deb_info("restore original TOPs\n"); | ||
1153 | ret = | ||
1154 | af9005_write_word_agc(state->d, | ||
1155 | xd_p_reg_aagc_rf_top_numerator_9_8, | ||
1156 | xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2, | ||
1157 | state->original_rf_top); | ||
1158 | if (ret) | ||
1159 | return ret; | ||
1160 | ret = | ||
1161 | af9005_write_word_agc(state->d, | ||
1162 | xd_p_reg_aagc_if_top_numerator_9_8, | ||
1163 | xd_p_reg_aagc_if_top_numerator_7_0, 0, 2, | ||
1164 | state->original_if_top); | ||
1165 | if (ret) | ||
1166 | return ret; | ||
1167 | ret = | ||
1168 | af9005_write_word_agc(state->d, 0xA60E, 0xA60A, 4, 2, | ||
1169 | state->original_aci0_if_top); | ||
1170 | if (ret) | ||
1171 | return ret; | ||
1172 | ret = | ||
1173 | af9005_write_word_agc(state->d, 0xA60E, 0xA60B, 6, 2, | ||
1174 | state->original_aci1_if_top); | ||
1175 | if (ret) | ||
1176 | return ret; | ||
1177 | |||
1178 | /* select bandwith */ | ||
1179 | deb_info("select bandwidth"); | ||
1180 | ret = af9005_fe_select_bw(state->d, fep->u.ofdm.bandwidth); | ||
1181 | if (ret) | ||
1182 | return ret; | ||
1183 | ret = af9005_fe_program_cfoe(state->d, fep->u.ofdm.bandwidth); | ||
1184 | if (ret) | ||
1185 | return ret; | ||
1186 | |||
1187 | /* clear easy mode flag */ | ||
1188 | deb_info("clear easy mode flag\n"); | ||
1189 | ret = af9005_write_ofdm_register(state->d, 0xaefd, 0); | ||
1190 | if (ret) | ||
1191 | return ret; | ||
1192 | |||
1193 | /* set unplug threshold to original value */ | ||
1194 | deb_info("set unplug threshold to original value\n"); | ||
1195 | ret = | ||
1196 | af9005_write_ofdm_register(state->d, xd_p_reg_unplug_th, | ||
1197 | state->original_if_unplug_th); | ||
1198 | if (ret) | ||
1199 | return ret; | ||
1200 | /* set tuner */ | ||
1201 | deb_info("set tuner\n"); | ||
1202 | ret = state->tuner->ops.tuner_ops.set_params(state->tuner, fep); | ||
1203 | if (ret) | ||
1204 | return ret; | ||
1205 | |||
1206 | /* trigger ofsm */ | ||
1207 | deb_info("trigger ofsm\n"); | ||
1208 | temp = 0; | ||
1209 | ret = af9005_write_tuner_registers(state->d, 0xffff, &temp, 1); | ||
1210 | if (ret) | ||
1211 | return ret; | ||
1212 | |||
1213 | /* clear retrain and freeze flag */ | ||
1214 | deb_info("clear retrain and freeze flag\n"); | ||
1215 | ret = | ||
1216 | af9005_write_register_bits(state->d, | ||
1217 | xd_p_reg_api_retrain_request, | ||
1218 | reg_api_retrain_request_pos, 2, 0); | ||
1219 | if (ret) | ||
1220 | return ret; | ||
1221 | |||
1222 | /* reset pre viterbi and post viterbi registers and statistics */ | ||
1223 | af9005_reset_pre_viterbi(fe); | ||
1224 | af9005_reset_post_viterbi(fe); | ||
1225 | state->pre_vit_error_count = 0; | ||
1226 | state->pre_vit_bit_count = 0; | ||
1227 | state->ber = 0; | ||
1228 | state->post_vit_error_count = 0; | ||
1229 | /* state->unc = 0; commented out since it should be ever increasing */ | ||
1230 | state->abort_count = 0; | ||
1231 | |||
1232 | state->next_status_check = jiffies; | ||
1233 | state->strong = -1; | ||
1234 | |||
1235 | return 0; | ||
1236 | } | ||
1237 | |||
1238 | static int af9005_fe_get_frontend(struct dvb_frontend *fe, | ||
1239 | struct dvb_frontend_parameters *fep) | ||
1240 | { | ||
1241 | struct af9005_fe_state *state = fe->demodulator_priv; | ||
1242 | int ret; | ||
1243 | u8 temp; | ||
1244 | |||
1245 | /* mode */ | ||
1246 | ret = | ||
1247 | af9005_read_register_bits(state->d, xd_g_reg_tpsd_const, | ||
1248 | reg_tpsd_const_pos, reg_tpsd_const_len, | ||
1249 | &temp); | ||
1250 | if (ret) | ||
1251 | return ret; | ||
1252 | deb_info("===== fe_get_frontend ==============\n"); | ||
1253 | deb_info("CONSTELLATION "); | ||
1254 | switch (temp) { | ||
1255 | case 0: | ||
1256 | fep->u.ofdm.constellation = QPSK; | ||
1257 | deb_info("QPSK\n"); | ||
1258 | break; | ||
1259 | case 1: | ||
1260 | fep->u.ofdm.constellation = QAM_16; | ||
1261 | deb_info("QAM_16\n"); | ||
1262 | break; | ||
1263 | case 2: | ||
1264 | fep->u.ofdm.constellation = QAM_64; | ||
1265 | deb_info("QAM_64\n"); | ||
1266 | break; | ||
1267 | } | ||
1268 | |||
1269 | /* tps hierarchy and alpha value */ | ||
1270 | ret = | ||
1271 | af9005_read_register_bits(state->d, xd_g_reg_tpsd_hier, | ||
1272 | reg_tpsd_hier_pos, reg_tpsd_hier_len, | ||
1273 | &temp); | ||
1274 | if (ret) | ||
1275 | return ret; | ||
1276 | deb_info("HIERARCHY "); | ||
1277 | switch (temp) { | ||
1278 | case 0: | ||
1279 | fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; | ||
1280 | deb_info("NONE\n"); | ||
1281 | break; | ||
1282 | case 1: | ||
1283 | fep->u.ofdm.hierarchy_information = HIERARCHY_1; | ||
1284 | deb_info("1\n"); | ||
1285 | break; | ||
1286 | case 2: | ||
1287 | fep->u.ofdm.hierarchy_information = HIERARCHY_2; | ||
1288 | deb_info("2\n"); | ||
1289 | break; | ||
1290 | case 3: | ||
1291 | fep->u.ofdm.hierarchy_information = HIERARCHY_4; | ||
1292 | deb_info("4\n"); | ||
1293 | break; | ||
1294 | } | ||
1295 | |||
1296 | /* high/low priority */ | ||
1297 | ret = | ||
1298 | af9005_read_register_bits(state->d, xd_g_reg_dec_pri, | ||
1299 | reg_dec_pri_pos, reg_dec_pri_len, &temp); | ||
1300 | if (ret) | ||
1301 | return ret; | ||
1302 | /* if temp is set = high priority */ | ||
1303 | deb_info("PRIORITY %s\n", temp ? "high" : "low"); | ||
1304 | |||
1305 | /* high coderate */ | ||
1306 | ret = | ||
1307 | af9005_read_register_bits(state->d, xd_g_reg_tpsd_hpcr, | ||
1308 | reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len, | ||
1309 | &temp); | ||
1310 | if (ret) | ||
1311 | return ret; | ||
1312 | deb_info("CODERATE HP "); | ||
1313 | switch (temp) { | ||
1314 | case 0: | ||
1315 | fep->u.ofdm.code_rate_HP = FEC_1_2; | ||
1316 | deb_info("FEC_1_2\n"); | ||
1317 | break; | ||
1318 | case 1: | ||
1319 | fep->u.ofdm.code_rate_HP = FEC_2_3; | ||
1320 | deb_info("FEC_2_3\n"); | ||
1321 | break; | ||
1322 | case 2: | ||
1323 | fep->u.ofdm.code_rate_HP = FEC_3_4; | ||
1324 | deb_info("FEC_3_4\n"); | ||
1325 | break; | ||
1326 | case 3: | ||
1327 | fep->u.ofdm.code_rate_HP = FEC_5_6; | ||
1328 | deb_info("FEC_5_6\n"); | ||
1329 | break; | ||
1330 | case 4: | ||
1331 | fep->u.ofdm.code_rate_HP = FEC_7_8; | ||
1332 | deb_info("FEC_7_8\n"); | ||
1333 | break; | ||
1334 | } | ||
1335 | |||
1336 | /* low coderate */ | ||
1337 | ret = | ||
1338 | af9005_read_register_bits(state->d, xd_g_reg_tpsd_lpcr, | ||
1339 | reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len, | ||
1340 | &temp); | ||
1341 | if (ret) | ||
1342 | return ret; | ||
1343 | deb_info("CODERATE LP "); | ||
1344 | switch (temp) { | ||
1345 | case 0: | ||
1346 | fep->u.ofdm.code_rate_LP = FEC_1_2; | ||
1347 | deb_info("FEC_1_2\n"); | ||
1348 | break; | ||
1349 | case 1: | ||
1350 | fep->u.ofdm.code_rate_LP = FEC_2_3; | ||
1351 | deb_info("FEC_2_3\n"); | ||
1352 | break; | ||
1353 | case 2: | ||
1354 | fep->u.ofdm.code_rate_LP = FEC_3_4; | ||
1355 | deb_info("FEC_3_4\n"); | ||
1356 | break; | ||
1357 | case 3: | ||
1358 | fep->u.ofdm.code_rate_LP = FEC_5_6; | ||
1359 | deb_info("FEC_5_6\n"); | ||
1360 | break; | ||
1361 | case 4: | ||
1362 | fep->u.ofdm.code_rate_LP = FEC_7_8; | ||
1363 | deb_info("FEC_7_8\n"); | ||
1364 | break; | ||
1365 | } | ||
1366 | |||
1367 | /* guard interval */ | ||
1368 | ret = | ||
1369 | af9005_read_register_bits(state->d, xd_g_reg_tpsd_gi, | ||
1370 | reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp); | ||
1371 | if (ret) | ||
1372 | return ret; | ||
1373 | deb_info("GUARD INTERVAL "); | ||
1374 | switch (temp) { | ||
1375 | case 0: | ||
1376 | fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; | ||
1377 | deb_info("1_32\n"); | ||
1378 | break; | ||
1379 | case 1: | ||
1380 | fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; | ||
1381 | deb_info("1_16\n"); | ||
1382 | break; | ||
1383 | case 2: | ||
1384 | fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; | ||
1385 | deb_info("1_8\n"); | ||
1386 | break; | ||
1387 | case 3: | ||
1388 | fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; | ||
1389 | deb_info("1_4\n"); | ||
1390 | break; | ||
1391 | } | ||
1392 | |||
1393 | /* fft */ | ||
1394 | ret = | ||
1395 | af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod, | ||
1396 | reg_tpsd_txmod_pos, reg_tpsd_txmod_len, | ||
1397 | &temp); | ||
1398 | if (ret) | ||
1399 | return ret; | ||
1400 | deb_info("TRANSMISSION MODE "); | ||
1401 | switch (temp) { | ||
1402 | case 0: | ||
1403 | fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; | ||
1404 | deb_info("2K\n"); | ||
1405 | break; | ||
1406 | case 1: | ||
1407 | fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; | ||
1408 | deb_info("8K\n"); | ||
1409 | break; | ||
1410 | } | ||
1411 | |||
1412 | /* bandwidth */ | ||
1413 | ret = | ||
1414 | af9005_read_register_bits(state->d, xd_g_reg_bw, reg_bw_pos, | ||
1415 | reg_bw_len, &temp); | ||
1416 | deb_info("BANDWIDTH "); | ||
1417 | switch (temp) { | ||
1418 | case 0: | ||
1419 | fep->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; | ||
1420 | deb_info("6\n"); | ||
1421 | break; | ||
1422 | case 1: | ||
1423 | fep->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; | ||
1424 | deb_info("7\n"); | ||
1425 | break; | ||
1426 | case 2: | ||
1427 | fep->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; | ||
1428 | deb_info("8\n"); | ||
1429 | break; | ||
1430 | } | ||
1431 | return 0; | ||
1432 | } | ||
1433 | |||
1434 | static void af9005_fe_release(struct dvb_frontend *fe) | ||
1435 | { | ||
1436 | struct af9005_fe_state *state = | ||
1437 | (struct af9005_fe_state *)fe->demodulator_priv; | ||
1438 | if (state->tuner != NULL && state->tuner->ops.tuner_ops.release != NULL) { | ||
1439 | state->tuner->ops.tuner_ops.release(state->tuner); | ||
1440 | #ifdef CONFIG_DVB_CORE_ATTACH | ||
1441 | symbol_put_addr(state->tuner->ops.tuner_ops.release); | ||
1442 | #endif | ||
1443 | } | ||
1444 | kfree(state); | ||
1445 | } | ||
1446 | |||
1447 | static struct dvb_frontend_ops af9005_fe_ops; | ||
1448 | |||
1449 | struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) | ||
1450 | { | ||
1451 | struct af9005_fe_state *state = NULL; | ||
1452 | |||
1453 | /* allocate memory for the internal state */ | ||
1454 | state = kzalloc(sizeof(struct af9005_fe_state), GFP_KERNEL); | ||
1455 | if (state == NULL) | ||
1456 | goto error; | ||
1457 | |||
1458 | deb_info("attaching frontend af9005\n"); | ||
1459 | |||
1460 | state->d = d; | ||
1461 | state->tuner = NULL; | ||
1462 | state->opened = 0; | ||
1463 | |||
1464 | memcpy(&state->frontend.ops, &af9005_fe_ops, | ||
1465 | sizeof(struct dvb_frontend_ops)); | ||
1466 | state->frontend.demodulator_priv = state; | ||
1467 | |||
1468 | return &state->frontend; | ||
1469 | error: | ||
1470 | return NULL; | ||
1471 | } | ||
1472 | |||
1473 | static struct dvb_frontend_ops af9005_fe_ops = { | ||
1474 | .info = { | ||
1475 | .name = "AF9005 USB DVB-T", | ||
1476 | .type = FE_OFDM, | ||
1477 | .frequency_min = 44250000, | ||
1478 | .frequency_max = 867250000, | ||
1479 | .frequency_stepsize = 250000, | ||
1480 | .caps = FE_CAN_INVERSION_AUTO | | ||
1481 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
1482 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
1483 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | | ||
1484 | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | | ||
1485 | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | | ||
1486 | FE_CAN_HIERARCHY_AUTO, | ||
1487 | }, | ||
1488 | |||
1489 | .release = af9005_fe_release, | ||
1490 | |||
1491 | .init = af9005_fe_init, | ||
1492 | .sleep = af9005_fe_sleep, | ||
1493 | .ts_bus_ctrl = af9005_ts_bus_ctrl, | ||
1494 | |||
1495 | .set_frontend = af9005_fe_set_frontend, | ||
1496 | .get_frontend = af9005_fe_get_frontend, | ||
1497 | |||
1498 | .read_status = af9005_fe_read_status, | ||
1499 | .read_ber = af9005_fe_read_ber, | ||
1500 | .read_signal_strength = af9005_fe_read_signal_strength, | ||
1501 | .read_snr = af9005_fe_read_snr, | ||
1502 | .read_ucblocks = af9005_fe_read_unc_blocks, | ||
1503 | }; | ||
diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c new file mode 100644 index 000000000000..ff00c0e8f4a1 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/af9005-remote.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* DVB USB compliant Linux driver for the Afatech 9005 | ||
2 | * USB1.1 DVB-T receiver. | ||
3 | * | ||
4 | * Standard remote decode function | ||
5 | * | ||
6 | * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) | ||
7 | * | ||
8 | * Thanks to Afatech who kindly provided information. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * see Documentation/dvb/REDME.dvb-usb for more information | ||
25 | */ | ||
26 | #include "af9005.h" | ||
27 | /* debug */ | ||
28 | int dvb_usb_af9005_remote_debug; | ||
29 | module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644); | ||
30 | MODULE_PARM_DESC(debug, | ||
31 | "enable (1) or disable (0) debug messages." | ||
32 | DVB_USB_DEBUG_STATUS); | ||
33 | |||
34 | #define deb_decode(args...) dprintk(dvb_usb_af9005_remote_debug,0x01,args) | ||
35 | |||
36 | struct dvb_usb_rc_key af9005_rc_keys[] = { | ||
37 | |||
38 | {0x01, 0xb7, KEY_POWER}, | ||
39 | {0x01, 0xa7, KEY_VOLUMEUP}, | ||
40 | {0x01, 0x87, KEY_CHANNELUP}, | ||
41 | {0x01, 0x7f, KEY_MUTE}, | ||
42 | {0x01, 0xbf, KEY_VOLUMEDOWN}, | ||
43 | {0x01, 0x3f, KEY_CHANNELDOWN}, | ||
44 | {0x01, 0xdf, KEY_1}, | ||
45 | {0x01, 0x5f, KEY_2}, | ||
46 | {0x01, 0x9f, KEY_3}, | ||
47 | {0x01, 0x1f, KEY_4}, | ||
48 | {0x01, 0xef, KEY_5}, | ||
49 | {0x01, 0x6f, KEY_6}, | ||
50 | {0x01, 0xaf, KEY_7}, | ||
51 | {0x01, 0x27, KEY_8}, | ||
52 | {0x01, 0x07, KEY_9}, | ||
53 | {0x01, 0xcf, KEY_ZOOM}, | ||
54 | {0x01, 0x4f, KEY_0}, | ||
55 | {0x01, 0x8f, KEY_GOTO}, /* marked jump on the remote */ | ||
56 | |||
57 | {0x00, 0xbd, KEY_POWER}, | ||
58 | {0x00, 0x7d, KEY_VOLUMEUP}, | ||
59 | {0x00, 0xfd, KEY_CHANNELUP}, | ||
60 | {0x00, 0x9d, KEY_MUTE}, | ||
61 | {0x00, 0x5d, KEY_VOLUMEDOWN}, | ||
62 | {0x00, 0xdd, KEY_CHANNELDOWN}, | ||
63 | {0x00, 0xad, KEY_1}, | ||
64 | {0x00, 0x6d, KEY_2}, | ||
65 | {0x00, 0xed, KEY_3}, | ||
66 | {0x00, 0x8d, KEY_4}, | ||
67 | {0x00, 0x4d, KEY_5}, | ||
68 | {0x00, 0xcd, KEY_6}, | ||
69 | {0x00, 0xb5, KEY_7}, | ||
70 | {0x00, 0x75, KEY_8}, | ||
71 | {0x00, 0xf5, KEY_9}, | ||
72 | {0x00, 0x95, KEY_ZOOM}, | ||
73 | {0x00, 0x55, KEY_0}, | ||
74 | {0x00, 0xd5, KEY_GOTO}, /* marked jump on the remote */ | ||
75 | }; | ||
76 | |||
77 | int af9005_rc_keys_size = ARRAY_SIZE(af9005_rc_keys); | ||
78 | |||
79 | static int repeatable_keys[] = { | ||
80 | KEY_VOLUMEUP, | ||
81 | KEY_VOLUMEDOWN, | ||
82 | KEY_CHANNELUP, | ||
83 | KEY_CHANNELDOWN | ||
84 | }; | ||
85 | |||
86 | int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event, | ||
87 | int *state) | ||
88 | { | ||
89 | u16 mark, space; | ||
90 | u32 result; | ||
91 | u8 cust, dat, invdat; | ||
92 | int i; | ||
93 | |||
94 | if (len >= 6) { | ||
95 | mark = (u16) (data[0] << 8) + data[1]; | ||
96 | space = (u16) (data[2] << 8) + data[3]; | ||
97 | if (space * 3 < mark) { | ||
98 | for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) { | ||
99 | if (d->last_event == repeatable_keys[i]) { | ||
100 | *state = REMOTE_KEY_REPEAT; | ||
101 | *event = d->last_event; | ||
102 | deb_decode("repeat key, event %x\n", | ||
103 | *event); | ||
104 | return 0; | ||
105 | } | ||
106 | } | ||
107 | deb_decode("repeated key ignored (non repeatable)\n"); | ||
108 | return 0; | ||
109 | } else if (len >= 33 * 4) { /*32 bits + start code */ | ||
110 | result = 0; | ||
111 | for (i = 4; i < 4 + 32 * 4; i += 4) { | ||
112 | result <<= 1; | ||
113 | mark = (u16) (data[i] << 8) + data[i + 1]; | ||
114 | mark >>= 1; | ||
115 | space = (u16) (data[i + 2] << 8) + data[i + 3]; | ||
116 | space >>= 1; | ||
117 | if (mark * 2 > space) | ||
118 | result += 1; | ||
119 | } | ||
120 | deb_decode("key pressed, raw value %x\n", result); | ||
121 | if ((result & 0xff000000) != 0xfe000000) { | ||
122 | deb_decode | ||
123 | ("doesn't start with 0xfe, ignored\n"); | ||
124 | return 0; | ||
125 | } | ||
126 | cust = (result >> 16) & 0xff; | ||
127 | dat = (result >> 8) & 0xff; | ||
128 | invdat = (~result) & 0xff; | ||
129 | if (dat != invdat) { | ||
130 | deb_decode("code != inverted code\n"); | ||
131 | return 0; | ||
132 | } | ||
133 | for (i = 0; i < af9005_rc_keys_size; i++) { | ||
134 | if (af9005_rc_keys[i].custom == cust | ||
135 | && af9005_rc_keys[i].data == dat) { | ||
136 | *event = af9005_rc_keys[i].event; | ||
137 | *state = REMOTE_KEY_PRESSED; | ||
138 | deb_decode | ||
139 | ("key pressed, event %x\n", *event); | ||
140 | return 0; | ||
141 | } | ||
142 | } | ||
143 | deb_decode("not found in table\n"); | ||
144 | } | ||
145 | } | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | EXPORT_SYMBOL(af9005_rc_keys); | ||
150 | EXPORT_SYMBOL(af9005_rc_keys_size); | ||
151 | EXPORT_SYMBOL(af9005_rc_decode); | ||
152 | |||
153 | MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>"); | ||
154 | MODULE_DESCRIPTION | ||
155 | ("Standard remote control decoder for Afatech 9005 DVB-T USB1.1 stick"); | ||
156 | MODULE_VERSION("1.0"); | ||
157 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/dvb-usb/af9005-script.h b/drivers/media/dvb/dvb-usb/af9005-script.h new file mode 100644 index 000000000000..6eeaae51b1ca --- /dev/null +++ b/drivers/media/dvb/dvb-usb/af9005-script.h | |||
@@ -0,0 +1,203 @@ | |||
1 | /* | ||
2 | File automatically generated by createinit.py using data | ||
3 | extracted from AF05BDA.sys (windows driver): | ||
4 | |||
5 | dd if=AF05BDA.sys of=initsequence bs=1 skip=88316 count=1110 | ||
6 | python createinit.py > af9005-script.h | ||
7 | |||
8 | */ | ||
9 | |||
10 | typedef struct { | ||
11 | u16 reg; | ||
12 | u8 pos; | ||
13 | u8 len; | ||
14 | u8 val; | ||
15 | } RegDesc; | ||
16 | |||
17 | RegDesc script[] = { | ||
18 | {0xa180, 0x0, 0x8, 0xa}, | ||
19 | {0xa181, 0x0, 0x8, 0xd7}, | ||
20 | {0xa182, 0x0, 0x8, 0xa3}, | ||
21 | {0xa0a0, 0x0, 0x8, 0x0}, | ||
22 | {0xa0a1, 0x0, 0x5, 0x0}, | ||
23 | {0xa0a1, 0x5, 0x1, 0x1}, | ||
24 | {0xa0c0, 0x0, 0x4, 0x1}, | ||
25 | {0xa20e, 0x4, 0x4, 0xa}, | ||
26 | {0xa20f, 0x0, 0x8, 0x40}, | ||
27 | {0xa210, 0x0, 0x8, 0x8}, | ||
28 | {0xa32a, 0x0, 0x4, 0xa}, | ||
29 | {0xa32c, 0x0, 0x8, 0x20}, | ||
30 | {0xa32b, 0x0, 0x8, 0x15}, | ||
31 | {0xa1a0, 0x1, 0x1, 0x1}, | ||
32 | {0xa000, 0x0, 0x1, 0x1}, | ||
33 | {0xa000, 0x1, 0x1, 0x0}, | ||
34 | {0xa001, 0x1, 0x1, 0x1}, | ||
35 | {0xa001, 0x0, 0x1, 0x0}, | ||
36 | {0xa001, 0x5, 0x1, 0x0}, | ||
37 | {0xa00e, 0x0, 0x5, 0x10}, | ||
38 | {0xa00f, 0x0, 0x3, 0x4}, | ||
39 | {0xa00f, 0x3, 0x3, 0x5}, | ||
40 | {0xa010, 0x0, 0x3, 0x4}, | ||
41 | {0xa010, 0x3, 0x3, 0x5}, | ||
42 | {0xa016, 0x4, 0x4, 0x3}, | ||
43 | {0xa01f, 0x0, 0x6, 0xa}, | ||
44 | {0xa020, 0x0, 0x6, 0xa}, | ||
45 | {0xa2bc, 0x0, 0x1, 0x1}, | ||
46 | {0xa2bc, 0x5, 0x1, 0x1}, | ||
47 | {0xa015, 0x0, 0x8, 0x50}, | ||
48 | {0xa016, 0x0, 0x1, 0x0}, | ||
49 | {0xa02a, 0x0, 0x8, 0x50}, | ||
50 | {0xa029, 0x0, 0x8, 0x4b}, | ||
51 | {0xa614, 0x0, 0x8, 0x46}, | ||
52 | {0xa002, 0x0, 0x5, 0x19}, | ||
53 | {0xa003, 0x0, 0x5, 0x1a}, | ||
54 | {0xa004, 0x0, 0x5, 0x19}, | ||
55 | {0xa005, 0x0, 0x5, 0x1a}, | ||
56 | {0xa008, 0x0, 0x8, 0x69}, | ||
57 | {0xa009, 0x0, 0x2, 0x2}, | ||
58 | {0xae1b, 0x0, 0x8, 0x69}, | ||
59 | {0xae1c, 0x0, 0x8, 0x2}, | ||
60 | {0xae1d, 0x0, 0x8, 0x2a}, | ||
61 | {0xa022, 0x0, 0x8, 0xaa}, | ||
62 | {0xa006, 0x0, 0x8, 0xc8}, | ||
63 | {0xa007, 0x0, 0x2, 0x0}, | ||
64 | {0xa00c, 0x0, 0x8, 0xba}, | ||
65 | {0xa00d, 0x0, 0x2, 0x2}, | ||
66 | {0xa608, 0x0, 0x8, 0xba}, | ||
67 | {0xa60e, 0x0, 0x2, 0x2}, | ||
68 | {0xa609, 0x0, 0x8, 0x80}, | ||
69 | {0xa60e, 0x2, 0x2, 0x3}, | ||
70 | {0xa00a, 0x0, 0x8, 0xb6}, | ||
71 | {0xa00b, 0x0, 0x2, 0x0}, | ||
72 | {0xa011, 0x0, 0x8, 0xb9}, | ||
73 | {0xa012, 0x0, 0x2, 0x0}, | ||
74 | {0xa013, 0x0, 0x8, 0xbd}, | ||
75 | {0xa014, 0x0, 0x2, 0x2}, | ||
76 | {0xa366, 0x0, 0x1, 0x1}, | ||
77 | {0xa2bc, 0x3, 0x1, 0x0}, | ||
78 | {0xa2bd, 0x0, 0x8, 0xa}, | ||
79 | {0xa2be, 0x0, 0x8, 0x14}, | ||
80 | {0xa2bf, 0x0, 0x8, 0x8}, | ||
81 | {0xa60a, 0x0, 0x8, 0xbd}, | ||
82 | {0xa60e, 0x4, 0x2, 0x2}, | ||
83 | {0xa60b, 0x0, 0x8, 0x86}, | ||
84 | {0xa60e, 0x6, 0x2, 0x3}, | ||
85 | {0xa001, 0x2, 0x2, 0x1}, | ||
86 | {0xa1c7, 0x0, 0x8, 0xf5}, | ||
87 | {0xa03d, 0x0, 0x8, 0xb1}, | ||
88 | {0xa616, 0x0, 0x8, 0xff}, | ||
89 | {0xa617, 0x0, 0x8, 0xad}, | ||
90 | {0xa618, 0x0, 0x8, 0xad}, | ||
91 | {0xa61e, 0x3, 0x1, 0x1}, | ||
92 | {0xae1a, 0x0, 0x8, 0x0}, | ||
93 | {0xae19, 0x0, 0x8, 0xc8}, | ||
94 | {0xae18, 0x0, 0x8, 0x61}, | ||
95 | {0xa140, 0x0, 0x8, 0x0}, | ||
96 | {0xa141, 0x0, 0x8, 0xc8}, | ||
97 | {0xa142, 0x0, 0x7, 0x61}, | ||
98 | {0xa023, 0x0, 0x8, 0xff}, | ||
99 | {0xa021, 0x0, 0x8, 0xad}, | ||
100 | {0xa026, 0x0, 0x1, 0x0}, | ||
101 | {0xa024, 0x0, 0x8, 0xff}, | ||
102 | {0xa025, 0x0, 0x8, 0xff}, | ||
103 | {0xa1c8, 0x0, 0x8, 0xf}, | ||
104 | {0xa2bc, 0x1, 0x1, 0x0}, | ||
105 | {0xa60c, 0x0, 0x4, 0x5}, | ||
106 | {0xa60c, 0x4, 0x4, 0x6}, | ||
107 | {0xa60d, 0x0, 0x8, 0xa}, | ||
108 | {0xa371, 0x0, 0x1, 0x1}, | ||
109 | {0xa366, 0x1, 0x3, 0x7}, | ||
110 | {0xa338, 0x0, 0x8, 0x10}, | ||
111 | {0xa339, 0x0, 0x6, 0x7}, | ||
112 | {0xa33a, 0x0, 0x6, 0x1f}, | ||
113 | {0xa33b, 0x0, 0x8, 0xf6}, | ||
114 | {0xa33c, 0x3, 0x5, 0x4}, | ||
115 | {0xa33d, 0x4, 0x4, 0x0}, | ||
116 | {0xa33d, 0x1, 0x1, 0x1}, | ||
117 | {0xa33d, 0x2, 0x1, 0x1}, | ||
118 | {0xa33d, 0x3, 0x1, 0x1}, | ||
119 | {0xa16d, 0x0, 0x4, 0xf}, | ||
120 | {0xa161, 0x0, 0x5, 0x5}, | ||
121 | {0xa162, 0x0, 0x4, 0x5}, | ||
122 | {0xa165, 0x0, 0x8, 0xff}, | ||
123 | {0xa166, 0x0, 0x8, 0x9c}, | ||
124 | {0xa2c3, 0x0, 0x4, 0x5}, | ||
125 | {0xa61a, 0x0, 0x6, 0xf}, | ||
126 | {0xb200, 0x0, 0x8, 0xa1}, | ||
127 | {0xb201, 0x0, 0x8, 0x7}, | ||
128 | {0xa093, 0x0, 0x1, 0x0}, | ||
129 | {0xa093, 0x1, 0x5, 0xf}, | ||
130 | {0xa094, 0x0, 0x8, 0xff}, | ||
131 | {0xa095, 0x0, 0x8, 0xf}, | ||
132 | {0xa080, 0x2, 0x5, 0x3}, | ||
133 | {0xa081, 0x0, 0x4, 0x0}, | ||
134 | {0xa081, 0x4, 0x4, 0x9}, | ||
135 | {0xa082, 0x0, 0x5, 0x1f}, | ||
136 | {0xa08d, 0x0, 0x8, 0x1}, | ||
137 | {0xa083, 0x0, 0x8, 0x32}, | ||
138 | {0xa084, 0x0, 0x1, 0x0}, | ||
139 | {0xa08e, 0x0, 0x8, 0x3}, | ||
140 | {0xa085, 0x0, 0x8, 0x32}, | ||
141 | {0xa086, 0x0, 0x3, 0x0}, | ||
142 | {0xa087, 0x0, 0x8, 0x6e}, | ||
143 | {0xa088, 0x0, 0x5, 0x15}, | ||
144 | {0xa089, 0x0, 0x8, 0x0}, | ||
145 | {0xa08a, 0x0, 0x5, 0x19}, | ||
146 | {0xa08b, 0x0, 0x8, 0x92}, | ||
147 | {0xa08c, 0x0, 0x5, 0x1c}, | ||
148 | {0xa120, 0x0, 0x8, 0x0}, | ||
149 | {0xa121, 0x0, 0x5, 0x10}, | ||
150 | {0xa122, 0x0, 0x8, 0x0}, | ||
151 | {0xa123, 0x0, 0x7, 0x40}, | ||
152 | {0xa123, 0x7, 0x1, 0x0}, | ||
153 | {0xa124, 0x0, 0x8, 0x13}, | ||
154 | {0xa125, 0x0, 0x7, 0x10}, | ||
155 | {0xa1c0, 0x0, 0x8, 0x0}, | ||
156 | {0xa1c1, 0x0, 0x5, 0x4}, | ||
157 | {0xa1c2, 0x0, 0x8, 0x0}, | ||
158 | {0xa1c3, 0x0, 0x5, 0x10}, | ||
159 | {0xa1c3, 0x5, 0x3, 0x0}, | ||
160 | {0xa1c4, 0x0, 0x6, 0x0}, | ||
161 | {0xa1c5, 0x0, 0x7, 0x10}, | ||
162 | {0xa100, 0x0, 0x8, 0x0}, | ||
163 | {0xa101, 0x0, 0x5, 0x10}, | ||
164 | {0xa102, 0x0, 0x8, 0x0}, | ||
165 | {0xa103, 0x0, 0x7, 0x40}, | ||
166 | {0xa103, 0x7, 0x1, 0x0}, | ||
167 | {0xa104, 0x0, 0x8, 0x18}, | ||
168 | {0xa105, 0x0, 0x7, 0xa}, | ||
169 | {0xa106, 0x0, 0x8, 0x20}, | ||
170 | {0xa107, 0x0, 0x8, 0x40}, | ||
171 | {0xa108, 0x0, 0x4, 0x0}, | ||
172 | {0xa38c, 0x0, 0x8, 0xfc}, | ||
173 | {0xa38d, 0x0, 0x8, 0x0}, | ||
174 | {0xa38e, 0x0, 0x8, 0x7e}, | ||
175 | {0xa38f, 0x0, 0x8, 0x0}, | ||
176 | {0xa390, 0x0, 0x8, 0x2f}, | ||
177 | {0xa60f, 0x5, 0x1, 0x1}, | ||
178 | {0xa170, 0x0, 0x8, 0xdc}, | ||
179 | {0xa171, 0x0, 0x2, 0x0}, | ||
180 | {0xa2ae, 0x0, 0x1, 0x1}, | ||
181 | {0xa2ae, 0x1, 0x1, 0x1}, | ||
182 | {0xa392, 0x0, 0x1, 0x1}, | ||
183 | {0xa391, 0x2, 0x1, 0x0}, | ||
184 | {0xabc1, 0x0, 0x8, 0xff}, | ||
185 | {0xabc2, 0x0, 0x8, 0x0}, | ||
186 | {0xabc8, 0x0, 0x8, 0x8}, | ||
187 | {0xabca, 0x0, 0x8, 0x10}, | ||
188 | {0xabcb, 0x0, 0x1, 0x0}, | ||
189 | {0xabc3, 0x5, 0x3, 0x7}, | ||
190 | {0xabc0, 0x6, 0x1, 0x0}, | ||
191 | {0xabc0, 0x4, 0x2, 0x0}, | ||
192 | {0xa344, 0x4, 0x4, 0x1}, | ||
193 | {0xabc0, 0x7, 0x1, 0x1}, | ||
194 | {0xabc0, 0x2, 0x1, 0x1}, | ||
195 | {0xa345, 0x0, 0x8, 0x66}, | ||
196 | {0xa346, 0x0, 0x8, 0x66}, | ||
197 | {0xa347, 0x0, 0x4, 0x0}, | ||
198 | {0xa343, 0x0, 0x4, 0xa}, | ||
199 | {0xa347, 0x4, 0x4, 0x2}, | ||
200 | {0xa348, 0x0, 0x4, 0xc}, | ||
201 | {0xa348, 0x4, 0x4, 0x7}, | ||
202 | {0xa349, 0x0, 0x6, 0x2}, | ||
203 | }; | ||
diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c new file mode 100644 index 000000000000..7db6eee50e39 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/af9005.c | |||
@@ -0,0 +1,1141 @@ | |||
1 | /* DVB USB compliant Linux driver for the Afatech 9005 | ||
2 | * USB1.1 DVB-T receiver. | ||
3 | * | ||
4 | * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) | ||
5 | * | ||
6 | * Thanks to Afatech who kindly provided information. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * see Documentation/dvb/REDME.dvb-usb for more information | ||
23 | */ | ||
24 | #include "af9005.h" | ||
25 | |||
26 | /* debug */ | ||
27 | int dvb_usb_af9005_debug; | ||
28 | module_param_named(debug, dvb_usb_af9005_debug, int, 0644); | ||
29 | MODULE_PARM_DESC(debug, | ||
30 | "set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))." | ||
31 | DVB_USB_DEBUG_STATUS); | ||
32 | /* enable obnoxious led */ | ||
33 | int dvb_usb_af9005_led = 1; | ||
34 | module_param_named(led, dvb_usb_af9005_led, bool, 0644); | ||
35 | MODULE_PARM_DESC(led, "enable led (default: 1)."); | ||
36 | |||
37 | /* eeprom dump */ | ||
38 | int dvb_usb_af9005_dump_eeprom = 0; | ||
39 | module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0); | ||
40 | MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom."); | ||
41 | |||
42 | /* remote control decoder */ | ||
43 | int (*rc_decode) (struct dvb_usb_device * d, u8 * data, int len, u32 * event, | ||
44 | int *state); | ||
45 | void *rc_keys; | ||
46 | int *rc_keys_size; | ||
47 | |||
48 | u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; | ||
49 | |||
50 | struct af9005_device_state { | ||
51 | u8 sequence; | ||
52 | int led_state; | ||
53 | }; | ||
54 | |||
55 | int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 * wbuf, u16 wlen, | ||
56 | u8 * rbuf, u16 rlen, int delay_ms) | ||
57 | { | ||
58 | int actlen, ret = -ENOMEM; | ||
59 | |||
60 | if (wbuf == NULL || wlen == 0) | ||
61 | return -EINVAL; | ||
62 | |||
63 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) | ||
64 | return ret; | ||
65 | |||
66 | deb_xfer(">>> "); | ||
67 | debug_dump(wbuf, wlen, deb_xfer); | ||
68 | |||
69 | ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev, | ||
70 | 2), wbuf, wlen, | ||
71 | &actlen, 2000); | ||
72 | |||
73 | if (ret) | ||
74 | err("bulk message failed: %d (%d/%d)", ret, wlen, actlen); | ||
75 | else | ||
76 | ret = actlen != wlen ? -1 : 0; | ||
77 | |||
78 | /* an answer is expected, and no error before */ | ||
79 | if (!ret && rbuf && rlen) { | ||
80 | if (delay_ms) | ||
81 | msleep(delay_ms); | ||
82 | |||
83 | ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, | ||
84 | 0x01), rbuf, | ||
85 | rlen, &actlen, 2000); | ||
86 | |||
87 | if (ret) | ||
88 | err("recv bulk message failed: %d", ret); | ||
89 | else { | ||
90 | deb_xfer("<<< "); | ||
91 | debug_dump(rbuf, actlen, deb_xfer); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | mutex_unlock(&d->usb_mutex); | ||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | int af9005_usb_generic_write(struct dvb_usb_device *d, u8 * buf, u16 len) | ||
100 | { | ||
101 | return af9005_usb_generic_rw(d, buf, len, NULL, 0, 0); | ||
102 | } | ||
103 | |||
104 | int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg, | ||
105 | int readwrite, int type, u8 * values, int len) | ||
106 | { | ||
107 | struct af9005_device_state *st = d->priv; | ||
108 | u8 obuf[16] = { 0 }; | ||
109 | u8 ibuf[17] = { 0 }; | ||
110 | u8 command; | ||
111 | int i; | ||
112 | int ret; | ||
113 | |||
114 | if (len < 1) { | ||
115 | err("generic read/write, less than 1 byte. Makes no sense."); | ||
116 | return -EINVAL; | ||
117 | } | ||
118 | if (len > 8) { | ||
119 | err("generic read/write, more than 8 bytes. Not supported."); | ||
120 | return -EINVAL; | ||
121 | } | ||
122 | |||
123 | obuf[0] = 14; /* rest of buffer length low */ | ||
124 | obuf[1] = 0; /* rest of buffer length high */ | ||
125 | |||
126 | obuf[2] = AF9005_REGISTER_RW; /* register operation */ | ||
127 | obuf[3] = 12; /* rest of buffer length */ | ||
128 | |||
129 | obuf[4] = st->sequence++; /* sequence number */ | ||
130 | |||
131 | obuf[5] = (u8) (reg >> 8); /* register address */ | ||
132 | obuf[6] = (u8) (reg & 0xff); | ||
133 | |||
134 | if (type == AF9005_OFDM_REG) { | ||
135 | command = AF9005_CMD_OFDM_REG; | ||
136 | } else { | ||
137 | command = AF9005_CMD_TUNER; | ||
138 | } | ||
139 | |||
140 | if (len > 1) | ||
141 | command |= | ||
142 | AF9005_CMD_BURST | AF9005_CMD_AUTOINC | (len - 1) << 3; | ||
143 | command |= readwrite; | ||
144 | if (readwrite == AF9005_CMD_WRITE) | ||
145 | for (i = 0; i < len; i++) | ||
146 | obuf[8 + i] = values[i]; | ||
147 | else if (type == AF9005_TUNER_REG) | ||
148 | /* read command for tuner, the first byte contains the i2c address */ | ||
149 | obuf[8] = values[0]; | ||
150 | obuf[7] = command; | ||
151 | |||
152 | ret = af9005_usb_generic_rw(d, obuf, 16, ibuf, 17, 0); | ||
153 | if (ret) | ||
154 | return ret; | ||
155 | |||
156 | /* sanity check */ | ||
157 | if (ibuf[2] != AF9005_REGISTER_RW_ACK) { | ||
158 | err("generic read/write, wrong reply code."); | ||
159 | return -EIO; | ||
160 | } | ||
161 | if (ibuf[3] != 0x0d) { | ||
162 | err("generic read/write, wrong length in reply."); | ||
163 | return -EIO; | ||
164 | } | ||
165 | if (ibuf[4] != obuf[4]) { | ||
166 | err("generic read/write, wrong sequence in reply."); | ||
167 | return -EIO; | ||
168 | } | ||
169 | /* | ||
170 | Windows driver doesn't check these fields, in fact sometimes | ||
171 | the register in the reply is different that what has been sent | ||
172 | |||
173 | if (ibuf[5] != obuf[5] || ibuf[6] != obuf[6]) { | ||
174 | err("generic read/write, wrong register in reply."); | ||
175 | return -EIO; | ||
176 | } | ||
177 | if (ibuf[7] != command) { | ||
178 | err("generic read/write wrong command in reply."); | ||
179 | return -EIO; | ||
180 | } | ||
181 | */ | ||
182 | if (ibuf[16] != 0x01) { | ||
183 | err("generic read/write wrong status code in reply."); | ||
184 | return -EIO; | ||
185 | } | ||
186 | if (readwrite == AF9005_CMD_READ) | ||
187 | for (i = 0; i < len; i++) | ||
188 | values[i] = ibuf[8 + i]; | ||
189 | |||
190 | return 0; | ||
191 | |||
192 | } | ||
193 | |||
194 | int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 * value) | ||
195 | { | ||
196 | int ret; | ||
197 | deb_reg("read register %x ", reg); | ||
198 | ret = af9005_generic_read_write(d, reg, | ||
199 | AF9005_CMD_READ, AF9005_OFDM_REG, | ||
200 | value, 1); | ||
201 | if (ret) | ||
202 | deb_reg("failed\n"); | ||
203 | else | ||
204 | deb_reg("value %x\n", *value); | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg, | ||
209 | u8 * values, int len) | ||
210 | { | ||
211 | int ret; | ||
212 | deb_reg("read %d registers %x ", len, reg); | ||
213 | ret = af9005_generic_read_write(d, reg, | ||
214 | AF9005_CMD_READ, AF9005_OFDM_REG, | ||
215 | values, len); | ||
216 | if (ret) | ||
217 | deb_reg("failed\n"); | ||
218 | else | ||
219 | debug_dump(values, len, deb_reg); | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 value) | ||
224 | { | ||
225 | int ret; | ||
226 | u8 temp = value; | ||
227 | deb_reg("write register %x value %x ", reg, value); | ||
228 | ret = af9005_generic_read_write(d, reg, | ||
229 | AF9005_CMD_WRITE, AF9005_OFDM_REG, | ||
230 | &temp, 1); | ||
231 | if (ret) | ||
232 | deb_reg("failed\n"); | ||
233 | else | ||
234 | deb_reg("ok\n"); | ||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg, | ||
239 | u8 * values, int len) | ||
240 | { | ||
241 | int ret; | ||
242 | deb_reg("write %d registers %x values ", len, reg); | ||
243 | debug_dump(values, len, deb_reg); | ||
244 | |||
245 | ret = af9005_generic_read_write(d, reg, | ||
246 | AF9005_CMD_WRITE, AF9005_OFDM_REG, | ||
247 | values, len); | ||
248 | if (ret) | ||
249 | deb_reg("failed\n"); | ||
250 | else | ||
251 | deb_reg("ok\n"); | ||
252 | return ret; | ||
253 | } | ||
254 | |||
255 | int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos, | ||
256 | u8 len, u8 * value) | ||
257 | { | ||
258 | u8 temp; | ||
259 | int ret; | ||
260 | deb_reg("read bits %x %x %x", reg, pos, len); | ||
261 | ret = af9005_read_ofdm_register(d, reg, &temp); | ||
262 | if (ret) { | ||
263 | deb_reg(" failed\n"); | ||
264 | return ret; | ||
265 | } | ||
266 | *value = (temp >> pos) & regmask[len - 1]; | ||
267 | deb_reg(" value %x\n", *value); | ||
268 | return 0; | ||
269 | |||
270 | } | ||
271 | |||
272 | int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos, | ||
273 | u8 len, u8 value) | ||
274 | { | ||
275 | u8 temp, mask; | ||
276 | int ret; | ||
277 | deb_reg("write bits %x %x %x value %x\n", reg, pos, len, value); | ||
278 | if (pos == 0 && len == 8) | ||
279 | return af9005_write_ofdm_register(d, reg, value); | ||
280 | ret = af9005_read_ofdm_register(d, reg, &temp); | ||
281 | if (ret) | ||
282 | return ret; | ||
283 | mask = regmask[len - 1] << pos; | ||
284 | temp = (temp & ~mask) | ((value << pos) & mask); | ||
285 | return af9005_write_ofdm_register(d, reg, temp); | ||
286 | |||
287 | } | ||
288 | |||
289 | static int af9005_usb_read_tuner_registers(struct dvb_usb_device *d, | ||
290 | u16 reg, u8 * values, int len) | ||
291 | { | ||
292 | return af9005_generic_read_write(d, reg, | ||
293 | AF9005_CMD_READ, AF9005_TUNER_REG, | ||
294 | values, len); | ||
295 | } | ||
296 | |||
297 | static int af9005_usb_write_tuner_registers(struct dvb_usb_device *d, | ||
298 | u16 reg, u8 * values, int len) | ||
299 | { | ||
300 | return af9005_generic_read_write(d, reg, | ||
301 | AF9005_CMD_WRITE, | ||
302 | AF9005_TUNER_REG, values, len); | ||
303 | } | ||
304 | |||
305 | int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg, | ||
306 | u8 * values, int len) | ||
307 | { | ||
308 | /* don't let the name of this function mislead you: it's just used | ||
309 | as an interface from the firmware to the i2c bus. The actual | ||
310 | i2c addresses are contained in the data */ | ||
311 | int ret, i, done = 0, fail = 0; | ||
312 | u8 temp; | ||
313 | ret = af9005_usb_write_tuner_registers(d, reg, values, len); | ||
314 | if (ret) | ||
315 | return ret; | ||
316 | if (reg != 0xffff) { | ||
317 | /* check if write done (0xa40d bit 1) or fail (0xa40d bit 2) */ | ||
318 | for (i = 0; i < 200; i++) { | ||
319 | ret = | ||
320 | af9005_read_ofdm_register(d, | ||
321 | xd_I2C_i2c_m_status_wdat_done, | ||
322 | &temp); | ||
323 | if (ret) | ||
324 | return ret; | ||
325 | done = temp & (regmask[i2c_m_status_wdat_done_len - 1] | ||
326 | << i2c_m_status_wdat_done_pos); | ||
327 | if (done) | ||
328 | break; | ||
329 | fail = temp & (regmask[i2c_m_status_wdat_fail_len - 1] | ||
330 | << i2c_m_status_wdat_fail_pos); | ||
331 | if (fail) | ||
332 | break; | ||
333 | msleep(50); | ||
334 | } | ||
335 | if (i == 200) | ||
336 | return -ETIMEDOUT; | ||
337 | if (fail) { | ||
338 | /* clear write fail bit */ | ||
339 | af9005_write_register_bits(d, | ||
340 | xd_I2C_i2c_m_status_wdat_fail, | ||
341 | i2c_m_status_wdat_fail_pos, | ||
342 | i2c_m_status_wdat_fail_len, | ||
343 | 1); | ||
344 | return -EIO; | ||
345 | } | ||
346 | /* clear write done bit */ | ||
347 | ret = | ||
348 | af9005_write_register_bits(d, | ||
349 | xd_I2C_i2c_m_status_wdat_fail, | ||
350 | i2c_m_status_wdat_done_pos, | ||
351 | i2c_m_status_wdat_done_len, 1); | ||
352 | if (ret) | ||
353 | return ret; | ||
354 | } | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, u8 addr, | ||
359 | u8 * values, int len) | ||
360 | { | ||
361 | /* don't let the name of this function mislead you: it's just used | ||
362 | as an interface from the firmware to the i2c bus. The actual | ||
363 | i2c addresses are contained in the data */ | ||
364 | int ret, i; | ||
365 | u8 temp, buf[2]; | ||
366 | |||
367 | buf[0] = addr; /* tuner i2c address */ | ||
368 | buf[1] = values[0]; /* tuner register */ | ||
369 | |||
370 | values[0] = addr + 0x01; /* i2c read address */ | ||
371 | |||
372 | if (reg == APO_REG_I2C_RW_SILICON_TUNER) { | ||
373 | /* write tuner i2c address to tuner, 0c00c0 undocumented, found by sniffing */ | ||
374 | ret = af9005_write_tuner_registers(d, 0x00c0, buf, 2); | ||
375 | if (ret) | ||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | /* send read command to ofsm */ | ||
380 | ret = af9005_usb_read_tuner_registers(d, reg, values, 1); | ||
381 | if (ret) | ||
382 | return ret; | ||
383 | |||
384 | /* check if read done */ | ||
385 | for (i = 0; i < 200; i++) { | ||
386 | ret = af9005_read_ofdm_register(d, 0xa408, &temp); | ||
387 | if (ret) | ||
388 | return ret; | ||
389 | if (temp & 0x01) | ||
390 | break; | ||
391 | msleep(50); | ||
392 | } | ||
393 | if (i == 200) | ||
394 | return -ETIMEDOUT; | ||
395 | |||
396 | /* clear read done bit (by writing 1) */ | ||
397 | ret = af9005_write_ofdm_register(d, xd_I2C_i2c_m_data8, 1); | ||
398 | if (ret) | ||
399 | return ret; | ||
400 | |||
401 | /* get read data (available from 0xa400) */ | ||
402 | for (i = 0; i < len; i++) { | ||
403 | ret = af9005_read_ofdm_register(d, 0xa400 + i, &temp); | ||
404 | if (ret) | ||
405 | return ret; | ||
406 | values[i] = temp; | ||
407 | } | ||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | static int af9005_i2c_write(struct dvb_usb_device *d, u8 i2caddr, u8 reg, | ||
412 | u8 * data, int len) | ||
413 | { | ||
414 | int ret, i; | ||
415 | u8 buf[3]; | ||
416 | deb_i2c("i2c_write i2caddr %x, reg %x, len %d data ", i2caddr, | ||
417 | reg, len); | ||
418 | debug_dump(data, len, deb_i2c); | ||
419 | |||
420 | for (i = 0; i < len; i++) { | ||
421 | buf[0] = i2caddr; | ||
422 | buf[1] = reg + (u8) i; | ||
423 | buf[2] = data[i]; | ||
424 | ret = | ||
425 | af9005_write_tuner_registers(d, | ||
426 | APO_REG_I2C_RW_SILICON_TUNER, | ||
427 | buf, 3); | ||
428 | if (ret) { | ||
429 | deb_i2c("i2c_write failed\n"); | ||
430 | return ret; | ||
431 | } | ||
432 | } | ||
433 | deb_i2c("i2c_write ok\n"); | ||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | static int af9005_i2c_read(struct dvb_usb_device *d, u8 i2caddr, u8 reg, | ||
438 | u8 * data, int len) | ||
439 | { | ||
440 | int ret, i; | ||
441 | u8 temp; | ||
442 | deb_i2c("i2c_read i2caddr %x, reg %x, len %d\n ", i2caddr, reg, len); | ||
443 | for (i = 0; i < len; i++) { | ||
444 | temp = reg + i; | ||
445 | ret = | ||
446 | af9005_read_tuner_registers(d, | ||
447 | APO_REG_I2C_RW_SILICON_TUNER, | ||
448 | i2caddr, &temp, 1); | ||
449 | if (ret) { | ||
450 | deb_i2c("i2c_read failed\n"); | ||
451 | return ret; | ||
452 | } | ||
453 | data[i] = temp; | ||
454 | } | ||
455 | deb_i2c("i2c data read: "); | ||
456 | debug_dump(data, len, deb_i2c); | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||
461 | int num) | ||
462 | { | ||
463 | /* only implements what the mt2060 module does, don't know how | ||
464 | to make it really generic */ | ||
465 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||
466 | int ret; | ||
467 | u8 reg, addr; | ||
468 | u8 *value; | ||
469 | |||
470 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
471 | return -EAGAIN; | ||
472 | |||
473 | if (num > 2) | ||
474 | warn("more than 2 i2c messages at a time is not handled yet. TODO."); | ||
475 | |||
476 | if (num == 2) { | ||
477 | /* reads a single register */ | ||
478 | reg = *msg[0].buf; | ||
479 | addr = msg[0].addr; | ||
480 | value = msg[1].buf; | ||
481 | ret = af9005_i2c_read(d, addr, reg, value, 1); | ||
482 | if (ret == 0) | ||
483 | ret = 2; | ||
484 | } else { | ||
485 | /* write one or more registers */ | ||
486 | reg = msg[0].buf[0]; | ||
487 | addr = msg[0].addr; | ||
488 | value = &msg[0].buf[1]; | ||
489 | ret = af9005_i2c_write(d, addr, reg, value, msg[0].len - 1); | ||
490 | if (ret == 0) | ||
491 | ret = 1; | ||
492 | } | ||
493 | |||
494 | mutex_unlock(&d->i2c_mutex); | ||
495 | return ret; | ||
496 | } | ||
497 | |||
498 | static u32 af9005_i2c_func(struct i2c_adapter *adapter) | ||
499 | { | ||
500 | return I2C_FUNC_I2C; | ||
501 | } | ||
502 | |||
503 | static struct i2c_algorithm af9005_i2c_algo = { | ||
504 | .master_xfer = af9005_i2c_xfer, | ||
505 | .functionality = af9005_i2c_func, | ||
506 | }; | ||
507 | |||
508 | int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf, | ||
509 | int wlen, u8 * rbuf, int rlen) | ||
510 | { | ||
511 | struct af9005_device_state *st = d->priv; | ||
512 | |||
513 | int ret, i, packet_len; | ||
514 | u8 buf[64]; | ||
515 | u8 ibuf[64]; | ||
516 | |||
517 | if (wlen < 0) { | ||
518 | err("send command, wlen less than 0 bytes. Makes no sense."); | ||
519 | return -EINVAL; | ||
520 | } | ||
521 | if (wlen > 54) { | ||
522 | err("send command, wlen more than 54 bytes. Not supported."); | ||
523 | return -EINVAL; | ||
524 | } | ||
525 | if (rlen > 54) { | ||
526 | err("send command, rlen more than 54 bytes. Not supported."); | ||
527 | return -EINVAL; | ||
528 | } | ||
529 | packet_len = wlen + 5; | ||
530 | buf[0] = (u8) (packet_len & 0xff); | ||
531 | buf[1] = (u8) ((packet_len & 0xff00) >> 8); | ||
532 | |||
533 | buf[2] = 0x26; /* packet type */ | ||
534 | buf[3] = wlen + 3; | ||
535 | buf[4] = st->sequence++; | ||
536 | buf[5] = command; | ||
537 | buf[6] = wlen; | ||
538 | for (i = 0; i < wlen; i++) | ||
539 | buf[7 + i] = wbuf[i]; | ||
540 | ret = af9005_usb_generic_rw(d, buf, wlen + 7, ibuf, rlen + 7, 0); | ||
541 | if (ret) | ||
542 | return ret; | ||
543 | if (ibuf[2] != 0x27) { | ||
544 | err("send command, wrong reply code."); | ||
545 | return -EIO; | ||
546 | } | ||
547 | if (ibuf[4] != buf[4]) { | ||
548 | err("send command, wrong sequence in reply."); | ||
549 | return -EIO; | ||
550 | } | ||
551 | if (ibuf[5] != 0x01) { | ||
552 | err("send command, wrong status code in reply."); | ||
553 | return -EIO; | ||
554 | } | ||
555 | if (ibuf[6] != rlen) { | ||
556 | err("send command, invalid data length in reply."); | ||
557 | return -EIO; | ||
558 | } | ||
559 | for (i = 0; i < rlen; i++) | ||
560 | rbuf[i] = ibuf[i + 7]; | ||
561 | return 0; | ||
562 | } | ||
563 | |||
564 | int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values, | ||
565 | int len) | ||
566 | { | ||
567 | struct af9005_device_state *st = d->priv; | ||
568 | u8 obuf[16], ibuf[14]; | ||
569 | int ret, i; | ||
570 | |||
571 | memset(obuf, 0, sizeof(obuf)); | ||
572 | memset(ibuf, 0, sizeof(ibuf)); | ||
573 | |||
574 | obuf[0] = 14; /* length of rest of packet low */ | ||
575 | obuf[1] = 0; /* length of rest of packer high */ | ||
576 | |||
577 | obuf[2] = 0x2a; /* read/write eeprom */ | ||
578 | |||
579 | obuf[3] = 12; /* size */ | ||
580 | |||
581 | obuf[4] = st->sequence++; | ||
582 | |||
583 | obuf[5] = 0; /* read */ | ||
584 | |||
585 | obuf[6] = len; | ||
586 | obuf[7] = address; | ||
587 | ret = af9005_usb_generic_rw(d, obuf, 16, ibuf, 14, 0); | ||
588 | if (ret) | ||
589 | return ret; | ||
590 | if (ibuf[2] != 0x2b) { | ||
591 | err("Read eeprom, invalid reply code"); | ||
592 | return -EIO; | ||
593 | } | ||
594 | if (ibuf[3] != 10) { | ||
595 | err("Read eeprom, invalid reply length"); | ||
596 | return -EIO; | ||
597 | } | ||
598 | if (ibuf[4] != obuf[4]) { | ||
599 | err("Read eeprom, wrong sequence in reply "); | ||
600 | return -EIO; | ||
601 | } | ||
602 | if (ibuf[5] != 1) { | ||
603 | err("Read eeprom, wrong status in reply "); | ||
604 | return -EIO; | ||
605 | } | ||
606 | for (i = 0; i < len; i++) { | ||
607 | values[i] = ibuf[6 + i]; | ||
608 | } | ||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | static int af9005_boot_packet(struct usb_device *udev, int type, u8 * reply) | ||
613 | { | ||
614 | u8 buf[FW_BULKOUT_SIZE + 2]; | ||
615 | u16 checksum; | ||
616 | int act_len, i, ret; | ||
617 | memset(buf, 0, sizeof(buf)); | ||
618 | buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff); | ||
619 | buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff); | ||
620 | switch (type) { | ||
621 | case FW_CONFIG: | ||
622 | buf[2] = 0x11; | ||
623 | buf[3] = 0x04; | ||
624 | buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */ | ||
625 | buf[5] = 0x03; | ||
626 | checksum = buf[4] + buf[5]; | ||
627 | buf[6] = (u8) ((checksum >> 8) & 0xff); | ||
628 | buf[7] = (u8) (checksum & 0xff); | ||
629 | break; | ||
630 | case FW_CONFIRM: | ||
631 | buf[2] = 0x11; | ||
632 | buf[3] = 0x04; | ||
633 | buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */ | ||
634 | buf[5] = 0x01; | ||
635 | checksum = buf[4] + buf[5]; | ||
636 | buf[6] = (u8) ((checksum >> 8) & 0xff); | ||
637 | buf[7] = (u8) (checksum & 0xff); | ||
638 | break; | ||
639 | case FW_BOOT: | ||
640 | buf[2] = 0x10; | ||
641 | buf[3] = 0x08; | ||
642 | buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */ | ||
643 | buf[5] = 0x97; | ||
644 | buf[6] = 0xaa; | ||
645 | buf[7] = 0x55; | ||
646 | buf[8] = 0xa5; | ||
647 | buf[9] = 0x5a; | ||
648 | checksum = 0; | ||
649 | for (i = 4; i <= 9; i++) | ||
650 | checksum += buf[i]; | ||
651 | buf[10] = (u8) ((checksum >> 8) & 0xff); | ||
652 | buf[11] = (u8) (checksum & 0xff); | ||
653 | break; | ||
654 | default: | ||
655 | err("boot packet invalid boot packet type"); | ||
656 | return -EINVAL; | ||
657 | } | ||
658 | deb_fw(">>> "); | ||
659 | debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw); | ||
660 | |||
661 | ret = usb_bulk_msg(udev, | ||
662 | usb_sndbulkpipe(udev, 0x02), | ||
663 | buf, FW_BULKOUT_SIZE + 2, &act_len, 2000); | ||
664 | if (ret) | ||
665 | err("boot packet bulk message failed: %d (%d/%d)", ret, | ||
666 | FW_BULKOUT_SIZE + 2, act_len); | ||
667 | else | ||
668 | ret = act_len != FW_BULKOUT_SIZE + 2 ? -1 : 0; | ||
669 | if (ret) | ||
670 | return ret; | ||
671 | memset(buf, 0, 9); | ||
672 | ret = usb_bulk_msg(udev, | ||
673 | usb_rcvbulkpipe(udev, 0x01), buf, 9, &act_len, 2000); | ||
674 | if (ret) { | ||
675 | err("boot packet recv bulk message failed: %d", ret); | ||
676 | return ret; | ||
677 | } | ||
678 | deb_fw("<<< "); | ||
679 | debug_dump(buf, act_len, deb_fw); | ||
680 | checksum = 0; | ||
681 | switch (type) { | ||
682 | case FW_CONFIG: | ||
683 | if (buf[2] != 0x11) { | ||
684 | err("boot bad config header."); | ||
685 | return -EIO; | ||
686 | } | ||
687 | if (buf[3] != 0x05) { | ||
688 | err("boot bad config size."); | ||
689 | return -EIO; | ||
690 | } | ||
691 | if (buf[4] != 0x00) { | ||
692 | err("boot bad config sequence."); | ||
693 | return -EIO; | ||
694 | } | ||
695 | if (buf[5] != 0x04) { | ||
696 | err("boot bad config subtype."); | ||
697 | return -EIO; | ||
698 | } | ||
699 | for (i = 4; i <= 6; i++) | ||
700 | checksum += buf[i]; | ||
701 | if (buf[7] * 256 + buf[8] != checksum) { | ||
702 | err("boot bad config checksum."); | ||
703 | return -EIO; | ||
704 | } | ||
705 | *reply = buf[6]; | ||
706 | break; | ||
707 | case FW_CONFIRM: | ||
708 | if (buf[2] != 0x11) { | ||
709 | err("boot bad confirm header."); | ||
710 | return -EIO; | ||
711 | } | ||
712 | if (buf[3] != 0x05) { | ||
713 | err("boot bad confirm size."); | ||
714 | return -EIO; | ||
715 | } | ||
716 | if (buf[4] != 0x00) { | ||
717 | err("boot bad confirm sequence."); | ||
718 | return -EIO; | ||
719 | } | ||
720 | if (buf[5] != 0x02) { | ||
721 | err("boot bad confirm subtype."); | ||
722 | return -EIO; | ||
723 | } | ||
724 | for (i = 4; i <= 6; i++) | ||
725 | checksum += buf[i]; | ||
726 | if (buf[7] * 256 + buf[8] != checksum) { | ||
727 | err("boot bad confirm checksum."); | ||
728 | return -EIO; | ||
729 | } | ||
730 | *reply = buf[6]; | ||
731 | break; | ||
732 | case FW_BOOT: | ||
733 | if (buf[2] != 0x10) { | ||
734 | err("boot bad boot header."); | ||
735 | return -EIO; | ||
736 | } | ||
737 | if (buf[3] != 0x05) { | ||
738 | err("boot bad boot size."); | ||
739 | return -EIO; | ||
740 | } | ||
741 | if (buf[4] != 0x00) { | ||
742 | err("boot bad boot sequence."); | ||
743 | return -EIO; | ||
744 | } | ||
745 | if (buf[5] != 0x01) { | ||
746 | err("boot bad boot pattern 01."); | ||
747 | return -EIO; | ||
748 | } | ||
749 | if (buf[6] != 0x10) { | ||
750 | err("boot bad boot pattern 10."); | ||
751 | return -EIO; | ||
752 | } | ||
753 | for (i = 4; i <= 6; i++) | ||
754 | checksum += buf[i]; | ||
755 | if (buf[7] * 256 + buf[8] != checksum) { | ||
756 | err("boot bad boot checksum."); | ||
757 | return -EIO; | ||
758 | } | ||
759 | break; | ||
760 | |||
761 | } | ||
762 | |||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw) | ||
767 | { | ||
768 | int i, packets, ret, act_len; | ||
769 | |||
770 | u8 buf[FW_BULKOUT_SIZE + 2]; | ||
771 | u8 reply; | ||
772 | |||
773 | ret = af9005_boot_packet(udev, FW_CONFIG, &reply); | ||
774 | if (ret) | ||
775 | return ret; | ||
776 | if (reply != 0x01) { | ||
777 | err("before downloading firmware, FW_CONFIG expected 0x01, received 0x%x", reply); | ||
778 | return -EIO; | ||
779 | } | ||
780 | packets = fw->size / FW_BULKOUT_SIZE; | ||
781 | buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff); | ||
782 | buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff); | ||
783 | for (i = 0; i < packets; i++) { | ||
784 | memcpy(&buf[2], fw->data + i * FW_BULKOUT_SIZE, | ||
785 | FW_BULKOUT_SIZE); | ||
786 | deb_fw(">>> "); | ||
787 | debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw); | ||
788 | ret = usb_bulk_msg(udev, | ||
789 | usb_sndbulkpipe(udev, 0x02), | ||
790 | buf, FW_BULKOUT_SIZE + 2, &act_len, 1000); | ||
791 | if (ret) { | ||
792 | err("firmware download failed at packet %d with code %d", i, ret); | ||
793 | return ret; | ||
794 | } | ||
795 | } | ||
796 | ret = af9005_boot_packet(udev, FW_CONFIRM, &reply); | ||
797 | if (ret) | ||
798 | return ret; | ||
799 | if (reply != (u8) (packets & 0xff)) { | ||
800 | err("after downloading firmware, FW_CONFIRM expected 0x%x, received 0x%x", packets & 0xff, reply); | ||
801 | return -EIO; | ||
802 | } | ||
803 | ret = af9005_boot_packet(udev, FW_BOOT, &reply); | ||
804 | if (ret) | ||
805 | return ret; | ||
806 | ret = af9005_boot_packet(udev, FW_CONFIG, &reply); | ||
807 | if (ret) | ||
808 | return ret; | ||
809 | if (reply != 0x02) { | ||
810 | err("after downloading firmware, FW_CONFIG expected 0x02, received 0x%x", reply); | ||
811 | return -EIO; | ||
812 | } | ||
813 | |||
814 | return 0; | ||
815 | |||
816 | } | ||
817 | |||
818 | int af9005_led_control(struct dvb_usb_device *d, int onoff) | ||
819 | { | ||
820 | struct af9005_device_state *st = d->priv; | ||
821 | int temp, ret; | ||
822 | |||
823 | if (onoff && dvb_usb_af9005_led) | ||
824 | temp = 1; | ||
825 | else | ||
826 | temp = 0; | ||
827 | if (st->led_state != temp) { | ||
828 | ret = | ||
829 | af9005_write_register_bits(d, xd_p_reg_top_locken1, | ||
830 | reg_top_locken1_pos, | ||
831 | reg_top_locken1_len, temp); | ||
832 | if (ret) | ||
833 | return ret; | ||
834 | ret = | ||
835 | af9005_write_register_bits(d, xd_p_reg_top_lock1, | ||
836 | reg_top_lock1_pos, | ||
837 | reg_top_lock1_len, temp); | ||
838 | if (ret) | ||
839 | return ret; | ||
840 | st->led_state = temp; | ||
841 | } | ||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | static int af9005_frontend_attach(struct dvb_usb_adapter *adap) | ||
846 | { | ||
847 | u8 buf[8]; | ||
848 | int i; | ||
849 | |||
850 | /* without these calls the first commands after downloading | ||
851 | the firmware fail. I put these calls here to simulate | ||
852 | what it is done in dvb-usb-init.c. | ||
853 | */ | ||
854 | struct usb_device *udev = adap->dev->udev; | ||
855 | usb_clear_halt(udev, usb_sndbulkpipe(udev, 2)); | ||
856 | usb_clear_halt(udev, usb_rcvbulkpipe(udev, 1)); | ||
857 | if (dvb_usb_af9005_dump_eeprom) { | ||
858 | printk("EEPROM DUMP\n"); | ||
859 | for (i = 0; i < 255; i += 8) { | ||
860 | af9005_read_eeprom(adap->dev, i, buf, 8); | ||
861 | printk("ADDR %x ", i); | ||
862 | debug_dump(buf, 8, printk); | ||
863 | } | ||
864 | } | ||
865 | adap->fe = af9005_fe_attach(adap->dev); | ||
866 | return 0; | ||
867 | } | ||
868 | |||
869 | static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state) | ||
870 | { | ||
871 | struct af9005_device_state *st = d->priv; | ||
872 | int ret, len; | ||
873 | |||
874 | u8 obuf[5]; | ||
875 | u8 ibuf[256]; | ||
876 | |||
877 | *state = REMOTE_NO_KEY_PRESSED; | ||
878 | if (rc_decode == NULL) { | ||
879 | /* it shouldn't never come here */ | ||
880 | return 0; | ||
881 | } | ||
882 | /* deb_info("rc_query\n"); */ | ||
883 | obuf[0] = 3; /* rest of packet length low */ | ||
884 | obuf[1] = 0; /* rest of packet lentgh high */ | ||
885 | obuf[2] = 0x40; /* read remote */ | ||
886 | obuf[3] = 1; /* rest of packet length */ | ||
887 | obuf[4] = st->sequence++; /* sequence number */ | ||
888 | ret = af9005_usb_generic_rw(d, obuf, 5, ibuf, 256, 0); | ||
889 | if (ret) { | ||
890 | err("rc query failed"); | ||
891 | return ret; | ||
892 | } | ||
893 | if (ibuf[2] != 0x41) { | ||
894 | err("rc query bad header."); | ||
895 | return -EIO; | ||
896 | } | ||
897 | if (ibuf[4] != obuf[4]) { | ||
898 | err("rc query bad sequence."); | ||
899 | return -EIO; | ||
900 | } | ||
901 | len = ibuf[5]; | ||
902 | if (len > 246) { | ||
903 | err("rc query invalid length"); | ||
904 | return -EIO; | ||
905 | } | ||
906 | if (len > 0) { | ||
907 | deb_rc("rc data (%d) ", len); | ||
908 | debug_dump((ibuf + 6), len, deb_rc); | ||
909 | ret = rc_decode(d, &ibuf[6], len, event, state); | ||
910 | if (ret) { | ||
911 | err("rc_decode failed"); | ||
912 | return ret; | ||
913 | } else { | ||
914 | deb_rc("rc_decode state %x event %x\n", *state, *event); | ||
915 | if (*state == REMOTE_KEY_REPEAT) | ||
916 | *event = d->last_event; | ||
917 | } | ||
918 | } | ||
919 | return 0; | ||
920 | } | ||
921 | |||
922 | static int af9005_power_ctrl(struct dvb_usb_device *d, int onoff) | ||
923 | { | ||
924 | |||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | static int af9005_pid_filter_control(struct dvb_usb_adapter *adap, int onoff) | ||
929 | { | ||
930 | int ret; | ||
931 | deb_info("pid filter control onoff %d\n", onoff); | ||
932 | if (onoff) { | ||
933 | ret = | ||
934 | af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1); | ||
935 | if (ret) | ||
936 | return ret; | ||
937 | ret = | ||
938 | af9005_write_register_bits(adap->dev, | ||
939 | XD_MP2IF_DMX_CTRL, 1, 1, 1); | ||
940 | if (ret) | ||
941 | return ret; | ||
942 | ret = | ||
943 | af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1); | ||
944 | } else | ||
945 | ret = | ||
946 | af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 0); | ||
947 | if (ret) | ||
948 | return ret; | ||
949 | deb_info("pid filter control ok\n"); | ||
950 | return 0; | ||
951 | } | ||
952 | |||
953 | static int af9005_pid_filter(struct dvb_usb_adapter *adap, int index, | ||
954 | u16 pid, int onoff) | ||
955 | { | ||
956 | u8 cmd = index & 0x1f; | ||
957 | int ret; | ||
958 | deb_info("set pid filter, index %d, pid %x, onoff %d\n", index, | ||
959 | pid, onoff); | ||
960 | if (onoff) { | ||
961 | /* cannot use it as pid_filter_ctrl since it has to be done | ||
962 | before setting the first pid */ | ||
963 | if (adap->feedcount == 1) { | ||
964 | deb_info("first pid set, enable pid table\n"); | ||
965 | ret = af9005_pid_filter_control(adap, onoff); | ||
966 | if (ret) | ||
967 | return ret; | ||
968 | } | ||
969 | ret = | ||
970 | af9005_write_ofdm_register(adap->dev, | ||
971 | XD_MP2IF_PID_DATA_L, | ||
972 | (u8) (pid & 0xff)); | ||
973 | if (ret) | ||
974 | return ret; | ||
975 | ret = | ||
976 | af9005_write_ofdm_register(adap->dev, | ||
977 | XD_MP2IF_PID_DATA_H, | ||
978 | (u8) (pid >> 8)); | ||
979 | if (ret) | ||
980 | return ret; | ||
981 | cmd |= 0x20 | 0x40; | ||
982 | } else { | ||
983 | if (adap->feedcount == 0) { | ||
984 | deb_info("last pid unset, disable pid table\n"); | ||
985 | ret = af9005_pid_filter_control(adap, onoff); | ||
986 | if (ret) | ||
987 | return ret; | ||
988 | } | ||
989 | } | ||
990 | ret = af9005_write_ofdm_register(adap->dev, XD_MP2IF_PID_IDX, cmd); | ||
991 | if (ret) | ||
992 | return ret; | ||
993 | deb_info("set pid ok\n"); | ||
994 | return 0; | ||
995 | } | ||
996 | |||
997 | static int af9005_identify_state(struct usb_device *udev, | ||
998 | struct dvb_usb_device_properties *props, | ||
999 | struct dvb_usb_device_description **desc, | ||
1000 | int *cold) | ||
1001 | { | ||
1002 | int ret; | ||
1003 | u8 reply; | ||
1004 | ret = af9005_boot_packet(udev, FW_CONFIG, &reply); | ||
1005 | if (ret) | ||
1006 | return ret; | ||
1007 | deb_info("result of FW_CONFIG in identify state %d\n", reply); | ||
1008 | if (reply == 0x01) | ||
1009 | *cold = 1; | ||
1010 | else if (reply == 0x02) | ||
1011 | *cold = 0; | ||
1012 | else | ||
1013 | return -EIO; | ||
1014 | deb_info("Identify state cold = %d\n", *cold); | ||
1015 | return 0; | ||
1016 | } | ||
1017 | |||
1018 | static struct dvb_usb_device_properties af9005_properties; | ||
1019 | |||
1020 | static int af9005_usb_probe(struct usb_interface *intf, | ||
1021 | const struct usb_device_id *id) | ||
1022 | { | ||
1023 | return dvb_usb_device_init(intf, &af9005_properties, THIS_MODULE, NULL); | ||
1024 | } | ||
1025 | |||
1026 | static struct usb_device_id af9005_usb_table[] = { | ||
1027 | {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9005)}, | ||
1028 | {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE)}, | ||
1029 | {0}, | ||
1030 | }; | ||
1031 | |||
1032 | MODULE_DEVICE_TABLE(usb, af9005_usb_table); | ||
1033 | |||
1034 | static struct dvb_usb_device_properties af9005_properties = { | ||
1035 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
1036 | |||
1037 | .usb_ctrl = DEVICE_SPECIFIC, | ||
1038 | .firmware = "af9005.fw", | ||
1039 | .download_firmware = af9005_download_firmware, | ||
1040 | .no_reconnect = 1, | ||
1041 | |||
1042 | .size_of_priv = sizeof(struct af9005_device_state), | ||
1043 | |||
1044 | .num_adapters = 1, | ||
1045 | .adapter = { | ||
1046 | { | ||
1047 | .caps = | ||
1048 | DVB_USB_ADAP_HAS_PID_FILTER | | ||
1049 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
1050 | .pid_filter_count = 32, | ||
1051 | .pid_filter = af9005_pid_filter, | ||
1052 | /* .pid_filter_ctrl = af9005_pid_filter_control, */ | ||
1053 | .frontend_attach = af9005_frontend_attach, | ||
1054 | /* .tuner_attach = af9005_tuner_attach, */ | ||
1055 | /* parameter for the MPEG2-data transfer */ | ||
1056 | .stream = { | ||
1057 | .type = USB_BULK, | ||
1058 | .count = 10, | ||
1059 | .endpoint = 0x04, | ||
1060 | .u = { | ||
1061 | .bulk = { | ||
1062 | .buffersize = 4096, /* actual size seen is 3948 */ | ||
1063 | } | ||
1064 | } | ||
1065 | }, | ||
1066 | } | ||
1067 | }, | ||
1068 | .power_ctrl = af9005_power_ctrl, | ||
1069 | .identify_state = af9005_identify_state, | ||
1070 | |||
1071 | .i2c_algo = &af9005_i2c_algo, | ||
1072 | |||
1073 | .rc_interval = 200, | ||
1074 | .rc_key_map = NULL, | ||
1075 | .rc_key_map_size = 0, | ||
1076 | .rc_query = af9005_rc_query, | ||
1077 | |||
1078 | .num_device_descs = 2, | ||
1079 | .devices = { | ||
1080 | {.name = "Afatech DVB-T USB1.1 stick", | ||
1081 | .cold_ids = {&af9005_usb_table[0], NULL}, | ||
1082 | .warm_ids = {NULL}, | ||
1083 | }, | ||
1084 | {.name = "TerraTec Cinergy T USB XE", | ||
1085 | .cold_ids = {&af9005_usb_table[1], NULL}, | ||
1086 | .warm_ids = {NULL}, | ||
1087 | }, | ||
1088 | {NULL}, | ||
1089 | } | ||
1090 | }; | ||
1091 | |||
1092 | /* usb specific object needed to register this driver with the usb subsystem */ | ||
1093 | static struct usb_driver af9005_usb_driver = { | ||
1094 | .name = "dvb_usb_af9005", | ||
1095 | .probe = af9005_usb_probe, | ||
1096 | .disconnect = dvb_usb_device_exit, | ||
1097 | .id_table = af9005_usb_table, | ||
1098 | }; | ||
1099 | |||
1100 | /* module stuff */ | ||
1101 | static int __init af9005_usb_module_init(void) | ||
1102 | { | ||
1103 | int result; | ||
1104 | if ((result = usb_register(&af9005_usb_driver))) { | ||
1105 | err("usb_register failed. (%d)", result); | ||
1106 | return result; | ||
1107 | } | ||
1108 | rc_decode = symbol_request(af9005_rc_decode); | ||
1109 | rc_keys = symbol_request(af9005_rc_keys); | ||
1110 | rc_keys_size = symbol_request(af9005_rc_keys_size); | ||
1111 | if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) { | ||
1112 | err("af9005_rc_decode function not found, disabling remote"); | ||
1113 | af9005_properties.rc_query = NULL; | ||
1114 | } else { | ||
1115 | af9005_properties.rc_key_map = rc_keys; | ||
1116 | af9005_properties.rc_key_map_size = *rc_keys_size; | ||
1117 | } | ||
1118 | |||
1119 | return 0; | ||
1120 | } | ||
1121 | |||
1122 | static void __exit af9005_usb_module_exit(void) | ||
1123 | { | ||
1124 | /* release rc decode symbols */ | ||
1125 | if (rc_decode != NULL) | ||
1126 | symbol_put(af9005_rc_decode); | ||
1127 | if (rc_keys != NULL) | ||
1128 | symbol_put(af9005_rc_keys); | ||
1129 | if (rc_keys_size != NULL) | ||
1130 | symbol_put(af9005_rc_keys_size); | ||
1131 | /* deregister this driver from the USB subsystem */ | ||
1132 | usb_deregister(&af9005_usb_driver); | ||
1133 | } | ||
1134 | |||
1135 | module_init(af9005_usb_module_init); | ||
1136 | module_exit(af9005_usb_module_exit); | ||
1137 | |||
1138 | MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>"); | ||
1139 | MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick"); | ||
1140 | MODULE_VERSION("1.0"); | ||
1141 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/dvb/dvb-usb/af9005.h new file mode 100644 index 000000000000..0bc48a012187 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/af9005.h | |||
@@ -0,0 +1,3496 @@ | |||
1 | /* Common header-file of the Linux driver for the Afatech 9005 | ||
2 | * USB1.1 DVB-T receiver. | ||
3 | * | ||
4 | * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) | ||
5 | * | ||
6 | * Thanks to Afatech who kindly provided information. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * see Documentation/dvb/README.dvb-usb for more information | ||
23 | */ | ||
24 | #ifndef _DVB_USB_AF9005_H_ | ||
25 | #define _DVB_USB_AF9005_H_ | ||
26 | |||
27 | #define DVB_USB_LOG_PREFIX "af9005" | ||
28 | #include "dvb-usb.h" | ||
29 | |||
30 | extern int dvb_usb_af9005_debug; | ||
31 | #define deb_info(args...) dprintk(dvb_usb_af9005_debug,0x01,args) | ||
32 | #define deb_xfer(args...) dprintk(dvb_usb_af9005_debug,0x02,args) | ||
33 | #define deb_rc(args...) dprintk(dvb_usb_af9005_debug,0x04,args) | ||
34 | #define deb_reg(args...) dprintk(dvb_usb_af9005_debug,0x08,args) | ||
35 | #define deb_i2c(args...) dprintk(dvb_usb_af9005_debug,0x10,args) | ||
36 | #define deb_fw(args...) dprintk(dvb_usb_af9005_debug,0x20,args) | ||
37 | |||
38 | extern int dvb_usb_af9005_led; | ||
39 | |||
40 | /* firmware */ | ||
41 | #define FW_BULKOUT_SIZE 250 | ||
42 | enum { | ||
43 | FW_CONFIG, | ||
44 | FW_CONFIRM, | ||
45 | FW_BOOT | ||
46 | }; | ||
47 | |||
48 | /* af9005 commands */ | ||
49 | #define AF9005_OFDM_REG 0 | ||
50 | #define AF9005_TUNER_REG 1 | ||
51 | |||
52 | #define AF9005_REGISTER_RW 0x20 | ||
53 | #define AF9005_REGISTER_RW_ACK 0x21 | ||
54 | |||
55 | #define AF9005_CMD_OFDM_REG 0x00 | ||
56 | #define AF9005_CMD_TUNER 0x80 | ||
57 | #define AF9005_CMD_BURST 0x02 | ||
58 | #define AF9005_CMD_AUTOINC 0x04 | ||
59 | #define AF9005_CMD_READ 0x00 | ||
60 | #define AF9005_CMD_WRITE 0x01 | ||
61 | |||
62 | /* af9005 registers */ | ||
63 | #define APO_REG_RESET 0xAEFF | ||
64 | |||
65 | #define APO_REG_I2C_RW_CAN_TUNER 0xF000 | ||
66 | #define APO_REG_I2C_RW_SILICON_TUNER 0xF001 | ||
67 | #define APO_REG_GPIO_RW_SILICON_TUNER 0xFFFE /* also for OFSM */ | ||
68 | #define APO_REG_TRIGGER_OFSM 0xFFFF /* also for OFSM */ | ||
69 | |||
70 | /*********************************************************************** | ||
71 | * Apollo Registers from VLSI * | ||
72 | ***********************************************************************/ | ||
73 | #define xd_p_reg_aagc_inverted_agc 0xA000 | ||
74 | #define reg_aagc_inverted_agc_pos 0 | ||
75 | #define reg_aagc_inverted_agc_len 1 | ||
76 | #define reg_aagc_inverted_agc_lsb 0 | ||
77 | #define xd_p_reg_aagc_sign_only 0xA000 | ||
78 | #define reg_aagc_sign_only_pos 1 | ||
79 | #define reg_aagc_sign_only_len 1 | ||
80 | #define reg_aagc_sign_only_lsb 0 | ||
81 | #define xd_p_reg_aagc_slow_adc_en 0xA000 | ||
82 | #define reg_aagc_slow_adc_en_pos 2 | ||
83 | #define reg_aagc_slow_adc_en_len 1 | ||
84 | #define reg_aagc_slow_adc_en_lsb 0 | ||
85 | #define xd_p_reg_aagc_slow_adc_scale 0xA000 | ||
86 | #define reg_aagc_slow_adc_scale_pos 3 | ||
87 | #define reg_aagc_slow_adc_scale_len 5 | ||
88 | #define reg_aagc_slow_adc_scale_lsb 0 | ||
89 | #define xd_p_reg_aagc_check_slow_adc_lock 0xA001 | ||
90 | #define reg_aagc_check_slow_adc_lock_pos 0 | ||
91 | #define reg_aagc_check_slow_adc_lock_len 1 | ||
92 | #define reg_aagc_check_slow_adc_lock_lsb 0 | ||
93 | #define xd_p_reg_aagc_init_control 0xA001 | ||
94 | #define reg_aagc_init_control_pos 1 | ||
95 | #define reg_aagc_init_control_len 1 | ||
96 | #define reg_aagc_init_control_lsb 0 | ||
97 | #define xd_p_reg_aagc_total_gain_sel 0xA001 | ||
98 | #define reg_aagc_total_gain_sel_pos 2 | ||
99 | #define reg_aagc_total_gain_sel_len 2 | ||
100 | #define reg_aagc_total_gain_sel_lsb 0 | ||
101 | #define xd_p_reg_aagc_out_inv 0xA001 | ||
102 | #define reg_aagc_out_inv_pos 5 | ||
103 | #define reg_aagc_out_inv_len 1 | ||
104 | #define reg_aagc_out_inv_lsb 0 | ||
105 | #define xd_p_reg_aagc_int_en 0xA001 | ||
106 | #define reg_aagc_int_en_pos 6 | ||
107 | #define reg_aagc_int_en_len 1 | ||
108 | #define reg_aagc_int_en_lsb 0 | ||
109 | #define xd_p_reg_aagc_lock_change_flag 0xA001 | ||
110 | #define reg_aagc_lock_change_flag_pos 7 | ||
111 | #define reg_aagc_lock_change_flag_len 1 | ||
112 | #define reg_aagc_lock_change_flag_lsb 0 | ||
113 | #define xd_p_reg_aagc_rf_loop_bw_scale_acquire 0xA002 | ||
114 | #define reg_aagc_rf_loop_bw_scale_acquire_pos 0 | ||
115 | #define reg_aagc_rf_loop_bw_scale_acquire_len 5 | ||
116 | #define reg_aagc_rf_loop_bw_scale_acquire_lsb 0 | ||
117 | #define xd_p_reg_aagc_rf_loop_bw_scale_track 0xA003 | ||
118 | #define reg_aagc_rf_loop_bw_scale_track_pos 0 | ||
119 | #define reg_aagc_rf_loop_bw_scale_track_len 5 | ||
120 | #define reg_aagc_rf_loop_bw_scale_track_lsb 0 | ||
121 | #define xd_p_reg_aagc_if_loop_bw_scale_acquire 0xA004 | ||
122 | #define reg_aagc_if_loop_bw_scale_acquire_pos 0 | ||
123 | #define reg_aagc_if_loop_bw_scale_acquire_len 5 | ||
124 | #define reg_aagc_if_loop_bw_scale_acquire_lsb 0 | ||
125 | #define xd_p_reg_aagc_if_loop_bw_scale_track 0xA005 | ||
126 | #define reg_aagc_if_loop_bw_scale_track_pos 0 | ||
127 | #define reg_aagc_if_loop_bw_scale_track_len 5 | ||
128 | #define reg_aagc_if_loop_bw_scale_track_lsb 0 | ||
129 | #define xd_p_reg_aagc_max_rf_agc_7_0 0xA006 | ||
130 | #define reg_aagc_max_rf_agc_7_0_pos 0 | ||
131 | #define reg_aagc_max_rf_agc_7_0_len 8 | ||
132 | #define reg_aagc_max_rf_agc_7_0_lsb 0 | ||
133 | #define xd_p_reg_aagc_max_rf_agc_9_8 0xA007 | ||
134 | #define reg_aagc_max_rf_agc_9_8_pos 0 | ||
135 | #define reg_aagc_max_rf_agc_9_8_len 2 | ||
136 | #define reg_aagc_max_rf_agc_9_8_lsb 8 | ||
137 | #define xd_p_reg_aagc_min_rf_agc_7_0 0xA008 | ||
138 | #define reg_aagc_min_rf_agc_7_0_pos 0 | ||
139 | #define reg_aagc_min_rf_agc_7_0_len 8 | ||
140 | #define reg_aagc_min_rf_agc_7_0_lsb 0 | ||
141 | #define xd_p_reg_aagc_min_rf_agc_9_8 0xA009 | ||
142 | #define reg_aagc_min_rf_agc_9_8_pos 0 | ||
143 | #define reg_aagc_min_rf_agc_9_8_len 2 | ||
144 | #define reg_aagc_min_rf_agc_9_8_lsb 8 | ||
145 | #define xd_p_reg_aagc_max_if_agc_7_0 0xA00A | ||
146 | #define reg_aagc_max_if_agc_7_0_pos 0 | ||
147 | #define reg_aagc_max_if_agc_7_0_len 8 | ||
148 | #define reg_aagc_max_if_agc_7_0_lsb 0 | ||
149 | #define xd_p_reg_aagc_max_if_agc_9_8 0xA00B | ||
150 | #define reg_aagc_max_if_agc_9_8_pos 0 | ||
151 | #define reg_aagc_max_if_agc_9_8_len 2 | ||
152 | #define reg_aagc_max_if_agc_9_8_lsb 8 | ||
153 | #define xd_p_reg_aagc_min_if_agc_7_0 0xA00C | ||
154 | #define reg_aagc_min_if_agc_7_0_pos 0 | ||
155 | #define reg_aagc_min_if_agc_7_0_len 8 | ||
156 | #define reg_aagc_min_if_agc_7_0_lsb 0 | ||
157 | #define xd_p_reg_aagc_min_if_agc_9_8 0xA00D | ||
158 | #define reg_aagc_min_if_agc_9_8_pos 0 | ||
159 | #define reg_aagc_min_if_agc_9_8_len 2 | ||
160 | #define reg_aagc_min_if_agc_9_8_lsb 8 | ||
161 | #define xd_p_reg_aagc_lock_sample_scale 0xA00E | ||
162 | #define reg_aagc_lock_sample_scale_pos 0 | ||
163 | #define reg_aagc_lock_sample_scale_len 5 | ||
164 | #define reg_aagc_lock_sample_scale_lsb 0 | ||
165 | #define xd_p_reg_aagc_rf_agc_lock_scale_acquire 0xA00F | ||
166 | #define reg_aagc_rf_agc_lock_scale_acquire_pos 0 | ||
167 | #define reg_aagc_rf_agc_lock_scale_acquire_len 3 | ||
168 | #define reg_aagc_rf_agc_lock_scale_acquire_lsb 0 | ||
169 | #define xd_p_reg_aagc_rf_agc_lock_scale_track 0xA00F | ||
170 | #define reg_aagc_rf_agc_lock_scale_track_pos 3 | ||
171 | #define reg_aagc_rf_agc_lock_scale_track_len 3 | ||
172 | #define reg_aagc_rf_agc_lock_scale_track_lsb 0 | ||
173 | #define xd_p_reg_aagc_if_agc_lock_scale_acquire 0xA010 | ||
174 | #define reg_aagc_if_agc_lock_scale_acquire_pos 0 | ||
175 | #define reg_aagc_if_agc_lock_scale_acquire_len 3 | ||
176 | #define reg_aagc_if_agc_lock_scale_acquire_lsb 0 | ||
177 | #define xd_p_reg_aagc_if_agc_lock_scale_track 0xA010 | ||
178 | #define reg_aagc_if_agc_lock_scale_track_pos 3 | ||
179 | #define reg_aagc_if_agc_lock_scale_track_len 3 | ||
180 | #define reg_aagc_if_agc_lock_scale_track_lsb 0 | ||
181 | #define xd_p_reg_aagc_rf_top_numerator_7_0 0xA011 | ||
182 | #define reg_aagc_rf_top_numerator_7_0_pos 0 | ||
183 | #define reg_aagc_rf_top_numerator_7_0_len 8 | ||
184 | #define reg_aagc_rf_top_numerator_7_0_lsb 0 | ||
185 | #define xd_p_reg_aagc_rf_top_numerator_9_8 0xA012 | ||
186 | #define reg_aagc_rf_top_numerator_9_8_pos 0 | ||
187 | #define reg_aagc_rf_top_numerator_9_8_len 2 | ||
188 | #define reg_aagc_rf_top_numerator_9_8_lsb 8 | ||
189 | #define xd_p_reg_aagc_if_top_numerator_7_0 0xA013 | ||
190 | #define reg_aagc_if_top_numerator_7_0_pos 0 | ||
191 | #define reg_aagc_if_top_numerator_7_0_len 8 | ||
192 | #define reg_aagc_if_top_numerator_7_0_lsb 0 | ||
193 | #define xd_p_reg_aagc_if_top_numerator_9_8 0xA014 | ||
194 | #define reg_aagc_if_top_numerator_9_8_pos 0 | ||
195 | #define reg_aagc_if_top_numerator_9_8_len 2 | ||
196 | #define reg_aagc_if_top_numerator_9_8_lsb 8 | ||
197 | #define xd_p_reg_aagc_adc_out_desired_7_0 0xA015 | ||
198 | #define reg_aagc_adc_out_desired_7_0_pos 0 | ||
199 | #define reg_aagc_adc_out_desired_7_0_len 8 | ||
200 | #define reg_aagc_adc_out_desired_7_0_lsb 0 | ||
201 | #define xd_p_reg_aagc_adc_out_desired_8 0xA016 | ||
202 | #define reg_aagc_adc_out_desired_8_pos 0 | ||
203 | #define reg_aagc_adc_out_desired_8_len 1 | ||
204 | #define reg_aagc_adc_out_desired_8_lsb 0 | ||
205 | #define xd_p_reg_aagc_fixed_gain 0xA016 | ||
206 | #define reg_aagc_fixed_gain_pos 3 | ||
207 | #define reg_aagc_fixed_gain_len 1 | ||
208 | #define reg_aagc_fixed_gain_lsb 0 | ||
209 | #define xd_p_reg_aagc_lock_count_th 0xA016 | ||
210 | #define reg_aagc_lock_count_th_pos 4 | ||
211 | #define reg_aagc_lock_count_th_len 4 | ||
212 | #define reg_aagc_lock_count_th_lsb 0 | ||
213 | #define xd_p_reg_aagc_fixed_rf_agc_control_7_0 0xA017 | ||
214 | #define reg_aagc_fixed_rf_agc_control_7_0_pos 0 | ||
215 | #define reg_aagc_fixed_rf_agc_control_7_0_len 8 | ||
216 | #define reg_aagc_fixed_rf_agc_control_7_0_lsb 0 | ||
217 | #define xd_p_reg_aagc_fixed_rf_agc_control_15_8 0xA018 | ||
218 | #define reg_aagc_fixed_rf_agc_control_15_8_pos 0 | ||
219 | #define reg_aagc_fixed_rf_agc_control_15_8_len 8 | ||
220 | #define reg_aagc_fixed_rf_agc_control_15_8_lsb 8 | ||
221 | #define xd_p_reg_aagc_fixed_rf_agc_control_23_16 0xA019 | ||
222 | #define reg_aagc_fixed_rf_agc_control_23_16_pos 0 | ||
223 | #define reg_aagc_fixed_rf_agc_control_23_16_len 8 | ||
224 | #define reg_aagc_fixed_rf_agc_control_23_16_lsb 16 | ||
225 | #define xd_p_reg_aagc_fixed_rf_agc_control_30_24 0xA01A | ||
226 | #define reg_aagc_fixed_rf_agc_control_30_24_pos 0 | ||
227 | #define reg_aagc_fixed_rf_agc_control_30_24_len 7 | ||
228 | #define reg_aagc_fixed_rf_agc_control_30_24_lsb 24 | ||
229 | #define xd_p_reg_aagc_fixed_if_agc_control_7_0 0xA01B | ||
230 | #define reg_aagc_fixed_if_agc_control_7_0_pos 0 | ||
231 | #define reg_aagc_fixed_if_agc_control_7_0_len 8 | ||
232 | #define reg_aagc_fixed_if_agc_control_7_0_lsb 0 | ||
233 | #define xd_p_reg_aagc_fixed_if_agc_control_15_8 0xA01C | ||
234 | #define reg_aagc_fixed_if_agc_control_15_8_pos 0 | ||
235 | #define reg_aagc_fixed_if_agc_control_15_8_len 8 | ||
236 | #define reg_aagc_fixed_if_agc_control_15_8_lsb 8 | ||
237 | #define xd_p_reg_aagc_fixed_if_agc_control_23_16 0xA01D | ||
238 | #define reg_aagc_fixed_if_agc_control_23_16_pos 0 | ||
239 | #define reg_aagc_fixed_if_agc_control_23_16_len 8 | ||
240 | #define reg_aagc_fixed_if_agc_control_23_16_lsb 16 | ||
241 | #define xd_p_reg_aagc_fixed_if_agc_control_30_24 0xA01E | ||
242 | #define reg_aagc_fixed_if_agc_control_30_24_pos 0 | ||
243 | #define reg_aagc_fixed_if_agc_control_30_24_len 7 | ||
244 | #define reg_aagc_fixed_if_agc_control_30_24_lsb 24 | ||
245 | #define xd_p_reg_aagc_rf_agc_unlock_numerator 0xA01F | ||
246 | #define reg_aagc_rf_agc_unlock_numerator_pos 0 | ||
247 | #define reg_aagc_rf_agc_unlock_numerator_len 6 | ||
248 | #define reg_aagc_rf_agc_unlock_numerator_lsb 0 | ||
249 | #define xd_p_reg_aagc_if_agc_unlock_numerator 0xA020 | ||
250 | #define reg_aagc_if_agc_unlock_numerator_pos 0 | ||
251 | #define reg_aagc_if_agc_unlock_numerator_len 6 | ||
252 | #define reg_aagc_if_agc_unlock_numerator_lsb 0 | ||
253 | #define xd_p_reg_unplug_th 0xA021 | ||
254 | #define reg_unplug_th_pos 0 | ||
255 | #define reg_unplug_th_len 8 | ||
256 | #define reg_aagc_rf_x0_lsb 0 | ||
257 | #define xd_p_reg_weak_signal_rfagc_thr 0xA022 | ||
258 | #define reg_weak_signal_rfagc_thr_pos 0 | ||
259 | #define reg_weak_signal_rfagc_thr_len 8 | ||
260 | #define reg_weak_signal_rfagc_thr_lsb 0 | ||
261 | #define xd_p_reg_unplug_rf_gain_th 0xA023 | ||
262 | #define reg_unplug_rf_gain_th_pos 0 | ||
263 | #define reg_unplug_rf_gain_th_len 8 | ||
264 | #define reg_unplug_rf_gain_th_lsb 0 | ||
265 | #define xd_p_reg_unplug_dtop_rf_gain_th 0xA024 | ||
266 | #define reg_unplug_dtop_rf_gain_th_pos 0 | ||
267 | #define reg_unplug_dtop_rf_gain_th_len 8 | ||
268 | #define reg_unplug_dtop_rf_gain_th_lsb 0 | ||
269 | #define xd_p_reg_unplug_dtop_if_gain_th 0xA025 | ||
270 | #define reg_unplug_dtop_if_gain_th_pos 0 | ||
271 | #define reg_unplug_dtop_if_gain_th_len 8 | ||
272 | #define reg_unplug_dtop_if_gain_th_lsb 0 | ||
273 | #define xd_p_reg_top_recover_at_unplug_en 0xA026 | ||
274 | #define reg_top_recover_at_unplug_en_pos 0 | ||
275 | #define reg_top_recover_at_unplug_en_len 1 | ||
276 | #define reg_top_recover_at_unplug_en_lsb 0 | ||
277 | #define xd_p_reg_aagc_rf_x6 0xA027 | ||
278 | #define reg_aagc_rf_x6_pos 0 | ||
279 | #define reg_aagc_rf_x6_len 8 | ||
280 | #define reg_aagc_rf_x6_lsb 0 | ||
281 | #define xd_p_reg_aagc_rf_x7 0xA028 | ||
282 | #define reg_aagc_rf_x7_pos 0 | ||
283 | #define reg_aagc_rf_x7_len 8 | ||
284 | #define reg_aagc_rf_x7_lsb 0 | ||
285 | #define xd_p_reg_aagc_rf_x8 0xA029 | ||
286 | #define reg_aagc_rf_x8_pos 0 | ||
287 | #define reg_aagc_rf_x8_len 8 | ||
288 | #define reg_aagc_rf_x8_lsb 0 | ||
289 | #define xd_p_reg_aagc_rf_x9 0xA02A | ||
290 | #define reg_aagc_rf_x9_pos 0 | ||
291 | #define reg_aagc_rf_x9_len 8 | ||
292 | #define reg_aagc_rf_x9_lsb 0 | ||
293 | #define xd_p_reg_aagc_rf_x10 0xA02B | ||
294 | #define reg_aagc_rf_x10_pos 0 | ||
295 | #define reg_aagc_rf_x10_len 8 | ||
296 | #define reg_aagc_rf_x10_lsb 0 | ||
297 | #define xd_p_reg_aagc_rf_x11 0xA02C | ||
298 | #define reg_aagc_rf_x11_pos 0 | ||
299 | #define reg_aagc_rf_x11_len 8 | ||
300 | #define reg_aagc_rf_x11_lsb 0 | ||
301 | #define xd_p_reg_aagc_rf_x12 0xA02D | ||
302 | #define reg_aagc_rf_x12_pos 0 | ||
303 | #define reg_aagc_rf_x12_len 8 | ||
304 | #define reg_aagc_rf_x12_lsb 0 | ||
305 | #define xd_p_reg_aagc_rf_x13 0xA02E | ||
306 | #define reg_aagc_rf_x13_pos 0 | ||
307 | #define reg_aagc_rf_x13_len 8 | ||
308 | #define reg_aagc_rf_x13_lsb 0 | ||
309 | #define xd_p_reg_aagc_if_x0 0xA02F | ||
310 | #define reg_aagc_if_x0_pos 0 | ||
311 | #define reg_aagc_if_x0_len 8 | ||
312 | #define reg_aagc_if_x0_lsb 0 | ||
313 | #define xd_p_reg_aagc_if_x1 0xA030 | ||
314 | #define reg_aagc_if_x1_pos 0 | ||
315 | #define reg_aagc_if_x1_len 8 | ||
316 | #define reg_aagc_if_x1_lsb 0 | ||
317 | #define xd_p_reg_aagc_if_x2 0xA031 | ||
318 | #define reg_aagc_if_x2_pos 0 | ||
319 | #define reg_aagc_if_x2_len 8 | ||
320 | #define reg_aagc_if_x2_lsb 0 | ||
321 | #define xd_p_reg_aagc_if_x3 0xA032 | ||
322 | #define reg_aagc_if_x3_pos 0 | ||
323 | #define reg_aagc_if_x3_len 8 | ||
324 | #define reg_aagc_if_x3_lsb 0 | ||
325 | #define xd_p_reg_aagc_if_x4 0xA033 | ||
326 | #define reg_aagc_if_x4_pos 0 | ||
327 | #define reg_aagc_if_x4_len 8 | ||
328 | #define reg_aagc_if_x4_lsb 0 | ||
329 | #define xd_p_reg_aagc_if_x5 0xA034 | ||
330 | #define reg_aagc_if_x5_pos 0 | ||
331 | #define reg_aagc_if_x5_len 8 | ||
332 | #define reg_aagc_if_x5_lsb 0 | ||
333 | #define xd_p_reg_aagc_if_x6 0xA035 | ||
334 | #define reg_aagc_if_x6_pos 0 | ||
335 | #define reg_aagc_if_x6_len 8 | ||
336 | #define reg_aagc_if_x6_lsb 0 | ||
337 | #define xd_p_reg_aagc_if_x7 0xA036 | ||
338 | #define reg_aagc_if_x7_pos 0 | ||
339 | #define reg_aagc_if_x7_len 8 | ||
340 | #define reg_aagc_if_x7_lsb 0 | ||
341 | #define xd_p_reg_aagc_if_x8 0xA037 | ||
342 | #define reg_aagc_if_x8_pos 0 | ||
343 | #define reg_aagc_if_x8_len 8 | ||
344 | #define reg_aagc_if_x8_lsb 0 | ||
345 | #define xd_p_reg_aagc_if_x9 0xA038 | ||
346 | #define reg_aagc_if_x9_pos 0 | ||
347 | #define reg_aagc_if_x9_len 8 | ||
348 | #define reg_aagc_if_x9_lsb 0 | ||
349 | #define xd_p_reg_aagc_if_x10 0xA039 | ||
350 | #define reg_aagc_if_x10_pos 0 | ||
351 | #define reg_aagc_if_x10_len 8 | ||
352 | #define reg_aagc_if_x10_lsb 0 | ||
353 | #define xd_p_reg_aagc_if_x11 0xA03A | ||
354 | #define reg_aagc_if_x11_pos 0 | ||
355 | #define reg_aagc_if_x11_len 8 | ||
356 | #define reg_aagc_if_x11_lsb 0 | ||
357 | #define xd_p_reg_aagc_if_x12 0xA03B | ||
358 | #define reg_aagc_if_x12_pos 0 | ||
359 | #define reg_aagc_if_x12_len 8 | ||
360 | #define reg_aagc_if_x12_lsb 0 | ||
361 | #define xd_p_reg_aagc_if_x13 0xA03C | ||
362 | #define reg_aagc_if_x13_pos 0 | ||
363 | #define reg_aagc_if_x13_len 8 | ||
364 | #define reg_aagc_if_x13_lsb 0 | ||
365 | #define xd_p_reg_aagc_min_rf_ctl_8bit_for_dca 0xA03D | ||
366 | #define reg_aagc_min_rf_ctl_8bit_for_dca_pos 0 | ||
367 | #define reg_aagc_min_rf_ctl_8bit_for_dca_len 8 | ||
368 | #define reg_aagc_min_rf_ctl_8bit_for_dca_lsb 0 | ||
369 | #define xd_p_reg_aagc_min_if_ctl_8bit_for_dca 0xA03E | ||
370 | #define reg_aagc_min_if_ctl_8bit_for_dca_pos 0 | ||
371 | #define reg_aagc_min_if_ctl_8bit_for_dca_len 8 | ||
372 | #define reg_aagc_min_if_ctl_8bit_for_dca_lsb 0 | ||
373 | #define xd_r_reg_aagc_total_gain_7_0 0xA070 | ||
374 | #define reg_aagc_total_gain_7_0_pos 0 | ||
375 | #define reg_aagc_total_gain_7_0_len 8 | ||
376 | #define reg_aagc_total_gain_7_0_lsb 0 | ||
377 | #define xd_r_reg_aagc_total_gain_15_8 0xA071 | ||
378 | #define reg_aagc_total_gain_15_8_pos 0 | ||
379 | #define reg_aagc_total_gain_15_8_len 8 | ||
380 | #define reg_aagc_total_gain_15_8_lsb 8 | ||
381 | #define xd_p_reg_aagc_in_sat_cnt_7_0 0xA074 | ||
382 | #define reg_aagc_in_sat_cnt_7_0_pos 0 | ||
383 | #define reg_aagc_in_sat_cnt_7_0_len 8 | ||
384 | #define reg_aagc_in_sat_cnt_7_0_lsb 0 | ||
385 | #define xd_p_reg_aagc_in_sat_cnt_15_8 0xA075 | ||
386 | #define reg_aagc_in_sat_cnt_15_8_pos 0 | ||
387 | #define reg_aagc_in_sat_cnt_15_8_len 8 | ||
388 | #define reg_aagc_in_sat_cnt_15_8_lsb 8 | ||
389 | #define xd_p_reg_aagc_in_sat_cnt_23_16 0xA076 | ||
390 | #define reg_aagc_in_sat_cnt_23_16_pos 0 | ||
391 | #define reg_aagc_in_sat_cnt_23_16_len 8 | ||
392 | #define reg_aagc_in_sat_cnt_23_16_lsb 16 | ||
393 | #define xd_p_reg_aagc_in_sat_cnt_31_24 0xA077 | ||
394 | #define reg_aagc_in_sat_cnt_31_24_pos 0 | ||
395 | #define reg_aagc_in_sat_cnt_31_24_len 8 | ||
396 | #define reg_aagc_in_sat_cnt_31_24_lsb 24 | ||
397 | #define xd_r_reg_aagc_digital_rf_volt_7_0 0xA078 | ||
398 | #define reg_aagc_digital_rf_volt_7_0_pos 0 | ||
399 | #define reg_aagc_digital_rf_volt_7_0_len 8 | ||
400 | #define reg_aagc_digital_rf_volt_7_0_lsb 0 | ||
401 | #define xd_r_reg_aagc_digital_rf_volt_9_8 0xA079 | ||
402 | #define reg_aagc_digital_rf_volt_9_8_pos 0 | ||
403 | #define reg_aagc_digital_rf_volt_9_8_len 2 | ||
404 | #define reg_aagc_digital_rf_volt_9_8_lsb 8 | ||
405 | #define xd_r_reg_aagc_digital_if_volt_7_0 0xA07A | ||
406 | #define reg_aagc_digital_if_volt_7_0_pos 0 | ||
407 | #define reg_aagc_digital_if_volt_7_0_len 8 | ||
408 | #define reg_aagc_digital_if_volt_7_0_lsb 0 | ||
409 | #define xd_r_reg_aagc_digital_if_volt_9_8 0xA07B | ||
410 | #define reg_aagc_digital_if_volt_9_8_pos 0 | ||
411 | #define reg_aagc_digital_if_volt_9_8_len 2 | ||
412 | #define reg_aagc_digital_if_volt_9_8_lsb 8 | ||
413 | #define xd_r_reg_aagc_rf_gain 0xA07C | ||
414 | #define reg_aagc_rf_gain_pos 0 | ||
415 | #define reg_aagc_rf_gain_len 8 | ||
416 | #define reg_aagc_rf_gain_lsb 0 | ||
417 | #define xd_r_reg_aagc_if_gain 0xA07D | ||
418 | #define reg_aagc_if_gain_pos 0 | ||
419 | #define reg_aagc_if_gain_len 8 | ||
420 | #define reg_aagc_if_gain_lsb 0 | ||
421 | #define xd_p_tinr_imp_indicator 0xA080 | ||
422 | #define tinr_imp_indicator_pos 0 | ||
423 | #define tinr_imp_indicator_len 2 | ||
424 | #define tinr_imp_indicator_lsb 0 | ||
425 | #define xd_p_reg_tinr_fifo_size 0xA080 | ||
426 | #define reg_tinr_fifo_size_pos 2 | ||
427 | #define reg_tinr_fifo_size_len 5 | ||
428 | #define reg_tinr_fifo_size_lsb 0 | ||
429 | #define xd_p_reg_tinr_saturation_cnt_th 0xA081 | ||
430 | #define reg_tinr_saturation_cnt_th_pos 0 | ||
431 | #define reg_tinr_saturation_cnt_th_len 4 | ||
432 | #define reg_tinr_saturation_cnt_th_lsb 0 | ||
433 | #define xd_p_reg_tinr_saturation_th_3_0 0xA081 | ||
434 | #define reg_tinr_saturation_th_3_0_pos 4 | ||
435 | #define reg_tinr_saturation_th_3_0_len 4 | ||
436 | #define reg_tinr_saturation_th_3_0_lsb 0 | ||
437 | #define xd_p_reg_tinr_saturation_th_8_4 0xA082 | ||
438 | #define reg_tinr_saturation_th_8_4_pos 0 | ||
439 | #define reg_tinr_saturation_th_8_4_len 5 | ||
440 | #define reg_tinr_saturation_th_8_4_lsb 4 | ||
441 | #define xd_p_reg_tinr_imp_duration_th_2k_7_0 0xA083 | ||
442 | #define reg_tinr_imp_duration_th_2k_7_0_pos 0 | ||
443 | #define reg_tinr_imp_duration_th_2k_7_0_len 8 | ||
444 | #define reg_tinr_imp_duration_th_2k_7_0_lsb 0 | ||
445 | #define xd_p_reg_tinr_imp_duration_th_2k_8 0xA084 | ||
446 | #define reg_tinr_imp_duration_th_2k_8_pos 0 | ||
447 | #define reg_tinr_imp_duration_th_2k_8_len 1 | ||
448 | #define reg_tinr_imp_duration_th_2k_8_lsb 0 | ||
449 | #define xd_p_reg_tinr_imp_duration_th_8k_7_0 0xA085 | ||
450 | #define reg_tinr_imp_duration_th_8k_7_0_pos 0 | ||
451 | #define reg_tinr_imp_duration_th_8k_7_0_len 8 | ||
452 | #define reg_tinr_imp_duration_th_8k_7_0_lsb 0 | ||
453 | #define xd_p_reg_tinr_imp_duration_th_8k_10_8 0xA086 | ||
454 | #define reg_tinr_imp_duration_th_8k_10_8_pos 0 | ||
455 | #define reg_tinr_imp_duration_th_8k_10_8_len 3 | ||
456 | #define reg_tinr_imp_duration_th_8k_10_8_lsb 8 | ||
457 | #define xd_p_reg_tinr_freq_ratio_6m_7_0 0xA087 | ||
458 | #define reg_tinr_freq_ratio_6m_7_0_pos 0 | ||
459 | #define reg_tinr_freq_ratio_6m_7_0_len 8 | ||
460 | #define reg_tinr_freq_ratio_6m_7_0_lsb 0 | ||
461 | #define xd_p_reg_tinr_freq_ratio_6m_12_8 0xA088 | ||
462 | #define reg_tinr_freq_ratio_6m_12_8_pos 0 | ||
463 | #define reg_tinr_freq_ratio_6m_12_8_len 5 | ||
464 | #define reg_tinr_freq_ratio_6m_12_8_lsb 8 | ||
465 | #define xd_p_reg_tinr_freq_ratio_7m_7_0 0xA089 | ||
466 | #define reg_tinr_freq_ratio_7m_7_0_pos 0 | ||
467 | #define reg_tinr_freq_ratio_7m_7_0_len 8 | ||
468 | #define reg_tinr_freq_ratio_7m_7_0_lsb 0 | ||
469 | #define xd_p_reg_tinr_freq_ratio_7m_12_8 0xA08A | ||
470 | #define reg_tinr_freq_ratio_7m_12_8_pos 0 | ||
471 | #define reg_tinr_freq_ratio_7m_12_8_len 5 | ||
472 | #define reg_tinr_freq_ratio_7m_12_8_lsb 8 | ||
473 | #define xd_p_reg_tinr_freq_ratio_8m_7_0 0xA08B | ||
474 | #define reg_tinr_freq_ratio_8m_7_0_pos 0 | ||
475 | #define reg_tinr_freq_ratio_8m_7_0_len 8 | ||
476 | #define reg_tinr_freq_ratio_8m_7_0_lsb 0 | ||
477 | #define xd_p_reg_tinr_freq_ratio_8m_12_8 0xA08C | ||
478 | #define reg_tinr_freq_ratio_8m_12_8_pos 0 | ||
479 | #define reg_tinr_freq_ratio_8m_12_8_len 5 | ||
480 | #define reg_tinr_freq_ratio_8m_12_8_lsb 8 | ||
481 | #define xd_p_reg_tinr_imp_duration_th_low_2k 0xA08D | ||
482 | #define reg_tinr_imp_duration_th_low_2k_pos 0 | ||
483 | #define reg_tinr_imp_duration_th_low_2k_len 8 | ||
484 | #define reg_tinr_imp_duration_th_low_2k_lsb 0 | ||
485 | #define xd_p_reg_tinr_imp_duration_th_low_8k 0xA08E | ||
486 | #define reg_tinr_imp_duration_th_low_8k_pos 0 | ||
487 | #define reg_tinr_imp_duration_th_low_8k_len 8 | ||
488 | #define reg_tinr_imp_duration_th_low_8k_lsb 0 | ||
489 | #define xd_r_reg_tinr_counter_7_0 0xA090 | ||
490 | #define reg_tinr_counter_7_0_pos 0 | ||
491 | #define reg_tinr_counter_7_0_len 8 | ||
492 | #define reg_tinr_counter_7_0_lsb 0 | ||
493 | #define xd_r_reg_tinr_counter_15_8 0xA091 | ||
494 | #define reg_tinr_counter_15_8_pos 0 | ||
495 | #define reg_tinr_counter_15_8_len 8 | ||
496 | #define reg_tinr_counter_15_8_lsb 8 | ||
497 | #define xd_p_reg_tinr_adative_tinr_en 0xA093 | ||
498 | #define reg_tinr_adative_tinr_en_pos 0 | ||
499 | #define reg_tinr_adative_tinr_en_len 1 | ||
500 | #define reg_tinr_adative_tinr_en_lsb 0 | ||
501 | #define xd_p_reg_tinr_peak_fifo_size 0xA093 | ||
502 | #define reg_tinr_peak_fifo_size_pos 1 | ||
503 | #define reg_tinr_peak_fifo_size_len 5 | ||
504 | #define reg_tinr_peak_fifo_size_lsb 0 | ||
505 | #define xd_p_reg_tinr_counter_rst 0xA093 | ||
506 | #define reg_tinr_counter_rst_pos 6 | ||
507 | #define reg_tinr_counter_rst_len 1 | ||
508 | #define reg_tinr_counter_rst_lsb 0 | ||
509 | #define xd_p_reg_tinr_search_period_7_0 0xA094 | ||
510 | #define reg_tinr_search_period_7_0_pos 0 | ||
511 | #define reg_tinr_search_period_7_0_len 8 | ||
512 | #define reg_tinr_search_period_7_0_lsb 0 | ||
513 | #define xd_p_reg_tinr_search_period_15_8 0xA095 | ||
514 | #define reg_tinr_search_period_15_8_pos 0 | ||
515 | #define reg_tinr_search_period_15_8_len 8 | ||
516 | #define reg_tinr_search_period_15_8_lsb 8 | ||
517 | #define xd_p_reg_ccifs_fcw_7_0 0xA0A0 | ||
518 | #define reg_ccifs_fcw_7_0_pos 0 | ||
519 | #define reg_ccifs_fcw_7_0_len 8 | ||
520 | #define reg_ccifs_fcw_7_0_lsb 0 | ||
521 | #define xd_p_reg_ccifs_fcw_12_8 0xA0A1 | ||
522 | #define reg_ccifs_fcw_12_8_pos 0 | ||
523 | #define reg_ccifs_fcw_12_8_len 5 | ||
524 | #define reg_ccifs_fcw_12_8_lsb 8 | ||
525 | #define xd_p_reg_ccifs_spec_inv 0xA0A1 | ||
526 | #define reg_ccifs_spec_inv_pos 5 | ||
527 | #define reg_ccifs_spec_inv_len 1 | ||
528 | #define reg_ccifs_spec_inv_lsb 0 | ||
529 | #define xd_p_reg_gp_trigger 0xA0A2 | ||
530 | #define reg_gp_trigger_pos 0 | ||
531 | #define reg_gp_trigger_len 1 | ||
532 | #define reg_gp_trigger_lsb 0 | ||
533 | #define xd_p_reg_trigger_sel 0xA0A2 | ||
534 | #define reg_trigger_sel_pos 1 | ||
535 | #define reg_trigger_sel_len 2 | ||
536 | #define reg_trigger_sel_lsb 0 | ||
537 | #define xd_p_reg_debug_ofdm 0xA0A2 | ||
538 | #define reg_debug_ofdm_pos 3 | ||
539 | #define reg_debug_ofdm_len 2 | ||
540 | #define reg_debug_ofdm_lsb 0 | ||
541 | #define xd_p_reg_trigger_module_sel 0xA0A3 | ||
542 | #define reg_trigger_module_sel_pos 0 | ||
543 | #define reg_trigger_module_sel_len 6 | ||
544 | #define reg_trigger_module_sel_lsb 0 | ||
545 | #define xd_p_reg_trigger_set_sel 0xA0A4 | ||
546 | #define reg_trigger_set_sel_pos 0 | ||
547 | #define reg_trigger_set_sel_len 6 | ||
548 | #define reg_trigger_set_sel_lsb 0 | ||
549 | #define xd_p_reg_fw_int_mask_n 0xA0A4 | ||
550 | #define reg_fw_int_mask_n_pos 6 | ||
551 | #define reg_fw_int_mask_n_len 1 | ||
552 | #define reg_fw_int_mask_n_lsb 0 | ||
553 | #define xd_p_reg_debug_group 0xA0A5 | ||
554 | #define reg_debug_group_pos 0 | ||
555 | #define reg_debug_group_len 4 | ||
556 | #define reg_debug_group_lsb 0 | ||
557 | #define xd_p_reg_odbg_clk_sel 0xA0A5 | ||
558 | #define reg_odbg_clk_sel_pos 4 | ||
559 | #define reg_odbg_clk_sel_len 2 | ||
560 | #define reg_odbg_clk_sel_lsb 0 | ||
561 | #define xd_p_reg_ccif_sc 0xA0C0 | ||
562 | #define reg_ccif_sc_pos 0 | ||
563 | #define reg_ccif_sc_len 4 | ||
564 | #define reg_ccif_sc_lsb 0 | ||
565 | #define xd_r_reg_ccif_saturate 0xA0C1 | ||
566 | #define reg_ccif_saturate_pos 0 | ||
567 | #define reg_ccif_saturate_len 2 | ||
568 | #define reg_ccif_saturate_lsb 0 | ||
569 | #define xd_r_reg_antif_saturate 0xA0C1 | ||
570 | #define reg_antif_saturate_pos 2 | ||
571 | #define reg_antif_saturate_len 4 | ||
572 | #define reg_antif_saturate_lsb 0 | ||
573 | #define xd_r_reg_acif_saturate 0xA0C2 | ||
574 | #define reg_acif_saturate_pos 0 | ||
575 | #define reg_acif_saturate_len 8 | ||
576 | #define reg_acif_saturate_lsb 0 | ||
577 | #define xd_p_reg_tmr_timer0_threshold_7_0 0xA0C8 | ||
578 | #define reg_tmr_timer0_threshold_7_0_pos 0 | ||
579 | #define reg_tmr_timer0_threshold_7_0_len 8 | ||
580 | #define reg_tmr_timer0_threshold_7_0_lsb 0 | ||
581 | #define xd_p_reg_tmr_timer0_threshold_15_8 0xA0C9 | ||
582 | #define reg_tmr_timer0_threshold_15_8_pos 0 | ||
583 | #define reg_tmr_timer0_threshold_15_8_len 8 | ||
584 | #define reg_tmr_timer0_threshold_15_8_lsb 8 | ||
585 | #define xd_p_reg_tmr_timer0_enable 0xA0CA | ||
586 | #define reg_tmr_timer0_enable_pos 0 | ||
587 | #define reg_tmr_timer0_enable_len 1 | ||
588 | #define reg_tmr_timer0_enable_lsb 0 | ||
589 | #define xd_p_reg_tmr_timer0_clk_sel 0xA0CA | ||
590 | #define reg_tmr_timer0_clk_sel_pos 1 | ||
591 | #define reg_tmr_timer0_clk_sel_len 1 | ||
592 | #define reg_tmr_timer0_clk_sel_lsb 0 | ||
593 | #define xd_p_reg_tmr_timer0_int 0xA0CA | ||
594 | #define reg_tmr_timer0_int_pos 2 | ||
595 | #define reg_tmr_timer0_int_len 1 | ||
596 | #define reg_tmr_timer0_int_lsb 0 | ||
597 | #define xd_p_reg_tmr_timer0_rst 0xA0CA | ||
598 | #define reg_tmr_timer0_rst_pos 3 | ||
599 | #define reg_tmr_timer0_rst_len 1 | ||
600 | #define reg_tmr_timer0_rst_lsb 0 | ||
601 | #define xd_r_reg_tmr_timer0_count_7_0 0xA0CB | ||
602 | #define reg_tmr_timer0_count_7_0_pos 0 | ||
603 | #define reg_tmr_timer0_count_7_0_len 8 | ||
604 | #define reg_tmr_timer0_count_7_0_lsb 0 | ||
605 | #define xd_r_reg_tmr_timer0_count_15_8 0xA0CC | ||
606 | #define reg_tmr_timer0_count_15_8_pos 0 | ||
607 | #define reg_tmr_timer0_count_15_8_len 8 | ||
608 | #define reg_tmr_timer0_count_15_8_lsb 8 | ||
609 | #define xd_p_reg_suspend 0xA0CD | ||
610 | #define reg_suspend_pos 0 | ||
611 | #define reg_suspend_len 1 | ||
612 | #define reg_suspend_lsb 0 | ||
613 | #define xd_p_reg_suspend_rdy 0xA0CD | ||
614 | #define reg_suspend_rdy_pos 1 | ||
615 | #define reg_suspend_rdy_len 1 | ||
616 | #define reg_suspend_rdy_lsb 0 | ||
617 | #define xd_p_reg_resume 0xA0CD | ||
618 | #define reg_resume_pos 2 | ||
619 | #define reg_resume_len 1 | ||
620 | #define reg_resume_lsb 0 | ||
621 | #define xd_p_reg_resume_rdy 0xA0CD | ||
622 | #define reg_resume_rdy_pos 3 | ||
623 | #define reg_resume_rdy_len 1 | ||
624 | #define reg_resume_rdy_lsb 0 | ||
625 | #define xd_p_reg_fmf 0xA0CE | ||
626 | #define reg_fmf_pos 0 | ||
627 | #define reg_fmf_len 8 | ||
628 | #define reg_fmf_lsb 0 | ||
629 | #define xd_p_ccid_accumulate_num_2k_7_0 0xA100 | ||
630 | #define ccid_accumulate_num_2k_7_0_pos 0 | ||
631 | #define ccid_accumulate_num_2k_7_0_len 8 | ||
632 | #define ccid_accumulate_num_2k_7_0_lsb 0 | ||
633 | #define xd_p_ccid_accumulate_num_2k_12_8 0xA101 | ||
634 | #define ccid_accumulate_num_2k_12_8_pos 0 | ||
635 | #define ccid_accumulate_num_2k_12_8_len 5 | ||
636 | #define ccid_accumulate_num_2k_12_8_lsb 8 | ||
637 | #define xd_p_ccid_accumulate_num_8k_7_0 0xA102 | ||
638 | #define ccid_accumulate_num_8k_7_0_pos 0 | ||
639 | #define ccid_accumulate_num_8k_7_0_len 8 | ||
640 | #define ccid_accumulate_num_8k_7_0_lsb 0 | ||
641 | #define xd_p_ccid_accumulate_num_8k_14_8 0xA103 | ||
642 | #define ccid_accumulate_num_8k_14_8_pos 0 | ||
643 | #define ccid_accumulate_num_8k_14_8_len 7 | ||
644 | #define ccid_accumulate_num_8k_14_8_lsb 8 | ||
645 | #define xd_p_ccid_desired_level_0 0xA103 | ||
646 | #define ccid_desired_level_0_pos 7 | ||
647 | #define ccid_desired_level_0_len 1 | ||
648 | #define ccid_desired_level_0_lsb 0 | ||
649 | #define xd_p_ccid_desired_level_8_1 0xA104 | ||
650 | #define ccid_desired_level_8_1_pos 0 | ||
651 | #define ccid_desired_level_8_1_len 8 | ||
652 | #define ccid_desired_level_8_1_lsb 1 | ||
653 | #define xd_p_ccid_apply_delay 0xA105 | ||
654 | #define ccid_apply_delay_pos 0 | ||
655 | #define ccid_apply_delay_len 7 | ||
656 | #define ccid_apply_delay_lsb 0 | ||
657 | #define xd_p_ccid_CCID_Threshold1 0xA106 | ||
658 | #define ccid_CCID_Threshold1_pos 0 | ||
659 | #define ccid_CCID_Threshold1_len 8 | ||
660 | #define ccid_CCID_Threshold1_lsb 0 | ||
661 | #define xd_p_ccid_CCID_Threshold2 0xA107 | ||
662 | #define ccid_CCID_Threshold2_pos 0 | ||
663 | #define ccid_CCID_Threshold2_len 8 | ||
664 | #define ccid_CCID_Threshold2_lsb 0 | ||
665 | #define xd_p_reg_ccid_gain_scale 0xA108 | ||
666 | #define reg_ccid_gain_scale_pos 0 | ||
667 | #define reg_ccid_gain_scale_len 4 | ||
668 | #define reg_ccid_gain_scale_lsb 0 | ||
669 | #define xd_p_reg_ccid2_passband_gain_set 0xA108 | ||
670 | #define reg_ccid2_passband_gain_set_pos 4 | ||
671 | #define reg_ccid2_passband_gain_set_len 4 | ||
672 | #define reg_ccid2_passband_gain_set_lsb 0 | ||
673 | #define xd_r_ccid_multiplier_7_0 0xA109 | ||
674 | #define ccid_multiplier_7_0_pos 0 | ||
675 | #define ccid_multiplier_7_0_len 8 | ||
676 | #define ccid_multiplier_7_0_lsb 0 | ||
677 | #define xd_r_ccid_multiplier_15_8 0xA10A | ||
678 | #define ccid_multiplier_15_8_pos 0 | ||
679 | #define ccid_multiplier_15_8_len 8 | ||
680 | #define ccid_multiplier_15_8_lsb 8 | ||
681 | #define xd_r_ccid_right_shift_bits 0xA10B | ||
682 | #define ccid_right_shift_bits_pos 0 | ||
683 | #define ccid_right_shift_bits_len 4 | ||
684 | #define ccid_right_shift_bits_lsb 0 | ||
685 | #define xd_r_reg_ccid_sx_7_0 0xA10C | ||
686 | #define reg_ccid_sx_7_0_pos 0 | ||
687 | #define reg_ccid_sx_7_0_len 8 | ||
688 | #define reg_ccid_sx_7_0_lsb 0 | ||
689 | #define xd_r_reg_ccid_sx_15_8 0xA10D | ||
690 | #define reg_ccid_sx_15_8_pos 0 | ||
691 | #define reg_ccid_sx_15_8_len 8 | ||
692 | #define reg_ccid_sx_15_8_lsb 8 | ||
693 | #define xd_r_reg_ccid_sx_21_16 0xA10E | ||
694 | #define reg_ccid_sx_21_16_pos 0 | ||
695 | #define reg_ccid_sx_21_16_len 6 | ||
696 | #define reg_ccid_sx_21_16_lsb 16 | ||
697 | #define xd_r_reg_ccid_sy_7_0 0xA110 | ||
698 | #define reg_ccid_sy_7_0_pos 0 | ||
699 | #define reg_ccid_sy_7_0_len 8 | ||
700 | #define reg_ccid_sy_7_0_lsb 0 | ||
701 | #define xd_r_reg_ccid_sy_15_8 0xA111 | ||
702 | #define reg_ccid_sy_15_8_pos 0 | ||
703 | #define reg_ccid_sy_15_8_len 8 | ||
704 | #define reg_ccid_sy_15_8_lsb 8 | ||
705 | #define xd_r_reg_ccid_sy_23_16 0xA112 | ||
706 | #define reg_ccid_sy_23_16_pos 0 | ||
707 | #define reg_ccid_sy_23_16_len 8 | ||
708 | #define reg_ccid_sy_23_16_lsb 16 | ||
709 | #define xd_r_reg_ccid2_sz_7_0 0xA114 | ||
710 | #define reg_ccid2_sz_7_0_pos 0 | ||
711 | #define reg_ccid2_sz_7_0_len 8 | ||
712 | #define reg_ccid2_sz_7_0_lsb 0 | ||
713 | #define xd_r_reg_ccid2_sz_15_8 0xA115 | ||
714 | #define reg_ccid2_sz_15_8_pos 0 | ||
715 | #define reg_ccid2_sz_15_8_len 8 | ||
716 | #define reg_ccid2_sz_15_8_lsb 8 | ||
717 | #define xd_r_reg_ccid2_sz_23_16 0xA116 | ||
718 | #define reg_ccid2_sz_23_16_pos 0 | ||
719 | #define reg_ccid2_sz_23_16_len 8 | ||
720 | #define reg_ccid2_sz_23_16_lsb 16 | ||
721 | #define xd_r_reg_ccid2_sz_25_24 0xA117 | ||
722 | #define reg_ccid2_sz_25_24_pos 0 | ||
723 | #define reg_ccid2_sz_25_24_len 2 | ||
724 | #define reg_ccid2_sz_25_24_lsb 24 | ||
725 | #define xd_r_reg_ccid2_sy_7_0 0xA118 | ||
726 | #define reg_ccid2_sy_7_0_pos 0 | ||
727 | #define reg_ccid2_sy_7_0_len 8 | ||
728 | #define reg_ccid2_sy_7_0_lsb 0 | ||
729 | #define xd_r_reg_ccid2_sy_15_8 0xA119 | ||
730 | #define reg_ccid2_sy_15_8_pos 0 | ||
731 | #define reg_ccid2_sy_15_8_len 8 | ||
732 | #define reg_ccid2_sy_15_8_lsb 8 | ||
733 | #define xd_r_reg_ccid2_sy_23_16 0xA11A | ||
734 | #define reg_ccid2_sy_23_16_pos 0 | ||
735 | #define reg_ccid2_sy_23_16_len 8 | ||
736 | #define reg_ccid2_sy_23_16_lsb 16 | ||
737 | #define xd_r_reg_ccid2_sy_25_24 0xA11B | ||
738 | #define reg_ccid2_sy_25_24_pos 0 | ||
739 | #define reg_ccid2_sy_25_24_len 2 | ||
740 | #define reg_ccid2_sy_25_24_lsb 24 | ||
741 | #define xd_p_dagc1_accumulate_num_2k_7_0 0xA120 | ||
742 | #define dagc1_accumulate_num_2k_7_0_pos 0 | ||
743 | #define dagc1_accumulate_num_2k_7_0_len 8 | ||
744 | #define dagc1_accumulate_num_2k_7_0_lsb 0 | ||
745 | #define xd_p_dagc1_accumulate_num_2k_12_8 0xA121 | ||
746 | #define dagc1_accumulate_num_2k_12_8_pos 0 | ||
747 | #define dagc1_accumulate_num_2k_12_8_len 5 | ||
748 | #define dagc1_accumulate_num_2k_12_8_lsb 8 | ||
749 | #define xd_p_dagc1_accumulate_num_8k_7_0 0xA122 | ||
750 | #define dagc1_accumulate_num_8k_7_0_pos 0 | ||
751 | #define dagc1_accumulate_num_8k_7_0_len 8 | ||
752 | #define dagc1_accumulate_num_8k_7_0_lsb 0 | ||
753 | #define xd_p_dagc1_accumulate_num_8k_14_8 0xA123 | ||
754 | #define dagc1_accumulate_num_8k_14_8_pos 0 | ||
755 | #define dagc1_accumulate_num_8k_14_8_len 7 | ||
756 | #define dagc1_accumulate_num_8k_14_8_lsb 8 | ||
757 | #define xd_p_dagc1_desired_level_0 0xA123 | ||
758 | #define dagc1_desired_level_0_pos 7 | ||
759 | #define dagc1_desired_level_0_len 1 | ||
760 | #define dagc1_desired_level_0_lsb 0 | ||
761 | #define xd_p_dagc1_desired_level_8_1 0xA124 | ||
762 | #define dagc1_desired_level_8_1_pos 0 | ||
763 | #define dagc1_desired_level_8_1_len 8 | ||
764 | #define dagc1_desired_level_8_1_lsb 1 | ||
765 | #define xd_p_dagc1_apply_delay 0xA125 | ||
766 | #define dagc1_apply_delay_pos 0 | ||
767 | #define dagc1_apply_delay_len 7 | ||
768 | #define dagc1_apply_delay_lsb 0 | ||
769 | #define xd_p_dagc1_bypass_scale_ctl 0xA126 | ||
770 | #define dagc1_bypass_scale_ctl_pos 0 | ||
771 | #define dagc1_bypass_scale_ctl_len 2 | ||
772 | #define dagc1_bypass_scale_ctl_lsb 0 | ||
773 | #define xd_p_reg_dagc1_in_sat_cnt_7_0 0xA127 | ||
774 | #define reg_dagc1_in_sat_cnt_7_0_pos 0 | ||
775 | #define reg_dagc1_in_sat_cnt_7_0_len 8 | ||
776 | #define reg_dagc1_in_sat_cnt_7_0_lsb 0 | ||
777 | #define xd_p_reg_dagc1_in_sat_cnt_15_8 0xA128 | ||
778 | #define reg_dagc1_in_sat_cnt_15_8_pos 0 | ||
779 | #define reg_dagc1_in_sat_cnt_15_8_len 8 | ||
780 | #define reg_dagc1_in_sat_cnt_15_8_lsb 8 | ||
781 | #define xd_p_reg_dagc1_in_sat_cnt_23_16 0xA129 | ||
782 | #define reg_dagc1_in_sat_cnt_23_16_pos 0 | ||
783 | #define reg_dagc1_in_sat_cnt_23_16_len 8 | ||
784 | #define reg_dagc1_in_sat_cnt_23_16_lsb 16 | ||
785 | #define xd_p_reg_dagc1_in_sat_cnt_31_24 0xA12A | ||
786 | #define reg_dagc1_in_sat_cnt_31_24_pos 0 | ||
787 | #define reg_dagc1_in_sat_cnt_31_24_len 8 | ||
788 | #define reg_dagc1_in_sat_cnt_31_24_lsb 24 | ||
789 | #define xd_p_reg_dagc1_out_sat_cnt_7_0 0xA12B | ||
790 | #define reg_dagc1_out_sat_cnt_7_0_pos 0 | ||
791 | #define reg_dagc1_out_sat_cnt_7_0_len 8 | ||
792 | #define reg_dagc1_out_sat_cnt_7_0_lsb 0 | ||
793 | #define xd_p_reg_dagc1_out_sat_cnt_15_8 0xA12C | ||
794 | #define reg_dagc1_out_sat_cnt_15_8_pos 0 | ||
795 | #define reg_dagc1_out_sat_cnt_15_8_len 8 | ||
796 | #define reg_dagc1_out_sat_cnt_15_8_lsb 8 | ||
797 | #define xd_p_reg_dagc1_out_sat_cnt_23_16 0xA12D | ||
798 | #define reg_dagc1_out_sat_cnt_23_16_pos 0 | ||
799 | #define reg_dagc1_out_sat_cnt_23_16_len 8 | ||
800 | #define reg_dagc1_out_sat_cnt_23_16_lsb 16 | ||
801 | #define xd_p_reg_dagc1_out_sat_cnt_31_24 0xA12E | ||
802 | #define reg_dagc1_out_sat_cnt_31_24_pos 0 | ||
803 | #define reg_dagc1_out_sat_cnt_31_24_len 8 | ||
804 | #define reg_dagc1_out_sat_cnt_31_24_lsb 24 | ||
805 | #define xd_r_dagc1_multiplier_7_0 0xA136 | ||
806 | #define dagc1_multiplier_7_0_pos 0 | ||
807 | #define dagc1_multiplier_7_0_len 8 | ||
808 | #define dagc1_multiplier_7_0_lsb 0 | ||
809 | #define xd_r_dagc1_multiplier_15_8 0xA137 | ||
810 | #define dagc1_multiplier_15_8_pos 0 | ||
811 | #define dagc1_multiplier_15_8_len 8 | ||
812 | #define dagc1_multiplier_15_8_lsb 8 | ||
813 | #define xd_r_dagc1_right_shift_bits 0xA138 | ||
814 | #define dagc1_right_shift_bits_pos 0 | ||
815 | #define dagc1_right_shift_bits_len 4 | ||
816 | #define dagc1_right_shift_bits_lsb 0 | ||
817 | #define xd_p_reg_bfs_fcw_7_0 0xA140 | ||
818 | #define reg_bfs_fcw_7_0_pos 0 | ||
819 | #define reg_bfs_fcw_7_0_len 8 | ||
820 | #define reg_bfs_fcw_7_0_lsb 0 | ||
821 | #define xd_p_reg_bfs_fcw_15_8 0xA141 | ||
822 | #define reg_bfs_fcw_15_8_pos 0 | ||
823 | #define reg_bfs_fcw_15_8_len 8 | ||
824 | #define reg_bfs_fcw_15_8_lsb 8 | ||
825 | #define xd_p_reg_bfs_fcw_22_16 0xA142 | ||
826 | #define reg_bfs_fcw_22_16_pos 0 | ||
827 | #define reg_bfs_fcw_22_16_len 7 | ||
828 | #define reg_bfs_fcw_22_16_lsb 16 | ||
829 | #define xd_p_reg_antif_sf_7_0 0xA144 | ||
830 | #define reg_antif_sf_7_0_pos 0 | ||
831 | #define reg_antif_sf_7_0_len 8 | ||
832 | #define reg_antif_sf_7_0_lsb 0 | ||
833 | #define xd_p_reg_antif_sf_11_8 0xA145 | ||
834 | #define reg_antif_sf_11_8_pos 0 | ||
835 | #define reg_antif_sf_11_8_len 4 | ||
836 | #define reg_antif_sf_11_8_lsb 8 | ||
837 | #define xd_r_bfs_fcw_q_7_0 0xA150 | ||
838 | #define bfs_fcw_q_7_0_pos 0 | ||
839 | #define bfs_fcw_q_7_0_len 8 | ||
840 | #define bfs_fcw_q_7_0_lsb 0 | ||
841 | #define xd_r_bfs_fcw_q_15_8 0xA151 | ||
842 | #define bfs_fcw_q_15_8_pos 0 | ||
843 | #define bfs_fcw_q_15_8_len 8 | ||
844 | #define bfs_fcw_q_15_8_lsb 8 | ||
845 | #define xd_r_bfs_fcw_q_22_16 0xA152 | ||
846 | #define bfs_fcw_q_22_16_pos 0 | ||
847 | #define bfs_fcw_q_22_16_len 7 | ||
848 | #define bfs_fcw_q_22_16_lsb 16 | ||
849 | #define xd_p_reg_dca_enu 0xA160 | ||
850 | #define reg_dca_enu_pos 0 | ||
851 | #define reg_dca_enu_len 1 | ||
852 | #define reg_dca_enu_lsb 0 | ||
853 | #define xd_p_reg_dca_enl 0xA160 | ||
854 | #define reg_dca_enl_pos 1 | ||
855 | #define reg_dca_enl_len 1 | ||
856 | #define reg_dca_enl_lsb 0 | ||
857 | #define xd_p_reg_dca_lower_chip 0xA160 | ||
858 | #define reg_dca_lower_chip_pos 2 | ||
859 | #define reg_dca_lower_chip_len 1 | ||
860 | #define reg_dca_lower_chip_lsb 0 | ||
861 | #define xd_p_reg_dca_upper_chip 0xA160 | ||
862 | #define reg_dca_upper_chip_pos 3 | ||
863 | #define reg_dca_upper_chip_len 1 | ||
864 | #define reg_dca_upper_chip_lsb 0 | ||
865 | #define xd_p_reg_dca_platch 0xA160 | ||
866 | #define reg_dca_platch_pos 4 | ||
867 | #define reg_dca_platch_len 1 | ||
868 | #define reg_dca_platch_lsb 0 | ||
869 | #define xd_p_reg_dca_th 0xA161 | ||
870 | #define reg_dca_th_pos 0 | ||
871 | #define reg_dca_th_len 5 | ||
872 | #define reg_dca_th_lsb 0 | ||
873 | #define xd_p_reg_dca_scale 0xA162 | ||
874 | #define reg_dca_scale_pos 0 | ||
875 | #define reg_dca_scale_len 4 | ||
876 | #define reg_dca_scale_lsb 0 | ||
877 | #define xd_p_reg_dca_tone_7_0 0xA163 | ||
878 | #define reg_dca_tone_7_0_pos 0 | ||
879 | #define reg_dca_tone_7_0_len 8 | ||
880 | #define reg_dca_tone_7_0_lsb 0 | ||
881 | #define xd_p_reg_dca_tone_12_8 0xA164 | ||
882 | #define reg_dca_tone_12_8_pos 0 | ||
883 | #define reg_dca_tone_12_8_len 5 | ||
884 | #define reg_dca_tone_12_8_lsb 8 | ||
885 | #define xd_p_reg_dca_time_7_0 0xA165 | ||
886 | #define reg_dca_time_7_0_pos 0 | ||
887 | #define reg_dca_time_7_0_len 8 | ||
888 | #define reg_dca_time_7_0_lsb 0 | ||
889 | #define xd_p_reg_dca_time_15_8 0xA166 | ||
890 | #define reg_dca_time_15_8_pos 0 | ||
891 | #define reg_dca_time_15_8_len 8 | ||
892 | #define reg_dca_time_15_8_lsb 8 | ||
893 | #define xd_r_dcasm 0xA167 | ||
894 | #define dcasm_pos 0 | ||
895 | #define dcasm_len 3 | ||
896 | #define dcasm_lsb 0 | ||
897 | #define xd_p_reg_qnt_valuew_7_0 0xA168 | ||
898 | #define reg_qnt_valuew_7_0_pos 0 | ||
899 | #define reg_qnt_valuew_7_0_len 8 | ||
900 | #define reg_qnt_valuew_7_0_lsb 0 | ||
901 | #define xd_p_reg_qnt_valuew_10_8 0xA169 | ||
902 | #define reg_qnt_valuew_10_8_pos 0 | ||
903 | #define reg_qnt_valuew_10_8_len 3 | ||
904 | #define reg_qnt_valuew_10_8_lsb 8 | ||
905 | #define xd_p_dca_sbx_gain_diff_7_0 0xA16A | ||
906 | #define dca_sbx_gain_diff_7_0_pos 0 | ||
907 | #define dca_sbx_gain_diff_7_0_len 8 | ||
908 | #define dca_sbx_gain_diff_7_0_lsb 0 | ||
909 | #define xd_p_dca_sbx_gain_diff_9_8 0xA16B | ||
910 | #define dca_sbx_gain_diff_9_8_pos 0 | ||
911 | #define dca_sbx_gain_diff_9_8_len 2 | ||
912 | #define dca_sbx_gain_diff_9_8_lsb 8 | ||
913 | #define xd_p_reg_dca_stand_alone 0xA16C | ||
914 | #define reg_dca_stand_alone_pos 0 | ||
915 | #define reg_dca_stand_alone_len 1 | ||
916 | #define reg_dca_stand_alone_lsb 0 | ||
917 | #define xd_p_reg_dca_upper_out_en 0xA16C | ||
918 | #define reg_dca_upper_out_en_pos 1 | ||
919 | #define reg_dca_upper_out_en_len 1 | ||
920 | #define reg_dca_upper_out_en_lsb 0 | ||
921 | #define xd_p_reg_dca_rc_en 0xA16C | ||
922 | #define reg_dca_rc_en_pos 2 | ||
923 | #define reg_dca_rc_en_len 1 | ||
924 | #define reg_dca_rc_en_lsb 0 | ||
925 | #define xd_p_reg_dca_retrain_send 0xA16C | ||
926 | #define reg_dca_retrain_send_pos 3 | ||
927 | #define reg_dca_retrain_send_len 1 | ||
928 | #define reg_dca_retrain_send_lsb 0 | ||
929 | #define xd_p_reg_dca_retrain_rec 0xA16C | ||
930 | #define reg_dca_retrain_rec_pos 4 | ||
931 | #define reg_dca_retrain_rec_len 1 | ||
932 | #define reg_dca_retrain_rec_lsb 0 | ||
933 | #define xd_p_reg_dca_api_tpsrdy 0xA16C | ||
934 | #define reg_dca_api_tpsrdy_pos 5 | ||
935 | #define reg_dca_api_tpsrdy_len 1 | ||
936 | #define reg_dca_api_tpsrdy_lsb 0 | ||
937 | #define xd_p_reg_dca_symbol_gap 0xA16D | ||
938 | #define reg_dca_symbol_gap_pos 0 | ||
939 | #define reg_dca_symbol_gap_len 4 | ||
940 | #define reg_dca_symbol_gap_lsb 0 | ||
941 | #define xd_p_reg_qnt_nfvaluew_7_0 0xA16E | ||
942 | #define reg_qnt_nfvaluew_7_0_pos 0 | ||
943 | #define reg_qnt_nfvaluew_7_0_len 8 | ||
944 | #define reg_qnt_nfvaluew_7_0_lsb 0 | ||
945 | #define xd_p_reg_qnt_nfvaluew_10_8 0xA16F | ||
946 | #define reg_qnt_nfvaluew_10_8_pos 0 | ||
947 | #define reg_qnt_nfvaluew_10_8_len 3 | ||
948 | #define reg_qnt_nfvaluew_10_8_lsb 8 | ||
949 | #define xd_p_reg_qnt_flatness_thr_7_0 0xA170 | ||
950 | #define reg_qnt_flatness_thr_7_0_pos 0 | ||
951 | #define reg_qnt_flatness_thr_7_0_len 8 | ||
952 | #define reg_qnt_flatness_thr_7_0_lsb 0 | ||
953 | #define xd_p_reg_qnt_flatness_thr_9_8 0xA171 | ||
954 | #define reg_qnt_flatness_thr_9_8_pos 0 | ||
955 | #define reg_qnt_flatness_thr_9_8_len 2 | ||
956 | #define reg_qnt_flatness_thr_9_8_lsb 8 | ||
957 | #define xd_p_reg_dca_tone_idx_5_0 0xA171 | ||
958 | #define reg_dca_tone_idx_5_0_pos 2 | ||
959 | #define reg_dca_tone_idx_5_0_len 6 | ||
960 | #define reg_dca_tone_idx_5_0_lsb 0 | ||
961 | #define xd_p_reg_dca_tone_idx_12_6 0xA172 | ||
962 | #define reg_dca_tone_idx_12_6_pos 0 | ||
963 | #define reg_dca_tone_idx_12_6_len 7 | ||
964 | #define reg_dca_tone_idx_12_6_lsb 6 | ||
965 | #define xd_p_reg_dca_data_vld 0xA173 | ||
966 | #define reg_dca_data_vld_pos 0 | ||
967 | #define reg_dca_data_vld_len 1 | ||
968 | #define reg_dca_data_vld_lsb 0 | ||
969 | #define xd_p_reg_dca_read_update 0xA173 | ||
970 | #define reg_dca_read_update_pos 1 | ||
971 | #define reg_dca_read_update_len 1 | ||
972 | #define reg_dca_read_update_lsb 0 | ||
973 | #define xd_r_reg_dca_data_re_5_0 0xA173 | ||
974 | #define reg_dca_data_re_5_0_pos 2 | ||
975 | #define reg_dca_data_re_5_0_len 6 | ||
976 | #define reg_dca_data_re_5_0_lsb 0 | ||
977 | #define xd_r_reg_dca_data_re_10_6 0xA174 | ||
978 | #define reg_dca_data_re_10_6_pos 0 | ||
979 | #define reg_dca_data_re_10_6_len 5 | ||
980 | #define reg_dca_data_re_10_6_lsb 6 | ||
981 | #define xd_r_reg_dca_data_im_7_0 0xA175 | ||
982 | #define reg_dca_data_im_7_0_pos 0 | ||
983 | #define reg_dca_data_im_7_0_len 8 | ||
984 | #define reg_dca_data_im_7_0_lsb 0 | ||
985 | #define xd_r_reg_dca_data_im_10_8 0xA176 | ||
986 | #define reg_dca_data_im_10_8_pos 0 | ||
987 | #define reg_dca_data_im_10_8_len 3 | ||
988 | #define reg_dca_data_im_10_8_lsb 8 | ||
989 | #define xd_r_reg_dca_data_h2_7_0 0xA178 | ||
990 | #define reg_dca_data_h2_7_0_pos 0 | ||
991 | #define reg_dca_data_h2_7_0_len 8 | ||
992 | #define reg_dca_data_h2_7_0_lsb 0 | ||
993 | #define xd_r_reg_dca_data_h2_9_8 0xA179 | ||
994 | #define reg_dca_data_h2_9_8_pos 0 | ||
995 | #define reg_dca_data_h2_9_8_len 2 | ||
996 | #define reg_dca_data_h2_9_8_lsb 8 | ||
997 | #define xd_p_reg_f_adc_7_0 0xA180 | ||
998 | #define reg_f_adc_7_0_pos 0 | ||
999 | #define reg_f_adc_7_0_len 8 | ||
1000 | #define reg_f_adc_7_0_lsb 0 | ||
1001 | #define xd_p_reg_f_adc_15_8 0xA181 | ||
1002 | #define reg_f_adc_15_8_pos 0 | ||
1003 | #define reg_f_adc_15_8_len 8 | ||
1004 | #define reg_f_adc_15_8_lsb 8 | ||
1005 | #define xd_p_reg_f_adc_23_16 0xA182 | ||
1006 | #define reg_f_adc_23_16_pos 0 | ||
1007 | #define reg_f_adc_23_16_len 8 | ||
1008 | #define reg_f_adc_23_16_lsb 16 | ||
1009 | #define xd_r_intp_mu_7_0 0xA190 | ||
1010 | #define intp_mu_7_0_pos 0 | ||
1011 | #define intp_mu_7_0_len 8 | ||
1012 | #define intp_mu_7_0_lsb 0 | ||
1013 | #define xd_r_intp_mu_15_8 0xA191 | ||
1014 | #define intp_mu_15_8_pos 0 | ||
1015 | #define intp_mu_15_8_len 8 | ||
1016 | #define intp_mu_15_8_lsb 8 | ||
1017 | #define xd_r_intp_mu_19_16 0xA192 | ||
1018 | #define intp_mu_19_16_pos 0 | ||
1019 | #define intp_mu_19_16_len 4 | ||
1020 | #define intp_mu_19_16_lsb 16 | ||
1021 | #define xd_p_reg_agc_rst 0xA1A0 | ||
1022 | #define reg_agc_rst_pos 0 | ||
1023 | #define reg_agc_rst_len 1 | ||
1024 | #define reg_agc_rst_lsb 0 | ||
1025 | #define xd_p_rf_agc_en 0xA1A0 | ||
1026 | #define rf_agc_en_pos 1 | ||
1027 | #define rf_agc_en_len 1 | ||
1028 | #define rf_agc_en_lsb 0 | ||
1029 | #define xd_p_rf_agc_dis 0xA1A0 | ||
1030 | #define rf_agc_dis_pos 2 | ||
1031 | #define rf_agc_dis_len 1 | ||
1032 | #define rf_agc_dis_lsb 0 | ||
1033 | #define xd_p_if_agc_rst 0xA1A0 | ||
1034 | #define if_agc_rst_pos 3 | ||
1035 | #define if_agc_rst_len 1 | ||
1036 | #define if_agc_rst_lsb 0 | ||
1037 | #define xd_p_if_agc_en 0xA1A0 | ||
1038 | #define if_agc_en_pos 4 | ||
1039 | #define if_agc_en_len 1 | ||
1040 | #define if_agc_en_lsb 0 | ||
1041 | #define xd_p_if_agc_dis 0xA1A0 | ||
1042 | #define if_agc_dis_pos 5 | ||
1043 | #define if_agc_dis_len 1 | ||
1044 | #define if_agc_dis_lsb 0 | ||
1045 | #define xd_p_agc_lock 0xA1A0 | ||
1046 | #define agc_lock_pos 6 | ||
1047 | #define agc_lock_len 1 | ||
1048 | #define agc_lock_lsb 0 | ||
1049 | #define xd_p_reg_tinr_rst 0xA1A1 | ||
1050 | #define reg_tinr_rst_pos 0 | ||
1051 | #define reg_tinr_rst_len 1 | ||
1052 | #define reg_tinr_rst_lsb 0 | ||
1053 | #define xd_p_reg_tinr_en 0xA1A1 | ||
1054 | #define reg_tinr_en_pos 1 | ||
1055 | #define reg_tinr_en_len 1 | ||
1056 | #define reg_tinr_en_lsb 0 | ||
1057 | #define xd_p_reg_ccifs_en 0xA1A2 | ||
1058 | #define reg_ccifs_en_pos 0 | ||
1059 | #define reg_ccifs_en_len 1 | ||
1060 | #define reg_ccifs_en_lsb 0 | ||
1061 | #define xd_p_reg_ccifs_dis 0xA1A2 | ||
1062 | #define reg_ccifs_dis_pos 1 | ||
1063 | #define reg_ccifs_dis_len 1 | ||
1064 | #define reg_ccifs_dis_lsb 0 | ||
1065 | #define xd_p_reg_ccifs_rst 0xA1A2 | ||
1066 | #define reg_ccifs_rst_pos 2 | ||
1067 | #define reg_ccifs_rst_len 1 | ||
1068 | #define reg_ccifs_rst_lsb 0 | ||
1069 | #define xd_p_reg_ccifs_byp 0xA1A2 | ||
1070 | #define reg_ccifs_byp_pos 3 | ||
1071 | #define reg_ccifs_byp_len 1 | ||
1072 | #define reg_ccifs_byp_lsb 0 | ||
1073 | #define xd_p_reg_ccif_en 0xA1A3 | ||
1074 | #define reg_ccif_en_pos 0 | ||
1075 | #define reg_ccif_en_len 1 | ||
1076 | #define reg_ccif_en_lsb 0 | ||
1077 | #define xd_p_reg_ccif_dis 0xA1A3 | ||
1078 | #define reg_ccif_dis_pos 1 | ||
1079 | #define reg_ccif_dis_len 1 | ||
1080 | #define reg_ccif_dis_lsb 0 | ||
1081 | #define xd_p_reg_ccif_rst 0xA1A3 | ||
1082 | #define reg_ccif_rst_pos 2 | ||
1083 | #define reg_ccif_rst_len 1 | ||
1084 | #define reg_ccif_rst_lsb 0 | ||
1085 | #define xd_p_reg_ccif_byp 0xA1A3 | ||
1086 | #define reg_ccif_byp_pos 3 | ||
1087 | #define reg_ccif_byp_len 1 | ||
1088 | #define reg_ccif_byp_lsb 0 | ||
1089 | #define xd_p_dagc1_rst 0xA1A4 | ||
1090 | #define dagc1_rst_pos 0 | ||
1091 | #define dagc1_rst_len 1 | ||
1092 | #define dagc1_rst_lsb 0 | ||
1093 | #define xd_p_dagc1_en 0xA1A4 | ||
1094 | #define dagc1_en_pos 1 | ||
1095 | #define dagc1_en_len 1 | ||
1096 | #define dagc1_en_lsb 0 | ||
1097 | #define xd_p_dagc1_mode 0xA1A4 | ||
1098 | #define dagc1_mode_pos 2 | ||
1099 | #define dagc1_mode_len 2 | ||
1100 | #define dagc1_mode_lsb 0 | ||
1101 | #define xd_p_dagc1_done 0xA1A4 | ||
1102 | #define dagc1_done_pos 4 | ||
1103 | #define dagc1_done_len 1 | ||
1104 | #define dagc1_done_lsb 0 | ||
1105 | #define xd_p_ccid_rst 0xA1A5 | ||
1106 | #define ccid_rst_pos 0 | ||
1107 | #define ccid_rst_len 1 | ||
1108 | #define ccid_rst_lsb 0 | ||
1109 | #define xd_p_ccid_en 0xA1A5 | ||
1110 | #define ccid_en_pos 1 | ||
1111 | #define ccid_en_len 1 | ||
1112 | #define ccid_en_lsb 0 | ||
1113 | #define xd_p_ccid_mode 0xA1A5 | ||
1114 | #define ccid_mode_pos 2 | ||
1115 | #define ccid_mode_len 2 | ||
1116 | #define ccid_mode_lsb 0 | ||
1117 | #define xd_p_ccid_done 0xA1A5 | ||
1118 | #define ccid_done_pos 4 | ||
1119 | #define ccid_done_len 1 | ||
1120 | #define ccid_done_lsb 0 | ||
1121 | #define xd_r_ccid_deted 0xA1A5 | ||
1122 | #define ccid_deted_pos 5 | ||
1123 | #define ccid_deted_len 1 | ||
1124 | #define ccid_deted_lsb 0 | ||
1125 | #define xd_p_ccid2_en 0xA1A5 | ||
1126 | #define ccid2_en_pos 6 | ||
1127 | #define ccid2_en_len 1 | ||
1128 | #define ccid2_en_lsb 0 | ||
1129 | #define xd_p_ccid2_done 0xA1A5 | ||
1130 | #define ccid2_done_pos 7 | ||
1131 | #define ccid2_done_len 1 | ||
1132 | #define ccid2_done_lsb 0 | ||
1133 | #define xd_p_reg_bfs_en 0xA1A6 | ||
1134 | #define reg_bfs_en_pos 0 | ||
1135 | #define reg_bfs_en_len 1 | ||
1136 | #define reg_bfs_en_lsb 0 | ||
1137 | #define xd_p_reg_bfs_dis 0xA1A6 | ||
1138 | #define reg_bfs_dis_pos 1 | ||
1139 | #define reg_bfs_dis_len 1 | ||
1140 | #define reg_bfs_dis_lsb 0 | ||
1141 | #define xd_p_reg_bfs_rst 0xA1A6 | ||
1142 | #define reg_bfs_rst_pos 2 | ||
1143 | #define reg_bfs_rst_len 1 | ||
1144 | #define reg_bfs_rst_lsb 0 | ||
1145 | #define xd_p_reg_bfs_byp 0xA1A6 | ||
1146 | #define reg_bfs_byp_pos 3 | ||
1147 | #define reg_bfs_byp_len 1 | ||
1148 | #define reg_bfs_byp_lsb 0 | ||
1149 | #define xd_p_reg_antif_en 0xA1A7 | ||
1150 | #define reg_antif_en_pos 0 | ||
1151 | #define reg_antif_en_len 1 | ||
1152 | #define reg_antif_en_lsb 0 | ||
1153 | #define xd_p_reg_antif_dis 0xA1A7 | ||
1154 | #define reg_antif_dis_pos 1 | ||
1155 | #define reg_antif_dis_len 1 | ||
1156 | #define reg_antif_dis_lsb 0 | ||
1157 | #define xd_p_reg_antif_rst 0xA1A7 | ||
1158 | #define reg_antif_rst_pos 2 | ||
1159 | #define reg_antif_rst_len 1 | ||
1160 | #define reg_antif_rst_lsb 0 | ||
1161 | #define xd_p_reg_antif_byp 0xA1A7 | ||
1162 | #define reg_antif_byp_pos 3 | ||
1163 | #define reg_antif_byp_len 1 | ||
1164 | #define reg_antif_byp_lsb 0 | ||
1165 | #define xd_p_intp_en 0xA1A8 | ||
1166 | #define intp_en_pos 0 | ||
1167 | #define intp_en_len 1 | ||
1168 | #define intp_en_lsb 0 | ||
1169 | #define xd_p_intp_dis 0xA1A8 | ||
1170 | #define intp_dis_pos 1 | ||
1171 | #define intp_dis_len 1 | ||
1172 | #define intp_dis_lsb 0 | ||
1173 | #define xd_p_intp_rst 0xA1A8 | ||
1174 | #define intp_rst_pos 2 | ||
1175 | #define intp_rst_len 1 | ||
1176 | #define intp_rst_lsb 0 | ||
1177 | #define xd_p_intp_byp 0xA1A8 | ||
1178 | #define intp_byp_pos 3 | ||
1179 | #define intp_byp_len 1 | ||
1180 | #define intp_byp_lsb 0 | ||
1181 | #define xd_p_reg_acif_en 0xA1A9 | ||
1182 | #define reg_acif_en_pos 0 | ||
1183 | #define reg_acif_en_len 1 | ||
1184 | #define reg_acif_en_lsb 0 | ||
1185 | #define xd_p_reg_acif_dis 0xA1A9 | ||
1186 | #define reg_acif_dis_pos 1 | ||
1187 | #define reg_acif_dis_len 1 | ||
1188 | #define reg_acif_dis_lsb 0 | ||
1189 | #define xd_p_reg_acif_rst 0xA1A9 | ||
1190 | #define reg_acif_rst_pos 2 | ||
1191 | #define reg_acif_rst_len 1 | ||
1192 | #define reg_acif_rst_lsb 0 | ||
1193 | #define xd_p_reg_acif_byp 0xA1A9 | ||
1194 | #define reg_acif_byp_pos 3 | ||
1195 | #define reg_acif_byp_len 1 | ||
1196 | #define reg_acif_byp_lsb 0 | ||
1197 | #define xd_p_reg_acif_sync_mode 0xA1A9 | ||
1198 | #define reg_acif_sync_mode_pos 4 | ||
1199 | #define reg_acif_sync_mode_len 1 | ||
1200 | #define reg_acif_sync_mode_lsb 0 | ||
1201 | #define xd_p_dagc2_rst 0xA1AA | ||
1202 | #define dagc2_rst_pos 0 | ||
1203 | #define dagc2_rst_len 1 | ||
1204 | #define dagc2_rst_lsb 0 | ||
1205 | #define xd_p_dagc2_en 0xA1AA | ||
1206 | #define dagc2_en_pos 1 | ||
1207 | #define dagc2_en_len 1 | ||
1208 | #define dagc2_en_lsb 0 | ||
1209 | #define xd_p_dagc2_mode 0xA1AA | ||
1210 | #define dagc2_mode_pos 2 | ||
1211 | #define dagc2_mode_len 2 | ||
1212 | #define dagc2_mode_lsb 0 | ||
1213 | #define xd_p_dagc2_done 0xA1AA | ||
1214 | #define dagc2_done_pos 4 | ||
1215 | #define dagc2_done_len 1 | ||
1216 | #define dagc2_done_lsb 0 | ||
1217 | #define xd_p_reg_dca_en 0xA1AB | ||
1218 | #define reg_dca_en_pos 0 | ||
1219 | #define reg_dca_en_len 1 | ||
1220 | #define reg_dca_en_lsb 0 | ||
1221 | #define xd_p_dagc2_accumulate_num_2k_7_0 0xA1C0 | ||
1222 | #define dagc2_accumulate_num_2k_7_0_pos 0 | ||
1223 | #define dagc2_accumulate_num_2k_7_0_len 8 | ||
1224 | #define dagc2_accumulate_num_2k_7_0_lsb 0 | ||
1225 | #define xd_p_dagc2_accumulate_num_2k_12_8 0xA1C1 | ||
1226 | #define dagc2_accumulate_num_2k_12_8_pos 0 | ||
1227 | #define dagc2_accumulate_num_2k_12_8_len 5 | ||
1228 | #define dagc2_accumulate_num_2k_12_8_lsb 8 | ||
1229 | #define xd_p_dagc2_accumulate_num_8k_7_0 0xA1C2 | ||
1230 | #define dagc2_accumulate_num_8k_7_0_pos 0 | ||
1231 | #define dagc2_accumulate_num_8k_7_0_len 8 | ||
1232 | #define dagc2_accumulate_num_8k_7_0_lsb 0 | ||
1233 | #define xd_p_dagc2_accumulate_num_8k_12_8 0xA1C3 | ||
1234 | #define dagc2_accumulate_num_8k_12_8_pos 0 | ||
1235 | #define dagc2_accumulate_num_8k_12_8_len 5 | ||
1236 | #define dagc2_accumulate_num_8k_12_8_lsb 8 | ||
1237 | #define xd_p_dagc2_desired_level_2_0 0xA1C3 | ||
1238 | #define dagc2_desired_level_2_0_pos 5 | ||
1239 | #define dagc2_desired_level_2_0_len 3 | ||
1240 | #define dagc2_desired_level_2_0_lsb 0 | ||
1241 | #define xd_p_dagc2_desired_level_8_3 0xA1C4 | ||
1242 | #define dagc2_desired_level_8_3_pos 0 | ||
1243 | #define dagc2_desired_level_8_3_len 6 | ||
1244 | #define dagc2_desired_level_8_3_lsb 3 | ||
1245 | #define xd_p_dagc2_apply_delay 0xA1C5 | ||
1246 | #define dagc2_apply_delay_pos 0 | ||
1247 | #define dagc2_apply_delay_len 7 | ||
1248 | #define dagc2_apply_delay_lsb 0 | ||
1249 | #define xd_p_dagc2_bypass_scale_ctl 0xA1C6 | ||
1250 | #define dagc2_bypass_scale_ctl_pos 0 | ||
1251 | #define dagc2_bypass_scale_ctl_len 3 | ||
1252 | #define dagc2_bypass_scale_ctl_lsb 0 | ||
1253 | #define xd_p_dagc2_programmable_shift1 0xA1C7 | ||
1254 | #define dagc2_programmable_shift1_pos 0 | ||
1255 | #define dagc2_programmable_shift1_len 8 | ||
1256 | #define dagc2_programmable_shift1_lsb 0 | ||
1257 | #define xd_p_dagc2_programmable_shift2 0xA1C8 | ||
1258 | #define dagc2_programmable_shift2_pos 0 | ||
1259 | #define dagc2_programmable_shift2_len 8 | ||
1260 | #define dagc2_programmable_shift2_lsb 0 | ||
1261 | #define xd_p_reg_dagc2_in_sat_cnt_7_0 0xA1C9 | ||
1262 | #define reg_dagc2_in_sat_cnt_7_0_pos 0 | ||
1263 | #define reg_dagc2_in_sat_cnt_7_0_len 8 | ||
1264 | #define reg_dagc2_in_sat_cnt_7_0_lsb 0 | ||
1265 | #define xd_p_reg_dagc2_in_sat_cnt_15_8 0xA1CA | ||
1266 | #define reg_dagc2_in_sat_cnt_15_8_pos 0 | ||
1267 | #define reg_dagc2_in_sat_cnt_15_8_len 8 | ||
1268 | #define reg_dagc2_in_sat_cnt_15_8_lsb 8 | ||
1269 | #define xd_p_reg_dagc2_in_sat_cnt_23_16 0xA1CB | ||
1270 | #define reg_dagc2_in_sat_cnt_23_16_pos 0 | ||
1271 | #define reg_dagc2_in_sat_cnt_23_16_len 8 | ||
1272 | #define reg_dagc2_in_sat_cnt_23_16_lsb 16 | ||
1273 | #define xd_p_reg_dagc2_in_sat_cnt_31_24 0xA1CC | ||
1274 | #define reg_dagc2_in_sat_cnt_31_24_pos 0 | ||
1275 | #define reg_dagc2_in_sat_cnt_31_24_len 8 | ||
1276 | #define reg_dagc2_in_sat_cnt_31_24_lsb 24 | ||
1277 | #define xd_p_reg_dagc2_out_sat_cnt_7_0 0xA1CD | ||
1278 | #define reg_dagc2_out_sat_cnt_7_0_pos 0 | ||
1279 | #define reg_dagc2_out_sat_cnt_7_0_len 8 | ||
1280 | #define reg_dagc2_out_sat_cnt_7_0_lsb 0 | ||
1281 | #define xd_p_reg_dagc2_out_sat_cnt_15_8 0xA1CE | ||
1282 | #define reg_dagc2_out_sat_cnt_15_8_pos 0 | ||
1283 | #define reg_dagc2_out_sat_cnt_15_8_len 8 | ||
1284 | #define reg_dagc2_out_sat_cnt_15_8_lsb 8 | ||
1285 | #define xd_p_reg_dagc2_out_sat_cnt_23_16 0xA1CF | ||
1286 | #define reg_dagc2_out_sat_cnt_23_16_pos 0 | ||
1287 | #define reg_dagc2_out_sat_cnt_23_16_len 8 | ||
1288 | #define reg_dagc2_out_sat_cnt_23_16_lsb 16 | ||
1289 | #define xd_p_reg_dagc2_out_sat_cnt_31_24 0xA1D0 | ||
1290 | #define reg_dagc2_out_sat_cnt_31_24_pos 0 | ||
1291 | #define reg_dagc2_out_sat_cnt_31_24_len 8 | ||
1292 | #define reg_dagc2_out_sat_cnt_31_24_lsb 24 | ||
1293 | #define xd_r_dagc2_multiplier_7_0 0xA1D6 | ||
1294 | #define dagc2_multiplier_7_0_pos 0 | ||
1295 | #define dagc2_multiplier_7_0_len 8 | ||
1296 | #define dagc2_multiplier_7_0_lsb 0 | ||
1297 | #define xd_r_dagc2_multiplier_15_8 0xA1D7 | ||
1298 | #define dagc2_multiplier_15_8_pos 0 | ||
1299 | #define dagc2_multiplier_15_8_len 8 | ||
1300 | #define dagc2_multiplier_15_8_lsb 8 | ||
1301 | #define xd_r_dagc2_right_shift_bits 0xA1D8 | ||
1302 | #define dagc2_right_shift_bits_pos 0 | ||
1303 | #define dagc2_right_shift_bits_len 4 | ||
1304 | #define dagc2_right_shift_bits_lsb 0 | ||
1305 | #define xd_p_cfoe_NS_coeff1_7_0 0xA200 | ||
1306 | #define cfoe_NS_coeff1_7_0_pos 0 | ||
1307 | #define cfoe_NS_coeff1_7_0_len 8 | ||
1308 | #define cfoe_NS_coeff1_7_0_lsb 0 | ||
1309 | #define xd_p_cfoe_NS_coeff1_15_8 0xA201 | ||
1310 | #define cfoe_NS_coeff1_15_8_pos 0 | ||
1311 | #define cfoe_NS_coeff1_15_8_len 8 | ||
1312 | #define cfoe_NS_coeff1_15_8_lsb 8 | ||
1313 | #define xd_p_cfoe_NS_coeff1_23_16 0xA202 | ||
1314 | #define cfoe_NS_coeff1_23_16_pos 0 | ||
1315 | #define cfoe_NS_coeff1_23_16_len 8 | ||
1316 | #define cfoe_NS_coeff1_23_16_lsb 16 | ||
1317 | #define xd_p_cfoe_NS_coeff1_25_24 0xA203 | ||
1318 | #define cfoe_NS_coeff1_25_24_pos 0 | ||
1319 | #define cfoe_NS_coeff1_25_24_len 2 | ||
1320 | #define cfoe_NS_coeff1_25_24_lsb 24 | ||
1321 | #define xd_p_cfoe_NS_coeff2_5_0 0xA203 | ||
1322 | #define cfoe_NS_coeff2_5_0_pos 2 | ||
1323 | #define cfoe_NS_coeff2_5_0_len 6 | ||
1324 | #define cfoe_NS_coeff2_5_0_lsb 0 | ||
1325 | #define xd_p_cfoe_NS_coeff2_13_6 0xA204 | ||
1326 | #define cfoe_NS_coeff2_13_6_pos 0 | ||
1327 | #define cfoe_NS_coeff2_13_6_len 8 | ||
1328 | #define cfoe_NS_coeff2_13_6_lsb 6 | ||
1329 | #define xd_p_cfoe_NS_coeff2_21_14 0xA205 | ||
1330 | #define cfoe_NS_coeff2_21_14_pos 0 | ||
1331 | #define cfoe_NS_coeff2_21_14_len 8 | ||
1332 | #define cfoe_NS_coeff2_21_14_lsb 14 | ||
1333 | #define xd_p_cfoe_NS_coeff2_24_22 0xA206 | ||
1334 | #define cfoe_NS_coeff2_24_22_pos 0 | ||
1335 | #define cfoe_NS_coeff2_24_22_len 3 | ||
1336 | #define cfoe_NS_coeff2_24_22_lsb 22 | ||
1337 | #define xd_p_cfoe_lf_c1_4_0 0xA206 | ||
1338 | #define cfoe_lf_c1_4_0_pos 3 | ||
1339 | #define cfoe_lf_c1_4_0_len 5 | ||
1340 | #define cfoe_lf_c1_4_0_lsb 0 | ||
1341 | #define xd_p_cfoe_lf_c1_12_5 0xA207 | ||
1342 | #define cfoe_lf_c1_12_5_pos 0 | ||
1343 | #define cfoe_lf_c1_12_5_len 8 | ||
1344 | #define cfoe_lf_c1_12_5_lsb 5 | ||
1345 | #define xd_p_cfoe_lf_c1_20_13 0xA208 | ||
1346 | #define cfoe_lf_c1_20_13_pos 0 | ||
1347 | #define cfoe_lf_c1_20_13_len 8 | ||
1348 | #define cfoe_lf_c1_20_13_lsb 13 | ||
1349 | #define xd_p_cfoe_lf_c1_25_21 0xA209 | ||
1350 | #define cfoe_lf_c1_25_21_pos 0 | ||
1351 | #define cfoe_lf_c1_25_21_len 5 | ||
1352 | #define cfoe_lf_c1_25_21_lsb 21 | ||
1353 | #define xd_p_cfoe_lf_c2_2_0 0xA209 | ||
1354 | #define cfoe_lf_c2_2_0_pos 5 | ||
1355 | #define cfoe_lf_c2_2_0_len 3 | ||
1356 | #define cfoe_lf_c2_2_0_lsb 0 | ||
1357 | #define xd_p_cfoe_lf_c2_10_3 0xA20A | ||
1358 | #define cfoe_lf_c2_10_3_pos 0 | ||
1359 | #define cfoe_lf_c2_10_3_len 8 | ||
1360 | #define cfoe_lf_c2_10_3_lsb 3 | ||
1361 | #define xd_p_cfoe_lf_c2_18_11 0xA20B | ||
1362 | #define cfoe_lf_c2_18_11_pos 0 | ||
1363 | #define cfoe_lf_c2_18_11_len 8 | ||
1364 | #define cfoe_lf_c2_18_11_lsb 11 | ||
1365 | #define xd_p_cfoe_lf_c2_25_19 0xA20C | ||
1366 | #define cfoe_lf_c2_25_19_pos 0 | ||
1367 | #define cfoe_lf_c2_25_19_len 7 | ||
1368 | #define cfoe_lf_c2_25_19_lsb 19 | ||
1369 | #define xd_p_cfoe_ifod_7_0 0xA20D | ||
1370 | #define cfoe_ifod_7_0_pos 0 | ||
1371 | #define cfoe_ifod_7_0_len 8 | ||
1372 | #define cfoe_ifod_7_0_lsb 0 | ||
1373 | #define xd_p_cfoe_ifod_10_8 0xA20E | ||
1374 | #define cfoe_ifod_10_8_pos 0 | ||
1375 | #define cfoe_ifod_10_8_len 3 | ||
1376 | #define cfoe_ifod_10_8_lsb 8 | ||
1377 | #define xd_p_cfoe_Divg_ctr_th 0xA20E | ||
1378 | #define cfoe_Divg_ctr_th_pos 4 | ||
1379 | #define cfoe_Divg_ctr_th_len 4 | ||
1380 | #define cfoe_Divg_ctr_th_lsb 0 | ||
1381 | #define xd_p_cfoe_FOT_divg_th 0xA20F | ||
1382 | #define cfoe_FOT_divg_th_pos 0 | ||
1383 | #define cfoe_FOT_divg_th_len 8 | ||
1384 | #define cfoe_FOT_divg_th_lsb 0 | ||
1385 | #define xd_p_cfoe_FOT_cnvg_th 0xA210 | ||
1386 | #define cfoe_FOT_cnvg_th_pos 0 | ||
1387 | #define cfoe_FOT_cnvg_th_len 8 | ||
1388 | #define cfoe_FOT_cnvg_th_lsb 0 | ||
1389 | #define xd_p_reg_cfoe_offset_7_0 0xA211 | ||
1390 | #define reg_cfoe_offset_7_0_pos 0 | ||
1391 | #define reg_cfoe_offset_7_0_len 8 | ||
1392 | #define reg_cfoe_offset_7_0_lsb 0 | ||
1393 | #define xd_p_reg_cfoe_offset_9_8 0xA212 | ||
1394 | #define reg_cfoe_offset_9_8_pos 0 | ||
1395 | #define reg_cfoe_offset_9_8_len 2 | ||
1396 | #define reg_cfoe_offset_9_8_lsb 8 | ||
1397 | #define xd_p_reg_cfoe_ifoe_sign_corr 0xA212 | ||
1398 | #define reg_cfoe_ifoe_sign_corr_pos 2 | ||
1399 | #define reg_cfoe_ifoe_sign_corr_len 1 | ||
1400 | #define reg_cfoe_ifoe_sign_corr_lsb 0 | ||
1401 | #define xd_r_cfoe_fot_LF_output_7_0 0xA218 | ||
1402 | #define cfoe_fot_LF_output_7_0_pos 0 | ||
1403 | #define cfoe_fot_LF_output_7_0_len 8 | ||
1404 | #define cfoe_fot_LF_output_7_0_lsb 0 | ||
1405 | #define xd_r_cfoe_fot_LF_output_15_8 0xA219 | ||
1406 | #define cfoe_fot_LF_output_15_8_pos 0 | ||
1407 | #define cfoe_fot_LF_output_15_8_len 8 | ||
1408 | #define cfoe_fot_LF_output_15_8_lsb 8 | ||
1409 | #define xd_r_cfoe_ifo_metric_7_0 0xA21A | ||
1410 | #define cfoe_ifo_metric_7_0_pos 0 | ||
1411 | #define cfoe_ifo_metric_7_0_len 8 | ||
1412 | #define cfoe_ifo_metric_7_0_lsb 0 | ||
1413 | #define xd_r_cfoe_ifo_metric_15_8 0xA21B | ||
1414 | #define cfoe_ifo_metric_15_8_pos 0 | ||
1415 | #define cfoe_ifo_metric_15_8_len 8 | ||
1416 | #define cfoe_ifo_metric_15_8_lsb 8 | ||
1417 | #define xd_r_cfoe_ifo_metric_23_16 0xA21C | ||
1418 | #define cfoe_ifo_metric_23_16_pos 0 | ||
1419 | #define cfoe_ifo_metric_23_16_len 8 | ||
1420 | #define cfoe_ifo_metric_23_16_lsb 16 | ||
1421 | #define xd_p_ste_Nu 0xA220 | ||
1422 | #define ste_Nu_pos 0 | ||
1423 | #define ste_Nu_len 2 | ||
1424 | #define ste_Nu_lsb 0 | ||
1425 | #define xd_p_ste_GI 0xA220 | ||
1426 | #define ste_GI_pos 2 | ||
1427 | #define ste_GI_len 3 | ||
1428 | #define ste_GI_lsb 0 | ||
1429 | #define xd_p_ste_symbol_num 0xA221 | ||
1430 | #define ste_symbol_num_pos 0 | ||
1431 | #define ste_symbol_num_len 2 | ||
1432 | #define ste_symbol_num_lsb 0 | ||
1433 | #define xd_p_ste_sample_num 0xA221 | ||
1434 | #define ste_sample_num_pos 2 | ||
1435 | #define ste_sample_num_len 2 | ||
1436 | #define ste_sample_num_lsb 0 | ||
1437 | #define xd_p_reg_ste_buf_en 0xA221 | ||
1438 | #define reg_ste_buf_en_pos 7 | ||
1439 | #define reg_ste_buf_en_len 1 | ||
1440 | #define reg_ste_buf_en_lsb 0 | ||
1441 | #define xd_p_ste_FFT_offset_7_0 0xA222 | ||
1442 | #define ste_FFT_offset_7_0_pos 0 | ||
1443 | #define ste_FFT_offset_7_0_len 8 | ||
1444 | #define ste_FFT_offset_7_0_lsb 0 | ||
1445 | #define xd_p_ste_FFT_offset_11_8 0xA223 | ||
1446 | #define ste_FFT_offset_11_8_pos 0 | ||
1447 | #define ste_FFT_offset_11_8_len 4 | ||
1448 | #define ste_FFT_offset_11_8_lsb 8 | ||
1449 | #define xd_p_reg_ste_tstmod 0xA223 | ||
1450 | #define reg_ste_tstmod_pos 5 | ||
1451 | #define reg_ste_tstmod_len 1 | ||
1452 | #define reg_ste_tstmod_lsb 0 | ||
1453 | #define xd_p_ste_adv_start_7_0 0xA224 | ||
1454 | #define ste_adv_start_7_0_pos 0 | ||
1455 | #define ste_adv_start_7_0_len 8 | ||
1456 | #define ste_adv_start_7_0_lsb 0 | ||
1457 | #define xd_p_ste_adv_start_10_8 0xA225 | ||
1458 | #define ste_adv_start_10_8_pos 0 | ||
1459 | #define ste_adv_start_10_8_len 3 | ||
1460 | #define ste_adv_start_10_8_lsb 8 | ||
1461 | #define xd_p_ste_adv_stop 0xA226 | ||
1462 | #define ste_adv_stop_pos 0 | ||
1463 | #define ste_adv_stop_len 8 | ||
1464 | #define ste_adv_stop_lsb 0 | ||
1465 | #define xd_r_ste_P_value_7_0 0xA228 | ||
1466 | #define ste_P_value_7_0_pos 0 | ||
1467 | #define ste_P_value_7_0_len 8 | ||
1468 | #define ste_P_value_7_0_lsb 0 | ||
1469 | #define xd_r_ste_P_value_10_8 0xA229 | ||
1470 | #define ste_P_value_10_8_pos 0 | ||
1471 | #define ste_P_value_10_8_len 3 | ||
1472 | #define ste_P_value_10_8_lsb 8 | ||
1473 | #define xd_r_ste_M_value_7_0 0xA22A | ||
1474 | #define ste_M_value_7_0_pos 0 | ||
1475 | #define ste_M_value_7_0_len 8 | ||
1476 | #define ste_M_value_7_0_lsb 0 | ||
1477 | #define xd_r_ste_M_value_10_8 0xA22B | ||
1478 | #define ste_M_value_10_8_pos 0 | ||
1479 | #define ste_M_value_10_8_len 3 | ||
1480 | #define ste_M_value_10_8_lsb 8 | ||
1481 | #define xd_r_ste_H1 0xA22C | ||
1482 | #define ste_H1_pos 0 | ||
1483 | #define ste_H1_len 7 | ||
1484 | #define ste_H1_lsb 0 | ||
1485 | #define xd_r_ste_H2 0xA22D | ||
1486 | #define ste_H2_pos 0 | ||
1487 | #define ste_H2_len 7 | ||
1488 | #define ste_H2_lsb 0 | ||
1489 | #define xd_r_ste_H3 0xA22E | ||
1490 | #define ste_H3_pos 0 | ||
1491 | #define ste_H3_len 7 | ||
1492 | #define ste_H3_lsb 0 | ||
1493 | #define xd_r_ste_H4 0xA22F | ||
1494 | #define ste_H4_pos 0 | ||
1495 | #define ste_H4_len 7 | ||
1496 | #define ste_H4_lsb 0 | ||
1497 | #define xd_r_ste_Corr_value_I_7_0 0xA230 | ||
1498 | #define ste_Corr_value_I_7_0_pos 0 | ||
1499 | #define ste_Corr_value_I_7_0_len 8 | ||
1500 | #define ste_Corr_value_I_7_0_lsb 0 | ||
1501 | #define xd_r_ste_Corr_value_I_15_8 0xA231 | ||
1502 | #define ste_Corr_value_I_15_8_pos 0 | ||
1503 | #define ste_Corr_value_I_15_8_len 8 | ||
1504 | #define ste_Corr_value_I_15_8_lsb 8 | ||
1505 | #define xd_r_ste_Corr_value_I_23_16 0xA232 | ||
1506 | #define ste_Corr_value_I_23_16_pos 0 | ||
1507 | #define ste_Corr_value_I_23_16_len 8 | ||
1508 | #define ste_Corr_value_I_23_16_lsb 16 | ||
1509 | #define xd_r_ste_Corr_value_I_27_24 0xA233 | ||
1510 | #define ste_Corr_value_I_27_24_pos 0 | ||
1511 | #define ste_Corr_value_I_27_24_len 4 | ||
1512 | #define ste_Corr_value_I_27_24_lsb 24 | ||
1513 | #define xd_r_ste_Corr_value_Q_7_0 0xA234 | ||
1514 | #define ste_Corr_value_Q_7_0_pos 0 | ||
1515 | #define ste_Corr_value_Q_7_0_len 8 | ||
1516 | #define ste_Corr_value_Q_7_0_lsb 0 | ||
1517 | #define xd_r_ste_Corr_value_Q_15_8 0xA235 | ||
1518 | #define ste_Corr_value_Q_15_8_pos 0 | ||
1519 | #define ste_Corr_value_Q_15_8_len 8 | ||
1520 | #define ste_Corr_value_Q_15_8_lsb 8 | ||
1521 | #define xd_r_ste_Corr_value_Q_23_16 0xA236 | ||
1522 | #define ste_Corr_value_Q_23_16_pos 0 | ||
1523 | #define ste_Corr_value_Q_23_16_len 8 | ||
1524 | #define ste_Corr_value_Q_23_16_lsb 16 | ||
1525 | #define xd_r_ste_Corr_value_Q_27_24 0xA237 | ||
1526 | #define ste_Corr_value_Q_27_24_pos 0 | ||
1527 | #define ste_Corr_value_Q_27_24_len 4 | ||
1528 | #define ste_Corr_value_Q_27_24_lsb 24 | ||
1529 | #define xd_r_ste_J_num_7_0 0xA238 | ||
1530 | #define ste_J_num_7_0_pos 0 | ||
1531 | #define ste_J_num_7_0_len 8 | ||
1532 | #define ste_J_num_7_0_lsb 0 | ||
1533 | #define xd_r_ste_J_num_15_8 0xA239 | ||
1534 | #define ste_J_num_15_8_pos 0 | ||
1535 | #define ste_J_num_15_8_len 8 | ||
1536 | #define ste_J_num_15_8_lsb 8 | ||
1537 | #define xd_r_ste_J_num_23_16 0xA23A | ||
1538 | #define ste_J_num_23_16_pos 0 | ||
1539 | #define ste_J_num_23_16_len 8 | ||
1540 | #define ste_J_num_23_16_lsb 16 | ||
1541 | #define xd_r_ste_J_num_31_24 0xA23B | ||
1542 | #define ste_J_num_31_24_pos 0 | ||
1543 | #define ste_J_num_31_24_len 8 | ||
1544 | #define ste_J_num_31_24_lsb 24 | ||
1545 | #define xd_r_ste_J_den_7_0 0xA23C | ||
1546 | #define ste_J_den_7_0_pos 0 | ||
1547 | #define ste_J_den_7_0_len 8 | ||
1548 | #define ste_J_den_7_0_lsb 0 | ||
1549 | #define xd_r_ste_J_den_15_8 0xA23D | ||
1550 | #define ste_J_den_15_8_pos 0 | ||
1551 | #define ste_J_den_15_8_len 8 | ||
1552 | #define ste_J_den_15_8_lsb 8 | ||
1553 | #define xd_r_ste_J_den_18_16 0xA23E | ||
1554 | #define ste_J_den_18_16_pos 0 | ||
1555 | #define ste_J_den_18_16_len 3 | ||
1556 | #define ste_J_den_18_16_lsb 16 | ||
1557 | #define xd_r_ste_Beacon_Indicator 0xA23E | ||
1558 | #define ste_Beacon_Indicator_pos 4 | ||
1559 | #define ste_Beacon_Indicator_len 1 | ||
1560 | #define ste_Beacon_Indicator_lsb 0 | ||
1561 | #define xd_r_tpsd_Frame_Num 0xA250 | ||
1562 | #define tpsd_Frame_Num_pos 0 | ||
1563 | #define tpsd_Frame_Num_len 2 | ||
1564 | #define tpsd_Frame_Num_lsb 0 | ||
1565 | #define xd_r_tpsd_Constel 0xA250 | ||
1566 | #define tpsd_Constel_pos 2 | ||
1567 | #define tpsd_Constel_len 2 | ||
1568 | #define tpsd_Constel_lsb 0 | ||
1569 | #define xd_r_tpsd_GI 0xA250 | ||
1570 | #define tpsd_GI_pos 4 | ||
1571 | #define tpsd_GI_len 2 | ||
1572 | #define tpsd_GI_lsb 0 | ||
1573 | #define xd_r_tpsd_Mode 0xA250 | ||
1574 | #define tpsd_Mode_pos 6 | ||
1575 | #define tpsd_Mode_len 2 | ||
1576 | #define tpsd_Mode_lsb 0 | ||
1577 | #define xd_r_tpsd_CR_HP 0xA251 | ||
1578 | #define tpsd_CR_HP_pos 0 | ||
1579 | #define tpsd_CR_HP_len 3 | ||
1580 | #define tpsd_CR_HP_lsb 0 | ||
1581 | #define xd_r_tpsd_CR_LP 0xA251 | ||
1582 | #define tpsd_CR_LP_pos 3 | ||
1583 | #define tpsd_CR_LP_len 3 | ||
1584 | #define tpsd_CR_LP_lsb 0 | ||
1585 | #define xd_r_tpsd_Hie 0xA252 | ||
1586 | #define tpsd_Hie_pos 0 | ||
1587 | #define tpsd_Hie_len 3 | ||
1588 | #define tpsd_Hie_lsb 0 | ||
1589 | #define xd_r_tpsd_Res_Bits 0xA252 | ||
1590 | #define tpsd_Res_Bits_pos 3 | ||
1591 | #define tpsd_Res_Bits_len 5 | ||
1592 | #define tpsd_Res_Bits_lsb 0 | ||
1593 | #define xd_r_tpsd_Res_Bits_0 0xA253 | ||
1594 | #define tpsd_Res_Bits_0_pos 0 | ||
1595 | #define tpsd_Res_Bits_0_len 1 | ||
1596 | #define tpsd_Res_Bits_0_lsb 0 | ||
1597 | #define xd_r_tpsd_LengthInd 0xA253 | ||
1598 | #define tpsd_LengthInd_pos 1 | ||
1599 | #define tpsd_LengthInd_len 6 | ||
1600 | #define tpsd_LengthInd_lsb 0 | ||
1601 | #define xd_r_tpsd_Cell_Id_7_0 0xA254 | ||
1602 | #define tpsd_Cell_Id_7_0_pos 0 | ||
1603 | #define tpsd_Cell_Id_7_0_len 8 | ||
1604 | #define tpsd_Cell_Id_7_0_lsb 0 | ||
1605 | #define xd_r_tpsd_Cell_Id_15_8 0xA255 | ||
1606 | #define tpsd_Cell_Id_15_8_pos 0 | ||
1607 | #define tpsd_Cell_Id_15_8_len 8 | ||
1608 | #define tpsd_Cell_Id_15_8_lsb 0 | ||
1609 | #define xd_p_reg_fft_mask_tone0_7_0 0xA260 | ||
1610 | #define reg_fft_mask_tone0_7_0_pos 0 | ||
1611 | #define reg_fft_mask_tone0_7_0_len 8 | ||
1612 | #define reg_fft_mask_tone0_7_0_lsb 0 | ||
1613 | #define xd_p_reg_fft_mask_tone0_12_8 0xA261 | ||
1614 | #define reg_fft_mask_tone0_12_8_pos 0 | ||
1615 | #define reg_fft_mask_tone0_12_8_len 5 | ||
1616 | #define reg_fft_mask_tone0_12_8_lsb 8 | ||
1617 | #define xd_p_reg_fft_mask_tone1_7_0 0xA262 | ||
1618 | #define reg_fft_mask_tone1_7_0_pos 0 | ||
1619 | #define reg_fft_mask_tone1_7_0_len 8 | ||
1620 | #define reg_fft_mask_tone1_7_0_lsb 0 | ||
1621 | #define xd_p_reg_fft_mask_tone1_12_8 0xA263 | ||
1622 | #define reg_fft_mask_tone1_12_8_pos 0 | ||
1623 | #define reg_fft_mask_tone1_12_8_len 5 | ||
1624 | #define reg_fft_mask_tone1_12_8_lsb 8 | ||
1625 | #define xd_p_reg_fft_mask_tone2_7_0 0xA264 | ||
1626 | #define reg_fft_mask_tone2_7_0_pos 0 | ||
1627 | #define reg_fft_mask_tone2_7_0_len 8 | ||
1628 | #define reg_fft_mask_tone2_7_0_lsb 0 | ||
1629 | #define xd_p_reg_fft_mask_tone2_12_8 0xA265 | ||
1630 | #define reg_fft_mask_tone2_12_8_pos 0 | ||
1631 | #define reg_fft_mask_tone2_12_8_len 5 | ||
1632 | #define reg_fft_mask_tone2_12_8_lsb 8 | ||
1633 | #define xd_p_reg_fft_mask_tone3_7_0 0xA266 | ||
1634 | #define reg_fft_mask_tone3_7_0_pos 0 | ||
1635 | #define reg_fft_mask_tone3_7_0_len 8 | ||
1636 | #define reg_fft_mask_tone3_7_0_lsb 0 | ||
1637 | #define xd_p_reg_fft_mask_tone3_12_8 0xA267 | ||
1638 | #define reg_fft_mask_tone3_12_8_pos 0 | ||
1639 | #define reg_fft_mask_tone3_12_8_len 5 | ||
1640 | #define reg_fft_mask_tone3_12_8_lsb 8 | ||
1641 | #define xd_p_reg_fft_mask_from0_7_0 0xA268 | ||
1642 | #define reg_fft_mask_from0_7_0_pos 0 | ||
1643 | #define reg_fft_mask_from0_7_0_len 8 | ||
1644 | #define reg_fft_mask_from0_7_0_lsb 0 | ||
1645 | #define xd_p_reg_fft_mask_from0_12_8 0xA269 | ||
1646 | #define reg_fft_mask_from0_12_8_pos 0 | ||
1647 | #define reg_fft_mask_from0_12_8_len 5 | ||
1648 | #define reg_fft_mask_from0_12_8_lsb 8 | ||
1649 | #define xd_p_reg_fft_mask_to0_7_0 0xA26A | ||
1650 | #define reg_fft_mask_to0_7_0_pos 0 | ||
1651 | #define reg_fft_mask_to0_7_0_len 8 | ||
1652 | #define reg_fft_mask_to0_7_0_lsb 0 | ||
1653 | #define xd_p_reg_fft_mask_to0_12_8 0xA26B | ||
1654 | #define reg_fft_mask_to0_12_8_pos 0 | ||
1655 | #define reg_fft_mask_to0_12_8_len 5 | ||
1656 | #define reg_fft_mask_to0_12_8_lsb 8 | ||
1657 | #define xd_p_reg_fft_mask_from1_7_0 0xA26C | ||
1658 | #define reg_fft_mask_from1_7_0_pos 0 | ||
1659 | #define reg_fft_mask_from1_7_0_len 8 | ||
1660 | #define reg_fft_mask_from1_7_0_lsb 0 | ||
1661 | #define xd_p_reg_fft_mask_from1_12_8 0xA26D | ||
1662 | #define reg_fft_mask_from1_12_8_pos 0 | ||
1663 | #define reg_fft_mask_from1_12_8_len 5 | ||
1664 | #define reg_fft_mask_from1_12_8_lsb 8 | ||
1665 | #define xd_p_reg_fft_mask_to1_7_0 0xA26E | ||
1666 | #define reg_fft_mask_to1_7_0_pos 0 | ||
1667 | #define reg_fft_mask_to1_7_0_len 8 | ||
1668 | #define reg_fft_mask_to1_7_0_lsb 0 | ||
1669 | #define xd_p_reg_fft_mask_to1_12_8 0xA26F | ||
1670 | #define reg_fft_mask_to1_12_8_pos 0 | ||
1671 | #define reg_fft_mask_to1_12_8_len 5 | ||
1672 | #define reg_fft_mask_to1_12_8_lsb 8 | ||
1673 | #define xd_p_reg_cge_idx0_7_0 0xA280 | ||
1674 | #define reg_cge_idx0_7_0_pos 0 | ||
1675 | #define reg_cge_idx0_7_0_len 8 | ||
1676 | #define reg_cge_idx0_7_0_lsb 0 | ||
1677 | #define xd_p_reg_cge_idx0_12_8 0xA281 | ||
1678 | #define reg_cge_idx0_12_8_pos 0 | ||
1679 | #define reg_cge_idx0_12_8_len 5 | ||
1680 | #define reg_cge_idx0_12_8_lsb 8 | ||
1681 | #define xd_p_reg_cge_idx1_7_0 0xA282 | ||
1682 | #define reg_cge_idx1_7_0_pos 0 | ||
1683 | #define reg_cge_idx1_7_0_len 8 | ||
1684 | #define reg_cge_idx1_7_0_lsb 0 | ||
1685 | #define xd_p_reg_cge_idx1_12_8 0xA283 | ||
1686 | #define reg_cge_idx1_12_8_pos 0 | ||
1687 | #define reg_cge_idx1_12_8_len 5 | ||
1688 | #define reg_cge_idx1_12_8_lsb 8 | ||
1689 | #define xd_p_reg_cge_idx2_7_0 0xA284 | ||
1690 | #define reg_cge_idx2_7_0_pos 0 | ||
1691 | #define reg_cge_idx2_7_0_len 8 | ||
1692 | #define reg_cge_idx2_7_0_lsb 0 | ||
1693 | #define xd_p_reg_cge_idx2_12_8 0xA285 | ||
1694 | #define reg_cge_idx2_12_8_pos 0 | ||
1695 | #define reg_cge_idx2_12_8_len 5 | ||
1696 | #define reg_cge_idx2_12_8_lsb 8 | ||
1697 | #define xd_p_reg_cge_idx3_7_0 0xA286 | ||
1698 | #define reg_cge_idx3_7_0_pos 0 | ||
1699 | #define reg_cge_idx3_7_0_len 8 | ||
1700 | #define reg_cge_idx3_7_0_lsb 0 | ||
1701 | #define xd_p_reg_cge_idx3_12_8 0xA287 | ||
1702 | #define reg_cge_idx3_12_8_pos 0 | ||
1703 | #define reg_cge_idx3_12_8_len 5 | ||
1704 | #define reg_cge_idx3_12_8_lsb 8 | ||
1705 | #define xd_p_reg_cge_idx4_7_0 0xA288 | ||
1706 | #define reg_cge_idx4_7_0_pos 0 | ||
1707 | #define reg_cge_idx4_7_0_len 8 | ||
1708 | #define reg_cge_idx4_7_0_lsb 0 | ||
1709 | #define xd_p_reg_cge_idx4_12_8 0xA289 | ||
1710 | #define reg_cge_idx4_12_8_pos 0 | ||
1711 | #define reg_cge_idx4_12_8_len 5 | ||
1712 | #define reg_cge_idx4_12_8_lsb 8 | ||
1713 | #define xd_p_reg_cge_idx5_7_0 0xA28A | ||
1714 | #define reg_cge_idx5_7_0_pos 0 | ||
1715 | #define reg_cge_idx5_7_0_len 8 | ||
1716 | #define reg_cge_idx5_7_0_lsb 0 | ||
1717 | #define xd_p_reg_cge_idx5_12_8 0xA28B | ||
1718 | #define reg_cge_idx5_12_8_pos 0 | ||
1719 | #define reg_cge_idx5_12_8_len 5 | ||
1720 | #define reg_cge_idx5_12_8_lsb 8 | ||
1721 | #define xd_p_reg_cge_idx6_7_0 0xA28C | ||
1722 | #define reg_cge_idx6_7_0_pos 0 | ||
1723 | #define reg_cge_idx6_7_0_len 8 | ||
1724 | #define reg_cge_idx6_7_0_lsb 0 | ||
1725 | #define xd_p_reg_cge_idx6_12_8 0xA28D | ||
1726 | #define reg_cge_idx6_12_8_pos 0 | ||
1727 | #define reg_cge_idx6_12_8_len 5 | ||
1728 | #define reg_cge_idx6_12_8_lsb 8 | ||
1729 | #define xd_p_reg_cge_idx7_7_0 0xA28E | ||
1730 | #define reg_cge_idx7_7_0_pos 0 | ||
1731 | #define reg_cge_idx7_7_0_len 8 | ||
1732 | #define reg_cge_idx7_7_0_lsb 0 | ||
1733 | #define xd_p_reg_cge_idx7_12_8 0xA28F | ||
1734 | #define reg_cge_idx7_12_8_pos 0 | ||
1735 | #define reg_cge_idx7_12_8_len 5 | ||
1736 | #define reg_cge_idx7_12_8_lsb 8 | ||
1737 | #define xd_p_reg_cge_idx8_7_0 0xA290 | ||
1738 | #define reg_cge_idx8_7_0_pos 0 | ||
1739 | #define reg_cge_idx8_7_0_len 8 | ||
1740 | #define reg_cge_idx8_7_0_lsb 0 | ||
1741 | #define xd_p_reg_cge_idx8_12_8 0xA291 | ||
1742 | #define reg_cge_idx8_12_8_pos 0 | ||
1743 | #define reg_cge_idx8_12_8_len 5 | ||
1744 | #define reg_cge_idx8_12_8_lsb 8 | ||
1745 | #define xd_p_reg_cge_idx9_7_0 0xA292 | ||
1746 | #define reg_cge_idx9_7_0_pos 0 | ||
1747 | #define reg_cge_idx9_7_0_len 8 | ||
1748 | #define reg_cge_idx9_7_0_lsb 0 | ||
1749 | #define xd_p_reg_cge_idx9_12_8 0xA293 | ||
1750 | #define reg_cge_idx9_12_8_pos 0 | ||
1751 | #define reg_cge_idx9_12_8_len 5 | ||
1752 | #define reg_cge_idx9_12_8_lsb 8 | ||
1753 | #define xd_p_reg_cge_idx10_7_0 0xA294 | ||
1754 | #define reg_cge_idx10_7_0_pos 0 | ||
1755 | #define reg_cge_idx10_7_0_len 8 | ||
1756 | #define reg_cge_idx10_7_0_lsb 0 | ||
1757 | #define xd_p_reg_cge_idx10_12_8 0xA295 | ||
1758 | #define reg_cge_idx10_12_8_pos 0 | ||
1759 | #define reg_cge_idx10_12_8_len 5 | ||
1760 | #define reg_cge_idx10_12_8_lsb 8 | ||
1761 | #define xd_p_reg_cge_idx11_7_0 0xA296 | ||
1762 | #define reg_cge_idx11_7_0_pos 0 | ||
1763 | #define reg_cge_idx11_7_0_len 8 | ||
1764 | #define reg_cge_idx11_7_0_lsb 0 | ||
1765 | #define xd_p_reg_cge_idx11_12_8 0xA297 | ||
1766 | #define reg_cge_idx11_12_8_pos 0 | ||
1767 | #define reg_cge_idx11_12_8_len 5 | ||
1768 | #define reg_cge_idx11_12_8_lsb 8 | ||
1769 | #define xd_p_reg_cge_idx12_7_0 0xA298 | ||
1770 | #define reg_cge_idx12_7_0_pos 0 | ||
1771 | #define reg_cge_idx12_7_0_len 8 | ||
1772 | #define reg_cge_idx12_7_0_lsb 0 | ||
1773 | #define xd_p_reg_cge_idx12_12_8 0xA299 | ||
1774 | #define reg_cge_idx12_12_8_pos 0 | ||
1775 | #define reg_cge_idx12_12_8_len 5 | ||
1776 | #define reg_cge_idx12_12_8_lsb 8 | ||
1777 | #define xd_p_reg_cge_idx13_7_0 0xA29A | ||
1778 | #define reg_cge_idx13_7_0_pos 0 | ||
1779 | #define reg_cge_idx13_7_0_len 8 | ||
1780 | #define reg_cge_idx13_7_0_lsb 0 | ||
1781 | #define xd_p_reg_cge_idx13_12_8 0xA29B | ||
1782 | #define reg_cge_idx13_12_8_pos 0 | ||
1783 | #define reg_cge_idx13_12_8_len 5 | ||
1784 | #define reg_cge_idx13_12_8_lsb 8 | ||
1785 | #define xd_p_reg_cge_idx14_7_0 0xA29C | ||
1786 | #define reg_cge_idx14_7_0_pos 0 | ||
1787 | #define reg_cge_idx14_7_0_len 8 | ||
1788 | #define reg_cge_idx14_7_0_lsb 0 | ||
1789 | #define xd_p_reg_cge_idx14_12_8 0xA29D | ||
1790 | #define reg_cge_idx14_12_8_pos 0 | ||
1791 | #define reg_cge_idx14_12_8_len 5 | ||
1792 | #define reg_cge_idx14_12_8_lsb 8 | ||
1793 | #define xd_p_reg_cge_idx15_7_0 0xA29E | ||
1794 | #define reg_cge_idx15_7_0_pos 0 | ||
1795 | #define reg_cge_idx15_7_0_len 8 | ||
1796 | #define reg_cge_idx15_7_0_lsb 0 | ||
1797 | #define xd_p_reg_cge_idx15_12_8 0xA29F | ||
1798 | #define reg_cge_idx15_12_8_pos 0 | ||
1799 | #define reg_cge_idx15_12_8_len 5 | ||
1800 | #define reg_cge_idx15_12_8_lsb 8 | ||
1801 | #define xd_r_reg_fft_crc 0xA2A8 | ||
1802 | #define reg_fft_crc_pos 0 | ||
1803 | #define reg_fft_crc_len 8 | ||
1804 | #define reg_fft_crc_lsb 0 | ||
1805 | #define xd_p_fd_fft_shift_max 0xA2A9 | ||
1806 | #define fd_fft_shift_max_pos 0 | ||
1807 | #define fd_fft_shift_max_len 4 | ||
1808 | #define fd_fft_shift_max_lsb 0 | ||
1809 | #define xd_r_fd_fft_shift 0xA2A9 | ||
1810 | #define fd_fft_shift_pos 4 | ||
1811 | #define fd_fft_shift_len 4 | ||
1812 | #define fd_fft_shift_lsb 0 | ||
1813 | #define xd_r_fd_fft_frame_num 0xA2AA | ||
1814 | #define fd_fft_frame_num_pos 0 | ||
1815 | #define fd_fft_frame_num_len 2 | ||
1816 | #define fd_fft_frame_num_lsb 0 | ||
1817 | #define xd_r_fd_fft_symbol_count 0xA2AB | ||
1818 | #define fd_fft_symbol_count_pos 0 | ||
1819 | #define fd_fft_symbol_count_len 7 | ||
1820 | #define fd_fft_symbol_count_lsb 0 | ||
1821 | #define xd_r_reg_fft_idx_max_7_0 0xA2AC | ||
1822 | #define reg_fft_idx_max_7_0_pos 0 | ||
1823 | #define reg_fft_idx_max_7_0_len 8 | ||
1824 | #define reg_fft_idx_max_7_0_lsb 0 | ||
1825 | #define xd_r_reg_fft_idx_max_12_8 0xA2AD | ||
1826 | #define reg_fft_idx_max_12_8_pos 0 | ||
1827 | #define reg_fft_idx_max_12_8_len 5 | ||
1828 | #define reg_fft_idx_max_12_8_lsb 8 | ||
1829 | #define xd_p_reg_cge_program 0xA2AE | ||
1830 | #define reg_cge_program_pos 0 | ||
1831 | #define reg_cge_program_len 1 | ||
1832 | #define reg_cge_program_lsb 0 | ||
1833 | #define xd_p_reg_cge_fixed 0xA2AE | ||
1834 | #define reg_cge_fixed_pos 1 | ||
1835 | #define reg_cge_fixed_len 1 | ||
1836 | #define reg_cge_fixed_lsb 0 | ||
1837 | #define xd_p_reg_fft_rotate_en 0xA2AE | ||
1838 | #define reg_fft_rotate_en_pos 2 | ||
1839 | #define reg_fft_rotate_en_len 1 | ||
1840 | #define reg_fft_rotate_en_lsb 0 | ||
1841 | #define xd_p_reg_fft_rotate_base_4_0 0xA2AE | ||
1842 | #define reg_fft_rotate_base_4_0_pos 3 | ||
1843 | #define reg_fft_rotate_base_4_0_len 5 | ||
1844 | #define reg_fft_rotate_base_4_0_lsb 0 | ||
1845 | #define xd_p_reg_fft_rotate_base_12_5 0xA2AF | ||
1846 | #define reg_fft_rotate_base_12_5_pos 0 | ||
1847 | #define reg_fft_rotate_base_12_5_len 8 | ||
1848 | #define reg_fft_rotate_base_12_5_lsb 5 | ||
1849 | #define xd_p_reg_gp_trigger_fd 0xA2B8 | ||
1850 | #define reg_gp_trigger_fd_pos 0 | ||
1851 | #define reg_gp_trigger_fd_len 1 | ||
1852 | #define reg_gp_trigger_fd_lsb 0 | ||
1853 | #define xd_p_reg_trigger_sel_fd 0xA2B8 | ||
1854 | #define reg_trigger_sel_fd_pos 1 | ||
1855 | #define reg_trigger_sel_fd_len 2 | ||
1856 | #define reg_trigger_sel_fd_lsb 0 | ||
1857 | #define xd_p_reg_trigger_module_sel_fd 0xA2B9 | ||
1858 | #define reg_trigger_module_sel_fd_pos 0 | ||
1859 | #define reg_trigger_module_sel_fd_len 6 | ||
1860 | #define reg_trigger_module_sel_fd_lsb 0 | ||
1861 | #define xd_p_reg_trigger_set_sel_fd 0xA2BA | ||
1862 | #define reg_trigger_set_sel_fd_pos 0 | ||
1863 | #define reg_trigger_set_sel_fd_len 6 | ||
1864 | #define reg_trigger_set_sel_fd_lsb 0 | ||
1865 | #define xd_p_reg_fd_noname_7_0 0xA2BC | ||
1866 | #define reg_fd_noname_7_0_pos 0 | ||
1867 | #define reg_fd_noname_7_0_len 8 | ||
1868 | #define reg_fd_noname_7_0_lsb 0 | ||
1869 | #define xd_p_reg_fd_noname_15_8 0xA2BD | ||
1870 | #define reg_fd_noname_15_8_pos 0 | ||
1871 | #define reg_fd_noname_15_8_len 8 | ||
1872 | #define reg_fd_noname_15_8_lsb 8 | ||
1873 | #define xd_p_reg_fd_noname_23_16 0xA2BE | ||
1874 | #define reg_fd_noname_23_16_pos 0 | ||
1875 | #define reg_fd_noname_23_16_len 8 | ||
1876 | #define reg_fd_noname_23_16_lsb 16 | ||
1877 | #define xd_p_reg_fd_noname_31_24 0xA2BF | ||
1878 | #define reg_fd_noname_31_24_pos 0 | ||
1879 | #define reg_fd_noname_31_24_len 8 | ||
1880 | #define reg_fd_noname_31_24_lsb 24 | ||
1881 | #define xd_r_fd_fpcc_cp_corr_signn 0xA2C0 | ||
1882 | #define fd_fpcc_cp_corr_signn_pos 0 | ||
1883 | #define fd_fpcc_cp_corr_signn_len 8 | ||
1884 | #define fd_fpcc_cp_corr_signn_lsb 0 | ||
1885 | #define xd_p_reg_feq_s1 0xA2C1 | ||
1886 | #define reg_feq_s1_pos 0 | ||
1887 | #define reg_feq_s1_len 5 | ||
1888 | #define reg_feq_s1_lsb 0 | ||
1889 | #define xd_p_fd_fpcc_cp_corr_tone_th 0xA2C2 | ||
1890 | #define fd_fpcc_cp_corr_tone_th_pos 0 | ||
1891 | #define fd_fpcc_cp_corr_tone_th_len 6 | ||
1892 | #define fd_fpcc_cp_corr_tone_th_lsb 0 | ||
1893 | #define xd_p_fd_fpcc_cp_corr_symbol_log_th 0xA2C3 | ||
1894 | #define fd_fpcc_cp_corr_symbol_log_th_pos 0 | ||
1895 | #define fd_fpcc_cp_corr_symbol_log_th_len 4 | ||
1896 | #define fd_fpcc_cp_corr_symbol_log_th_lsb 0 | ||
1897 | #define xd_p_fd_fpcc_cp_corr_int 0xA2C4 | ||
1898 | #define fd_fpcc_cp_corr_int_pos 0 | ||
1899 | #define fd_fpcc_cp_corr_int_len 1 | ||
1900 | #define fd_fpcc_cp_corr_int_lsb 0 | ||
1901 | #define xd_p_reg_sfoe_ns_7_0 0xA320 | ||
1902 | #define reg_sfoe_ns_7_0_pos 0 | ||
1903 | #define reg_sfoe_ns_7_0_len 8 | ||
1904 | #define reg_sfoe_ns_7_0_lsb 0 | ||
1905 | #define xd_p_reg_sfoe_ns_14_8 0xA321 | ||
1906 | #define reg_sfoe_ns_14_8_pos 0 | ||
1907 | #define reg_sfoe_ns_14_8_len 7 | ||
1908 | #define reg_sfoe_ns_14_8_lsb 8 | ||
1909 | #define xd_p_reg_sfoe_c1_7_0 0xA322 | ||
1910 | #define reg_sfoe_c1_7_0_pos 0 | ||
1911 | #define reg_sfoe_c1_7_0_len 8 | ||
1912 | #define reg_sfoe_c1_7_0_lsb 0 | ||
1913 | #define xd_p_reg_sfoe_c1_15_8 0xA323 | ||
1914 | #define reg_sfoe_c1_15_8_pos 0 | ||
1915 | #define reg_sfoe_c1_15_8_len 8 | ||
1916 | #define reg_sfoe_c1_15_8_lsb 8 | ||
1917 | #define xd_p_reg_sfoe_c1_17_16 0xA324 | ||
1918 | #define reg_sfoe_c1_17_16_pos 0 | ||
1919 | #define reg_sfoe_c1_17_16_len 2 | ||
1920 | #define reg_sfoe_c1_17_16_lsb 16 | ||
1921 | #define xd_p_reg_sfoe_c2_7_0 0xA325 | ||
1922 | #define reg_sfoe_c2_7_0_pos 0 | ||
1923 | #define reg_sfoe_c2_7_0_len 8 | ||
1924 | #define reg_sfoe_c2_7_0_lsb 0 | ||
1925 | #define xd_p_reg_sfoe_c2_15_8 0xA326 | ||
1926 | #define reg_sfoe_c2_15_8_pos 0 | ||
1927 | #define reg_sfoe_c2_15_8_len 8 | ||
1928 | #define reg_sfoe_c2_15_8_lsb 8 | ||
1929 | #define xd_p_reg_sfoe_c2_17_16 0xA327 | ||
1930 | #define reg_sfoe_c2_17_16_pos 0 | ||
1931 | #define reg_sfoe_c2_17_16_len 2 | ||
1932 | #define reg_sfoe_c2_17_16_lsb 16 | ||
1933 | #define xd_r_reg_sfoe_out_9_2 0xA328 | ||
1934 | #define reg_sfoe_out_9_2_pos 0 | ||
1935 | #define reg_sfoe_out_9_2_len 8 | ||
1936 | #define reg_sfoe_out_9_2_lsb 0 | ||
1937 | #define xd_r_reg_sfoe_out_1_0 0xA329 | ||
1938 | #define reg_sfoe_out_1_0_pos 0 | ||
1939 | #define reg_sfoe_out_1_0_len 2 | ||
1940 | #define reg_sfoe_out_1_0_lsb 0 | ||
1941 | #define xd_p_reg_sfoe_lm_counter_th 0xA32A | ||
1942 | #define reg_sfoe_lm_counter_th_pos 0 | ||
1943 | #define reg_sfoe_lm_counter_th_len 4 | ||
1944 | #define reg_sfoe_lm_counter_th_lsb 0 | ||
1945 | #define xd_p_reg_sfoe_convg_th 0xA32B | ||
1946 | #define reg_sfoe_convg_th_pos 0 | ||
1947 | #define reg_sfoe_convg_th_len 8 | ||
1948 | #define reg_sfoe_convg_th_lsb 0 | ||
1949 | #define xd_p_reg_sfoe_divg_th 0xA32C | ||
1950 | #define reg_sfoe_divg_th_pos 0 | ||
1951 | #define reg_sfoe_divg_th_len 8 | ||
1952 | #define reg_sfoe_divg_th_lsb 0 | ||
1953 | #define xd_p_fd_tpsd_en 0xA330 | ||
1954 | #define fd_tpsd_en_pos 0 | ||
1955 | #define fd_tpsd_en_len 1 | ||
1956 | #define fd_tpsd_en_lsb 0 | ||
1957 | #define xd_p_fd_tpsd_dis 0xA330 | ||
1958 | #define fd_tpsd_dis_pos 1 | ||
1959 | #define fd_tpsd_dis_len 1 | ||
1960 | #define fd_tpsd_dis_lsb 0 | ||
1961 | #define xd_p_fd_tpsd_rst 0xA330 | ||
1962 | #define fd_tpsd_rst_pos 2 | ||
1963 | #define fd_tpsd_rst_len 1 | ||
1964 | #define fd_tpsd_rst_lsb 0 | ||
1965 | #define xd_p_fd_tpsd_lock 0xA330 | ||
1966 | #define fd_tpsd_lock_pos 3 | ||
1967 | #define fd_tpsd_lock_len 1 | ||
1968 | #define fd_tpsd_lock_lsb 0 | ||
1969 | #define xd_r_fd_tpsd_s19 0xA330 | ||
1970 | #define fd_tpsd_s19_pos 4 | ||
1971 | #define fd_tpsd_s19_len 1 | ||
1972 | #define fd_tpsd_s19_lsb 0 | ||
1973 | #define xd_r_fd_tpsd_s17 0xA330 | ||
1974 | #define fd_tpsd_s17_pos 5 | ||
1975 | #define fd_tpsd_s17_len 1 | ||
1976 | #define fd_tpsd_s17_lsb 0 | ||
1977 | #define xd_p_fd_sfr_ste_en 0xA331 | ||
1978 | #define fd_sfr_ste_en_pos 0 | ||
1979 | #define fd_sfr_ste_en_len 1 | ||
1980 | #define fd_sfr_ste_en_lsb 0 | ||
1981 | #define xd_p_fd_sfr_ste_dis 0xA331 | ||
1982 | #define fd_sfr_ste_dis_pos 1 | ||
1983 | #define fd_sfr_ste_dis_len 1 | ||
1984 | #define fd_sfr_ste_dis_lsb 0 | ||
1985 | #define xd_p_fd_sfr_ste_rst 0xA331 | ||
1986 | #define fd_sfr_ste_rst_pos 2 | ||
1987 | #define fd_sfr_ste_rst_len 1 | ||
1988 | #define fd_sfr_ste_rst_lsb 0 | ||
1989 | #define xd_p_fd_sfr_ste_mode 0xA331 | ||
1990 | #define fd_sfr_ste_mode_pos 3 | ||
1991 | #define fd_sfr_ste_mode_len 1 | ||
1992 | #define fd_sfr_ste_mode_lsb 0 | ||
1993 | #define xd_p_fd_sfr_ste_done 0xA331 | ||
1994 | #define fd_sfr_ste_done_pos 4 | ||
1995 | #define fd_sfr_ste_done_len 1 | ||
1996 | #define fd_sfr_ste_done_lsb 0 | ||
1997 | #define xd_p_reg_cfoe_ffoe_en 0xA332 | ||
1998 | #define reg_cfoe_ffoe_en_pos 0 | ||
1999 | #define reg_cfoe_ffoe_en_len 1 | ||
2000 | #define reg_cfoe_ffoe_en_lsb 0 | ||
2001 | #define xd_p_reg_cfoe_ffoe_dis 0xA332 | ||
2002 | #define reg_cfoe_ffoe_dis_pos 1 | ||
2003 | #define reg_cfoe_ffoe_dis_len 1 | ||
2004 | #define reg_cfoe_ffoe_dis_lsb 0 | ||
2005 | #define xd_p_reg_cfoe_ffoe_rst 0xA332 | ||
2006 | #define reg_cfoe_ffoe_rst_pos 2 | ||
2007 | #define reg_cfoe_ffoe_rst_len 1 | ||
2008 | #define reg_cfoe_ffoe_rst_lsb 0 | ||
2009 | #define xd_p_reg_cfoe_ifoe_en 0xA332 | ||
2010 | #define reg_cfoe_ifoe_en_pos 3 | ||
2011 | #define reg_cfoe_ifoe_en_len 1 | ||
2012 | #define reg_cfoe_ifoe_en_lsb 0 | ||
2013 | #define xd_p_reg_cfoe_ifoe_dis 0xA332 | ||
2014 | #define reg_cfoe_ifoe_dis_pos 4 | ||
2015 | #define reg_cfoe_ifoe_dis_len 1 | ||
2016 | #define reg_cfoe_ifoe_dis_lsb 0 | ||
2017 | #define xd_p_reg_cfoe_ifoe_rst 0xA332 | ||
2018 | #define reg_cfoe_ifoe_rst_pos 5 | ||
2019 | #define reg_cfoe_ifoe_rst_len 1 | ||
2020 | #define reg_cfoe_ifoe_rst_lsb 0 | ||
2021 | #define xd_p_reg_cfoe_fot_en 0xA332 | ||
2022 | #define reg_cfoe_fot_en_pos 6 | ||
2023 | #define reg_cfoe_fot_en_len 1 | ||
2024 | #define reg_cfoe_fot_en_lsb 0 | ||
2025 | #define xd_p_reg_cfoe_fot_lm_en 0xA332 | ||
2026 | #define reg_cfoe_fot_lm_en_pos 7 | ||
2027 | #define reg_cfoe_fot_lm_en_len 1 | ||
2028 | #define reg_cfoe_fot_lm_en_lsb 0 | ||
2029 | #define xd_p_reg_cfoe_fot_rst 0xA333 | ||
2030 | #define reg_cfoe_fot_rst_pos 0 | ||
2031 | #define reg_cfoe_fot_rst_len 1 | ||
2032 | #define reg_cfoe_fot_rst_lsb 0 | ||
2033 | #define xd_r_fd_cfoe_ffoe_done 0xA333 | ||
2034 | #define fd_cfoe_ffoe_done_pos 1 | ||
2035 | #define fd_cfoe_ffoe_done_len 1 | ||
2036 | #define fd_cfoe_ffoe_done_lsb 0 | ||
2037 | #define xd_p_fd_cfoe_metric_vld 0xA333 | ||
2038 | #define fd_cfoe_metric_vld_pos 2 | ||
2039 | #define fd_cfoe_metric_vld_len 1 | ||
2040 | #define fd_cfoe_metric_vld_lsb 0 | ||
2041 | #define xd_p_reg_cfoe_ifod_vld 0xA333 | ||
2042 | #define reg_cfoe_ifod_vld_pos 3 | ||
2043 | #define reg_cfoe_ifod_vld_len 1 | ||
2044 | #define reg_cfoe_ifod_vld_lsb 0 | ||
2045 | #define xd_r_fd_cfoe_ifoe_done 0xA333 | ||
2046 | #define fd_cfoe_ifoe_done_pos 4 | ||
2047 | #define fd_cfoe_ifoe_done_len 1 | ||
2048 | #define fd_cfoe_ifoe_done_lsb 0 | ||
2049 | #define xd_r_fd_cfoe_fot_valid 0xA333 | ||
2050 | #define fd_cfoe_fot_valid_pos 5 | ||
2051 | #define fd_cfoe_fot_valid_len 1 | ||
2052 | #define fd_cfoe_fot_valid_lsb 0 | ||
2053 | #define xd_p_reg_cfoe_divg_int 0xA333 | ||
2054 | #define reg_cfoe_divg_int_pos 6 | ||
2055 | #define reg_cfoe_divg_int_len 1 | ||
2056 | #define reg_cfoe_divg_int_lsb 0 | ||
2057 | #define xd_r_reg_cfoe_divg_flag 0xA333 | ||
2058 | #define reg_cfoe_divg_flag_pos 7 | ||
2059 | #define reg_cfoe_divg_flag_len 1 | ||
2060 | #define reg_cfoe_divg_flag_lsb 0 | ||
2061 | #define xd_p_reg_sfoe_en 0xA334 | ||
2062 | #define reg_sfoe_en_pos 0 | ||
2063 | #define reg_sfoe_en_len 1 | ||
2064 | #define reg_sfoe_en_lsb 0 | ||
2065 | #define xd_p_reg_sfoe_dis 0xA334 | ||
2066 | #define reg_sfoe_dis_pos 1 | ||
2067 | #define reg_sfoe_dis_len 1 | ||
2068 | #define reg_sfoe_dis_lsb 0 | ||
2069 | #define xd_p_reg_sfoe_rst 0xA334 | ||
2070 | #define reg_sfoe_rst_pos 2 | ||
2071 | #define reg_sfoe_rst_len 1 | ||
2072 | #define reg_sfoe_rst_lsb 0 | ||
2073 | #define xd_p_reg_sfoe_vld_int 0xA334 | ||
2074 | #define reg_sfoe_vld_int_pos 3 | ||
2075 | #define reg_sfoe_vld_int_len 1 | ||
2076 | #define reg_sfoe_vld_int_lsb 0 | ||
2077 | #define xd_p_reg_sfoe_lm_en 0xA334 | ||
2078 | #define reg_sfoe_lm_en_pos 4 | ||
2079 | #define reg_sfoe_lm_en_len 1 | ||
2080 | #define reg_sfoe_lm_en_lsb 0 | ||
2081 | #define xd_p_reg_sfoe_divg_int 0xA334 | ||
2082 | #define reg_sfoe_divg_int_pos 5 | ||
2083 | #define reg_sfoe_divg_int_len 1 | ||
2084 | #define reg_sfoe_divg_int_lsb 0 | ||
2085 | #define xd_r_reg_sfoe_divg_flag 0xA334 | ||
2086 | #define reg_sfoe_divg_flag_pos 6 | ||
2087 | #define reg_sfoe_divg_flag_len 1 | ||
2088 | #define reg_sfoe_divg_flag_lsb 0 | ||
2089 | #define xd_p_reg_fft_rst 0xA335 | ||
2090 | #define reg_fft_rst_pos 0 | ||
2091 | #define reg_fft_rst_len 1 | ||
2092 | #define reg_fft_rst_lsb 0 | ||
2093 | #define xd_p_reg_fft_fast_beacon 0xA335 | ||
2094 | #define reg_fft_fast_beacon_pos 1 | ||
2095 | #define reg_fft_fast_beacon_len 1 | ||
2096 | #define reg_fft_fast_beacon_lsb 0 | ||
2097 | #define xd_p_reg_fft_fast_valid 0xA335 | ||
2098 | #define reg_fft_fast_valid_pos 2 | ||
2099 | #define reg_fft_fast_valid_len 1 | ||
2100 | #define reg_fft_fast_valid_lsb 0 | ||
2101 | #define xd_p_reg_fft_mask_en 0xA335 | ||
2102 | #define reg_fft_mask_en_pos 3 | ||
2103 | #define reg_fft_mask_en_len 1 | ||
2104 | #define reg_fft_mask_en_lsb 0 | ||
2105 | #define xd_p_reg_fft_crc_en 0xA335 | ||
2106 | #define reg_fft_crc_en_pos 4 | ||
2107 | #define reg_fft_crc_en_len 1 | ||
2108 | #define reg_fft_crc_en_lsb 0 | ||
2109 | #define xd_p_reg_finr_en 0xA336 | ||
2110 | #define reg_finr_en_pos 0 | ||
2111 | #define reg_finr_en_len 1 | ||
2112 | #define reg_finr_en_lsb 0 | ||
2113 | #define xd_p_fd_fste_en 0xA337 | ||
2114 | #define fd_fste_en_pos 1 | ||
2115 | #define fd_fste_en_len 1 | ||
2116 | #define fd_fste_en_lsb 0 | ||
2117 | #define xd_p_fd_sqi_tps_level_shift 0xA338 | ||
2118 | #define fd_sqi_tps_level_shift_pos 0 | ||
2119 | #define fd_sqi_tps_level_shift_len 8 | ||
2120 | #define fd_sqi_tps_level_shift_lsb 0 | ||
2121 | #define xd_p_fd_pilot_ma_len 0xA339 | ||
2122 | #define fd_pilot_ma_len_pos 0 | ||
2123 | #define fd_pilot_ma_len_len 6 | ||
2124 | #define fd_pilot_ma_len_lsb 0 | ||
2125 | #define xd_p_fd_tps_ma_len 0xA33A | ||
2126 | #define fd_tps_ma_len_pos 0 | ||
2127 | #define fd_tps_ma_len_len 6 | ||
2128 | #define fd_tps_ma_len_lsb 0 | ||
2129 | #define xd_p_fd_sqi_s3 0xA33B | ||
2130 | #define fd_sqi_s3_pos 0 | ||
2131 | #define fd_sqi_s3_len 8 | ||
2132 | #define fd_sqi_s3_lsb 0 | ||
2133 | #define xd_p_fd_sqi_dummy_reg_0 0xA33C | ||
2134 | #define fd_sqi_dummy_reg_0_pos 0 | ||
2135 | #define fd_sqi_dummy_reg_0_len 1 | ||
2136 | #define fd_sqi_dummy_reg_0_lsb 0 | ||
2137 | #define xd_p_fd_sqi_debug_sel 0xA33C | ||
2138 | #define fd_sqi_debug_sel_pos 1 | ||
2139 | #define fd_sqi_debug_sel_len 2 | ||
2140 | #define fd_sqi_debug_sel_lsb 0 | ||
2141 | #define xd_p_fd_sqi_s2 0xA33C | ||
2142 | #define fd_sqi_s2_pos 3 | ||
2143 | #define fd_sqi_s2_len 5 | ||
2144 | #define fd_sqi_s2_lsb 0 | ||
2145 | #define xd_p_fd_sqi_dummy_reg_1 0xA33D | ||
2146 | #define fd_sqi_dummy_reg_1_pos 0 | ||
2147 | #define fd_sqi_dummy_reg_1_len 1 | ||
2148 | #define fd_sqi_dummy_reg_1_lsb 0 | ||
2149 | #define xd_p_fd_inr_ignore 0xA33D | ||
2150 | #define fd_inr_ignore_pos 1 | ||
2151 | #define fd_inr_ignore_len 1 | ||
2152 | #define fd_inr_ignore_lsb 0 | ||
2153 | #define xd_p_fd_pilot_ignore 0xA33D | ||
2154 | #define fd_pilot_ignore_pos 2 | ||
2155 | #define fd_pilot_ignore_len 1 | ||
2156 | #define fd_pilot_ignore_lsb 0 | ||
2157 | #define xd_p_fd_etps_ignore 0xA33D | ||
2158 | #define fd_etps_ignore_pos 3 | ||
2159 | #define fd_etps_ignore_len 1 | ||
2160 | #define fd_etps_ignore_lsb 0 | ||
2161 | #define xd_p_fd_sqi_s1 0xA33D | ||
2162 | #define fd_sqi_s1_pos 4 | ||
2163 | #define fd_sqi_s1_len 4 | ||
2164 | #define fd_sqi_s1_lsb 0 | ||
2165 | #define xd_p_reg_fste_ehw_7_0 0xA33E | ||
2166 | #define reg_fste_ehw_7_0_pos 0 | ||
2167 | #define reg_fste_ehw_7_0_len 8 | ||
2168 | #define reg_fste_ehw_7_0_lsb 0 | ||
2169 | #define xd_p_reg_fste_ehw_9_8 0xA33F | ||
2170 | #define reg_fste_ehw_9_8_pos 0 | ||
2171 | #define reg_fste_ehw_9_8_len 2 | ||
2172 | #define reg_fste_ehw_9_8_lsb 8 | ||
2173 | #define xd_p_reg_fste_i_adj_vld 0xA33F | ||
2174 | #define reg_fste_i_adj_vld_pos 2 | ||
2175 | #define reg_fste_i_adj_vld_len 1 | ||
2176 | #define reg_fste_i_adj_vld_lsb 0 | ||
2177 | #define xd_p_reg_fste_phase_ini_7_0 0xA340 | ||
2178 | #define reg_fste_phase_ini_7_0_pos 0 | ||
2179 | #define reg_fste_phase_ini_7_0_len 8 | ||
2180 | #define reg_fste_phase_ini_7_0_lsb 0 | ||
2181 | #define xd_p_reg_fste_phase_ini_11_8 0xA341 | ||
2182 | #define reg_fste_phase_ini_11_8_pos 0 | ||
2183 | #define reg_fste_phase_ini_11_8_len 4 | ||
2184 | #define reg_fste_phase_ini_11_8_lsb 8 | ||
2185 | #define xd_p_reg_fste_phase_inc_3_0 0xA341 | ||
2186 | #define reg_fste_phase_inc_3_0_pos 4 | ||
2187 | #define reg_fste_phase_inc_3_0_len 4 | ||
2188 | #define reg_fste_phase_inc_3_0_lsb 0 | ||
2189 | #define xd_p_reg_fste_phase_inc_11_4 0xA342 | ||
2190 | #define reg_fste_phase_inc_11_4_pos 0 | ||
2191 | #define reg_fste_phase_inc_11_4_len 8 | ||
2192 | #define reg_fste_phase_inc_11_4_lsb 4 | ||
2193 | #define xd_p_reg_fste_acum_cost_cnt_max 0xA343 | ||
2194 | #define reg_fste_acum_cost_cnt_max_pos 0 | ||
2195 | #define reg_fste_acum_cost_cnt_max_len 4 | ||
2196 | #define reg_fste_acum_cost_cnt_max_lsb 0 | ||
2197 | #define xd_p_reg_fste_step_size_std 0xA343 | ||
2198 | #define reg_fste_step_size_std_pos 4 | ||
2199 | #define reg_fste_step_size_std_len 4 | ||
2200 | #define reg_fste_step_size_std_lsb 0 | ||
2201 | #define xd_p_reg_fste_step_size_max 0xA344 | ||
2202 | #define reg_fste_step_size_max_pos 0 | ||
2203 | #define reg_fste_step_size_max_len 4 | ||
2204 | #define reg_fste_step_size_max_lsb 0 | ||
2205 | #define xd_p_reg_fste_step_size_min 0xA344 | ||
2206 | #define reg_fste_step_size_min_pos 4 | ||
2207 | #define reg_fste_step_size_min_len 4 | ||
2208 | #define reg_fste_step_size_min_lsb 0 | ||
2209 | #define xd_p_reg_fste_frac_step_size_7_0 0xA345 | ||
2210 | #define reg_fste_frac_step_size_7_0_pos 0 | ||
2211 | #define reg_fste_frac_step_size_7_0_len 8 | ||
2212 | #define reg_fste_frac_step_size_7_0_lsb 0 | ||
2213 | #define xd_p_reg_fste_frac_step_size_15_8 0xA346 | ||
2214 | #define reg_fste_frac_step_size_15_8_pos 0 | ||
2215 | #define reg_fste_frac_step_size_15_8_len 8 | ||
2216 | #define reg_fste_frac_step_size_15_8_lsb 8 | ||
2217 | #define xd_p_reg_fste_frac_step_size_19_16 0xA347 | ||
2218 | #define reg_fste_frac_step_size_19_16_pos 0 | ||
2219 | #define reg_fste_frac_step_size_19_16_len 4 | ||
2220 | #define reg_fste_frac_step_size_19_16_lsb 16 | ||
2221 | #define xd_p_reg_fste_rpd_dir_cnt_max 0xA347 | ||
2222 | #define reg_fste_rpd_dir_cnt_max_pos 4 | ||
2223 | #define reg_fste_rpd_dir_cnt_max_len 4 | ||
2224 | #define reg_fste_rpd_dir_cnt_max_lsb 0 | ||
2225 | #define xd_p_reg_fste_ehs 0xA348 | ||
2226 | #define reg_fste_ehs_pos 0 | ||
2227 | #define reg_fste_ehs_len 4 | ||
2228 | #define reg_fste_ehs_lsb 0 | ||
2229 | #define xd_p_reg_fste_frac_cost_cnt_max_3_0 0xA348 | ||
2230 | #define reg_fste_frac_cost_cnt_max_3_0_pos 4 | ||
2231 | #define reg_fste_frac_cost_cnt_max_3_0_len 4 | ||
2232 | #define reg_fste_frac_cost_cnt_max_3_0_lsb 0 | ||
2233 | #define xd_p_reg_fste_frac_cost_cnt_max_9_4 0xA349 | ||
2234 | #define reg_fste_frac_cost_cnt_max_9_4_pos 0 | ||
2235 | #define reg_fste_frac_cost_cnt_max_9_4_len 6 | ||
2236 | #define reg_fste_frac_cost_cnt_max_9_4_lsb 4 | ||
2237 | #define xd_p_reg_fste_w0_7_0 0xA34A | ||
2238 | #define reg_fste_w0_7_0_pos 0 | ||
2239 | #define reg_fste_w0_7_0_len 8 | ||
2240 | #define reg_fste_w0_7_0_lsb 0 | ||
2241 | #define xd_p_reg_fste_w0_11_8 0xA34B | ||
2242 | #define reg_fste_w0_11_8_pos 0 | ||
2243 | #define reg_fste_w0_11_8_len 4 | ||
2244 | #define reg_fste_w0_11_8_lsb 8 | ||
2245 | #define xd_p_reg_fste_w1_3_0 0xA34B | ||
2246 | #define reg_fste_w1_3_0_pos 4 | ||
2247 | #define reg_fste_w1_3_0_len 4 | ||
2248 | #define reg_fste_w1_3_0_lsb 0 | ||
2249 | #define xd_p_reg_fste_w1_11_4 0xA34C | ||
2250 | #define reg_fste_w1_11_4_pos 0 | ||
2251 | #define reg_fste_w1_11_4_len 8 | ||
2252 | #define reg_fste_w1_11_4_lsb 4 | ||
2253 | #define xd_p_reg_fste_w2_7_0 0xA34D | ||
2254 | #define reg_fste_w2_7_0_pos 0 | ||
2255 | #define reg_fste_w2_7_0_len 8 | ||
2256 | #define reg_fste_w2_7_0_lsb 0 | ||
2257 | #define xd_p_reg_fste_w2_11_8 0xA34E | ||
2258 | #define reg_fste_w2_11_8_pos 0 | ||
2259 | #define reg_fste_w2_11_8_len 4 | ||
2260 | #define reg_fste_w2_11_8_lsb 8 | ||
2261 | #define xd_p_reg_fste_w3_3_0 0xA34E | ||
2262 | #define reg_fste_w3_3_0_pos 4 | ||
2263 | #define reg_fste_w3_3_0_len 4 | ||
2264 | #define reg_fste_w3_3_0_lsb 0 | ||
2265 | #define xd_p_reg_fste_w3_11_4 0xA34F | ||
2266 | #define reg_fste_w3_11_4_pos 0 | ||
2267 | #define reg_fste_w3_11_4_len 8 | ||
2268 | #define reg_fste_w3_11_4_lsb 4 | ||
2269 | #define xd_p_reg_fste_w4_7_0 0xA350 | ||
2270 | #define reg_fste_w4_7_0_pos 0 | ||
2271 | #define reg_fste_w4_7_0_len 8 | ||
2272 | #define reg_fste_w4_7_0_lsb 0 | ||
2273 | #define xd_p_reg_fste_w4_11_8 0xA351 | ||
2274 | #define reg_fste_w4_11_8_pos 0 | ||
2275 | #define reg_fste_w4_11_8_len 4 | ||
2276 | #define reg_fste_w4_11_8_lsb 8 | ||
2277 | #define xd_p_reg_fste_w5_3_0 0xA351 | ||
2278 | #define reg_fste_w5_3_0_pos 4 | ||
2279 | #define reg_fste_w5_3_0_len 4 | ||
2280 | #define reg_fste_w5_3_0_lsb 0 | ||
2281 | #define xd_p_reg_fste_w5_11_4 0xA352 | ||
2282 | #define reg_fste_w5_11_4_pos 0 | ||
2283 | #define reg_fste_w5_11_4_len 8 | ||
2284 | #define reg_fste_w5_11_4_lsb 4 | ||
2285 | #define xd_p_reg_fste_w6_7_0 0xA353 | ||
2286 | #define reg_fste_w6_7_0_pos 0 | ||
2287 | #define reg_fste_w6_7_0_len 8 | ||
2288 | #define reg_fste_w6_7_0_lsb 0 | ||
2289 | #define xd_p_reg_fste_w6_11_8 0xA354 | ||
2290 | #define reg_fste_w6_11_8_pos 0 | ||
2291 | #define reg_fste_w6_11_8_len 4 | ||
2292 | #define reg_fste_w6_11_8_lsb 8 | ||
2293 | #define xd_p_reg_fste_w7_3_0 0xA354 | ||
2294 | #define reg_fste_w7_3_0_pos 4 | ||
2295 | #define reg_fste_w7_3_0_len 4 | ||
2296 | #define reg_fste_w7_3_0_lsb 0 | ||
2297 | #define xd_p_reg_fste_w7_11_4 0xA355 | ||
2298 | #define reg_fste_w7_11_4_pos 0 | ||
2299 | #define reg_fste_w7_11_4_len 8 | ||
2300 | #define reg_fste_w7_11_4_lsb 4 | ||
2301 | #define xd_p_reg_fste_w8_7_0 0xA356 | ||
2302 | #define reg_fste_w8_7_0_pos 0 | ||
2303 | #define reg_fste_w8_7_0_len 8 | ||
2304 | #define reg_fste_w8_7_0_lsb 0 | ||
2305 | #define xd_p_reg_fste_w8_11_8 0xA357 | ||
2306 | #define reg_fste_w8_11_8_pos 0 | ||
2307 | #define reg_fste_w8_11_8_len 4 | ||
2308 | #define reg_fste_w8_11_8_lsb 8 | ||
2309 | #define xd_p_reg_fste_w9_3_0 0xA357 | ||
2310 | #define reg_fste_w9_3_0_pos 4 | ||
2311 | #define reg_fste_w9_3_0_len 4 | ||
2312 | #define reg_fste_w9_3_0_lsb 0 | ||
2313 | #define xd_p_reg_fste_w9_11_4 0xA358 | ||
2314 | #define reg_fste_w9_11_4_pos 0 | ||
2315 | #define reg_fste_w9_11_4_len 8 | ||
2316 | #define reg_fste_w9_11_4_lsb 4 | ||
2317 | #define xd_p_reg_fste_wa_7_0 0xA359 | ||
2318 | #define reg_fste_wa_7_0_pos 0 | ||
2319 | #define reg_fste_wa_7_0_len 8 | ||
2320 | #define reg_fste_wa_7_0_lsb 0 | ||
2321 | #define xd_p_reg_fste_wa_11_8 0xA35A | ||
2322 | #define reg_fste_wa_11_8_pos 0 | ||
2323 | #define reg_fste_wa_11_8_len 4 | ||
2324 | #define reg_fste_wa_11_8_lsb 8 | ||
2325 | #define xd_p_reg_fste_wb_3_0 0xA35A | ||
2326 | #define reg_fste_wb_3_0_pos 4 | ||
2327 | #define reg_fste_wb_3_0_len 4 | ||
2328 | #define reg_fste_wb_3_0_lsb 0 | ||
2329 | #define xd_p_reg_fste_wb_11_4 0xA35B | ||
2330 | #define reg_fste_wb_11_4_pos 0 | ||
2331 | #define reg_fste_wb_11_4_len 8 | ||
2332 | #define reg_fste_wb_11_4_lsb 4 | ||
2333 | #define xd_r_fd_fste_i_adj 0xA35C | ||
2334 | #define fd_fste_i_adj_pos 0 | ||
2335 | #define fd_fste_i_adj_len 5 | ||
2336 | #define fd_fste_i_adj_lsb 0 | ||
2337 | #define xd_r_fd_fste_f_adj_7_0 0xA35D | ||
2338 | #define fd_fste_f_adj_7_0_pos 0 | ||
2339 | #define fd_fste_f_adj_7_0_len 8 | ||
2340 | #define fd_fste_f_adj_7_0_lsb 0 | ||
2341 | #define xd_r_fd_fste_f_adj_15_8 0xA35E | ||
2342 | #define fd_fste_f_adj_15_8_pos 0 | ||
2343 | #define fd_fste_f_adj_15_8_len 8 | ||
2344 | #define fd_fste_f_adj_15_8_lsb 8 | ||
2345 | #define xd_r_fd_fste_f_adj_19_16 0xA35F | ||
2346 | #define fd_fste_f_adj_19_16_pos 0 | ||
2347 | #define fd_fste_f_adj_19_16_len 4 | ||
2348 | #define fd_fste_f_adj_19_16_lsb 16 | ||
2349 | #define xd_p_reg_feq_Leak_Bypass 0xA366 | ||
2350 | #define reg_feq_Leak_Bypass_pos 0 | ||
2351 | #define reg_feq_Leak_Bypass_len 1 | ||
2352 | #define reg_feq_Leak_Bypass_lsb 0 | ||
2353 | #define xd_p_reg_feq_Leak_Mneg1 0xA366 | ||
2354 | #define reg_feq_Leak_Mneg1_pos 1 | ||
2355 | #define reg_feq_Leak_Mneg1_len 3 | ||
2356 | #define reg_feq_Leak_Mneg1_lsb 0 | ||
2357 | #define xd_p_reg_feq_Leak_B_ShiftQ 0xA366 | ||
2358 | #define reg_feq_Leak_B_ShiftQ_pos 4 | ||
2359 | #define reg_feq_Leak_B_ShiftQ_len 4 | ||
2360 | #define reg_feq_Leak_B_ShiftQ_lsb 0 | ||
2361 | #define xd_p_reg_feq_Leak_B_Float0 0xA367 | ||
2362 | #define reg_feq_Leak_B_Float0_pos 0 | ||
2363 | #define reg_feq_Leak_B_Float0_len 8 | ||
2364 | #define reg_feq_Leak_B_Float0_lsb 0 | ||
2365 | #define xd_p_reg_feq_Leak_B_Float1 0xA368 | ||
2366 | #define reg_feq_Leak_B_Float1_pos 0 | ||
2367 | #define reg_feq_Leak_B_Float1_len 8 | ||
2368 | #define reg_feq_Leak_B_Float1_lsb 0 | ||
2369 | #define xd_p_reg_feq_Leak_B_Float2 0xA369 | ||
2370 | #define reg_feq_Leak_B_Float2_pos 0 | ||
2371 | #define reg_feq_Leak_B_Float2_len 8 | ||
2372 | #define reg_feq_Leak_B_Float2_lsb 0 | ||
2373 | #define xd_p_reg_feq_Leak_B_Float3 0xA36A | ||
2374 | #define reg_feq_Leak_B_Float3_pos 0 | ||
2375 | #define reg_feq_Leak_B_Float3_len 8 | ||
2376 | #define reg_feq_Leak_B_Float3_lsb 0 | ||
2377 | #define xd_p_reg_feq_Leak_B_Float4 0xA36B | ||
2378 | #define reg_feq_Leak_B_Float4_pos 0 | ||
2379 | #define reg_feq_Leak_B_Float4_len 8 | ||
2380 | #define reg_feq_Leak_B_Float4_lsb 0 | ||
2381 | #define xd_p_reg_feq_Leak_B_Float5 0xA36C | ||
2382 | #define reg_feq_Leak_B_Float5_pos 0 | ||
2383 | #define reg_feq_Leak_B_Float5_len 8 | ||
2384 | #define reg_feq_Leak_B_Float5_lsb 0 | ||
2385 | #define xd_p_reg_feq_Leak_B_Float6 0xA36D | ||
2386 | #define reg_feq_Leak_B_Float6_pos 0 | ||
2387 | #define reg_feq_Leak_B_Float6_len 8 | ||
2388 | #define reg_feq_Leak_B_Float6_lsb 0 | ||
2389 | #define xd_p_reg_feq_Leak_B_Float7 0xA36E | ||
2390 | #define reg_feq_Leak_B_Float7_pos 0 | ||
2391 | #define reg_feq_Leak_B_Float7_len 8 | ||
2392 | #define reg_feq_Leak_B_Float7_lsb 0 | ||
2393 | #define xd_r_reg_feq_data_h2_7_0 0xA36F | ||
2394 | #define reg_feq_data_h2_7_0_pos 0 | ||
2395 | #define reg_feq_data_h2_7_0_len 8 | ||
2396 | #define reg_feq_data_h2_7_0_lsb 0 | ||
2397 | #define xd_r_reg_feq_data_h2_9_8 0xA370 | ||
2398 | #define reg_feq_data_h2_9_8_pos 0 | ||
2399 | #define reg_feq_data_h2_9_8_len 2 | ||
2400 | #define reg_feq_data_h2_9_8_lsb 8 | ||
2401 | #define xd_p_reg_feq_leak_use_slice_tps 0xA371 | ||
2402 | #define reg_feq_leak_use_slice_tps_pos 0 | ||
2403 | #define reg_feq_leak_use_slice_tps_len 1 | ||
2404 | #define reg_feq_leak_use_slice_tps_lsb 0 | ||
2405 | #define xd_p_reg_feq_read_update 0xA371 | ||
2406 | #define reg_feq_read_update_pos 1 | ||
2407 | #define reg_feq_read_update_len 1 | ||
2408 | #define reg_feq_read_update_lsb 0 | ||
2409 | #define xd_p_reg_feq_data_vld 0xA371 | ||
2410 | #define reg_feq_data_vld_pos 2 | ||
2411 | #define reg_feq_data_vld_len 1 | ||
2412 | #define reg_feq_data_vld_lsb 0 | ||
2413 | #define xd_p_reg_feq_tone_idx_4_0 0xA371 | ||
2414 | #define reg_feq_tone_idx_4_0_pos 3 | ||
2415 | #define reg_feq_tone_idx_4_0_len 5 | ||
2416 | #define reg_feq_tone_idx_4_0_lsb 0 | ||
2417 | #define xd_p_reg_feq_tone_idx_12_5 0xA372 | ||
2418 | #define reg_feq_tone_idx_12_5_pos 0 | ||
2419 | #define reg_feq_tone_idx_12_5_len 8 | ||
2420 | #define reg_feq_tone_idx_12_5_lsb 5 | ||
2421 | #define xd_r_reg_feq_data_re_7_0 0xA373 | ||
2422 | #define reg_feq_data_re_7_0_pos 0 | ||
2423 | #define reg_feq_data_re_7_0_len 8 | ||
2424 | #define reg_feq_data_re_7_0_lsb 0 | ||
2425 | #define xd_r_reg_feq_data_re_10_8 0xA374 | ||
2426 | #define reg_feq_data_re_10_8_pos 0 | ||
2427 | #define reg_feq_data_re_10_8_len 3 | ||
2428 | #define reg_feq_data_re_10_8_lsb 8 | ||
2429 | #define xd_r_reg_feq_data_im_7_0 0xA375 | ||
2430 | #define reg_feq_data_im_7_0_pos 0 | ||
2431 | #define reg_feq_data_im_7_0_len 8 | ||
2432 | #define reg_feq_data_im_7_0_lsb 0 | ||
2433 | #define xd_r_reg_feq_data_im_10_8 0xA376 | ||
2434 | #define reg_feq_data_im_10_8_pos 0 | ||
2435 | #define reg_feq_data_im_10_8_len 3 | ||
2436 | #define reg_feq_data_im_10_8_lsb 8 | ||
2437 | #define xd_r_reg_feq_y_re 0xA377 | ||
2438 | #define reg_feq_y_re_pos 0 | ||
2439 | #define reg_feq_y_re_len 8 | ||
2440 | #define reg_feq_y_re_lsb 0 | ||
2441 | #define xd_r_reg_feq_y_im 0xA378 | ||
2442 | #define reg_feq_y_im_pos 0 | ||
2443 | #define reg_feq_y_im_len 8 | ||
2444 | #define reg_feq_y_im_lsb 0 | ||
2445 | #define xd_r_reg_feq_h_re_7_0 0xA379 | ||
2446 | #define reg_feq_h_re_7_0_pos 0 | ||
2447 | #define reg_feq_h_re_7_0_len 8 | ||
2448 | #define reg_feq_h_re_7_0_lsb 0 | ||
2449 | #define xd_r_reg_feq_h_re_8 0xA37A | ||
2450 | #define reg_feq_h_re_8_pos 0 | ||
2451 | #define reg_feq_h_re_8_len 1 | ||
2452 | #define reg_feq_h_re_8_lsb 0 | ||
2453 | #define xd_r_reg_feq_h_im_7_0 0xA37B | ||
2454 | #define reg_feq_h_im_7_0_pos 0 | ||
2455 | #define reg_feq_h_im_7_0_len 8 | ||
2456 | #define reg_feq_h_im_7_0_lsb 0 | ||
2457 | #define xd_r_reg_feq_h_im_8 0xA37C | ||
2458 | #define reg_feq_h_im_8_pos 0 | ||
2459 | #define reg_feq_h_im_8_len 1 | ||
2460 | #define reg_feq_h_im_8_lsb 0 | ||
2461 | #define xd_p_fec_super_frm_unit_7_0 0xA380 | ||
2462 | #define fec_super_frm_unit_7_0_pos 0 | ||
2463 | #define fec_super_frm_unit_7_0_len 8 | ||
2464 | #define fec_super_frm_unit_7_0_lsb 0 | ||
2465 | #define xd_p_fec_super_frm_unit_15_8 0xA381 | ||
2466 | #define fec_super_frm_unit_15_8_pos 0 | ||
2467 | #define fec_super_frm_unit_15_8_len 8 | ||
2468 | #define fec_super_frm_unit_15_8_lsb 8 | ||
2469 | #define xd_r_fec_vtb_err_bit_cnt_7_0 0xA382 | ||
2470 | #define fec_vtb_err_bit_cnt_7_0_pos 0 | ||
2471 | #define fec_vtb_err_bit_cnt_7_0_len 8 | ||
2472 | #define fec_vtb_err_bit_cnt_7_0_lsb 0 | ||
2473 | #define xd_r_fec_vtb_err_bit_cnt_15_8 0xA383 | ||
2474 | #define fec_vtb_err_bit_cnt_15_8_pos 0 | ||
2475 | #define fec_vtb_err_bit_cnt_15_8_len 8 | ||
2476 | #define fec_vtb_err_bit_cnt_15_8_lsb 8 | ||
2477 | #define xd_r_fec_vtb_err_bit_cnt_23_16 0xA384 | ||
2478 | #define fec_vtb_err_bit_cnt_23_16_pos 0 | ||
2479 | #define fec_vtb_err_bit_cnt_23_16_len 8 | ||
2480 | #define fec_vtb_err_bit_cnt_23_16_lsb 16 | ||
2481 | #define xd_p_fec_rsd_packet_unit_7_0 0xA385 | ||
2482 | #define fec_rsd_packet_unit_7_0_pos 0 | ||
2483 | #define fec_rsd_packet_unit_7_0_len 8 | ||
2484 | #define fec_rsd_packet_unit_7_0_lsb 0 | ||
2485 | #define xd_p_fec_rsd_packet_unit_15_8 0xA386 | ||
2486 | #define fec_rsd_packet_unit_15_8_pos 0 | ||
2487 | #define fec_rsd_packet_unit_15_8_len 8 | ||
2488 | #define fec_rsd_packet_unit_15_8_lsb 8 | ||
2489 | #define xd_r_fec_rsd_bit_err_cnt_7_0 0xA387 | ||
2490 | #define fec_rsd_bit_err_cnt_7_0_pos 0 | ||
2491 | #define fec_rsd_bit_err_cnt_7_0_len 8 | ||
2492 | #define fec_rsd_bit_err_cnt_7_0_lsb 0 | ||
2493 | #define xd_r_fec_rsd_bit_err_cnt_15_8 0xA388 | ||
2494 | #define fec_rsd_bit_err_cnt_15_8_pos 0 | ||
2495 | #define fec_rsd_bit_err_cnt_15_8_len 8 | ||
2496 | #define fec_rsd_bit_err_cnt_15_8_lsb 8 | ||
2497 | #define xd_r_fec_rsd_bit_err_cnt_23_16 0xA389 | ||
2498 | #define fec_rsd_bit_err_cnt_23_16_pos 0 | ||
2499 | #define fec_rsd_bit_err_cnt_23_16_len 8 | ||
2500 | #define fec_rsd_bit_err_cnt_23_16_lsb 16 | ||
2501 | #define xd_r_fec_rsd_abort_packet_cnt_7_0 0xA38A | ||
2502 | #define fec_rsd_abort_packet_cnt_7_0_pos 0 | ||
2503 | #define fec_rsd_abort_packet_cnt_7_0_len 8 | ||
2504 | #define fec_rsd_abort_packet_cnt_7_0_lsb 0 | ||
2505 | #define xd_r_fec_rsd_abort_packet_cnt_15_8 0xA38B | ||
2506 | #define fec_rsd_abort_packet_cnt_15_8_pos 0 | ||
2507 | #define fec_rsd_abort_packet_cnt_15_8_len 8 | ||
2508 | #define fec_rsd_abort_packet_cnt_15_8_lsb 8 | ||
2509 | #define xd_p_fec_RSD_PKT_NUM_PER_UNIT_7_0 0xA38C | ||
2510 | #define fec_RSD_PKT_NUM_PER_UNIT_7_0_pos 0 | ||
2511 | #define fec_RSD_PKT_NUM_PER_UNIT_7_0_len 8 | ||
2512 | #define fec_RSD_PKT_NUM_PER_UNIT_7_0_lsb 0 | ||
2513 | #define xd_p_fec_RSD_PKT_NUM_PER_UNIT_15_8 0xA38D | ||
2514 | #define fec_RSD_PKT_NUM_PER_UNIT_15_8_pos 0 | ||
2515 | #define fec_RSD_PKT_NUM_PER_UNIT_15_8_len 8 | ||
2516 | #define fec_RSD_PKT_NUM_PER_UNIT_15_8_lsb 8 | ||
2517 | #define xd_p_fec_RS_TH_1_7_0 0xA38E | ||
2518 | #define fec_RS_TH_1_7_0_pos 0 | ||
2519 | #define fec_RS_TH_1_7_0_len 8 | ||
2520 | #define fec_RS_TH_1_7_0_lsb 0 | ||
2521 | #define xd_p_fec_RS_TH_1_15_8 0xA38F | ||
2522 | #define fec_RS_TH_1_15_8_pos 0 | ||
2523 | #define fec_RS_TH_1_15_8_len 8 | ||
2524 | #define fec_RS_TH_1_15_8_lsb 8 | ||
2525 | #define xd_p_fec_RS_TH_2 0xA390 | ||
2526 | #define fec_RS_TH_2_pos 0 | ||
2527 | #define fec_RS_TH_2_len 8 | ||
2528 | #define fec_RS_TH_2_lsb 0 | ||
2529 | #define xd_p_fec_mon_en 0xA391 | ||
2530 | #define fec_mon_en_pos 0 | ||
2531 | #define fec_mon_en_len 1 | ||
2532 | #define fec_mon_en_lsb 0 | ||
2533 | #define xd_p_reg_b8to47 0xA391 | ||
2534 | #define reg_b8to47_pos 1 | ||
2535 | #define reg_b8to47_len 1 | ||
2536 | #define reg_b8to47_lsb 0 | ||
2537 | #define xd_p_reg_rsd_sync_rep 0xA391 | ||
2538 | #define reg_rsd_sync_rep_pos 2 | ||
2539 | #define reg_rsd_sync_rep_len 1 | ||
2540 | #define reg_rsd_sync_rep_lsb 0 | ||
2541 | #define xd_p_fec_rsd_retrain_rst 0xA391 | ||
2542 | #define fec_rsd_retrain_rst_pos 3 | ||
2543 | #define fec_rsd_retrain_rst_len 1 | ||
2544 | #define fec_rsd_retrain_rst_lsb 0 | ||
2545 | #define xd_r_fec_rsd_ber_rdy 0xA391 | ||
2546 | #define fec_rsd_ber_rdy_pos 4 | ||
2547 | #define fec_rsd_ber_rdy_len 1 | ||
2548 | #define fec_rsd_ber_rdy_lsb 0 | ||
2549 | #define xd_p_fec_rsd_ber_rst 0xA391 | ||
2550 | #define fec_rsd_ber_rst_pos 5 | ||
2551 | #define fec_rsd_ber_rst_len 1 | ||
2552 | #define fec_rsd_ber_rst_lsb 0 | ||
2553 | #define xd_r_fec_vtb_ber_rdy 0xA391 | ||
2554 | #define fec_vtb_ber_rdy_pos 6 | ||
2555 | #define fec_vtb_ber_rdy_len 1 | ||
2556 | #define fec_vtb_ber_rdy_lsb 0 | ||
2557 | #define xd_p_fec_vtb_ber_rst 0xA391 | ||
2558 | #define fec_vtb_ber_rst_pos 7 | ||
2559 | #define fec_vtb_ber_rst_len 1 | ||
2560 | #define fec_vtb_ber_rst_lsb 0 | ||
2561 | #define xd_p_reg_vtb_clk40en 0xA392 | ||
2562 | #define reg_vtb_clk40en_pos 0 | ||
2563 | #define reg_vtb_clk40en_len 1 | ||
2564 | #define reg_vtb_clk40en_lsb 0 | ||
2565 | #define xd_p_fec_vtb_rsd_mon_en 0xA392 | ||
2566 | #define fec_vtb_rsd_mon_en_pos 1 | ||
2567 | #define fec_vtb_rsd_mon_en_len 1 | ||
2568 | #define fec_vtb_rsd_mon_en_lsb 0 | ||
2569 | #define xd_p_reg_fec_data_en 0xA392 | ||
2570 | #define reg_fec_data_en_pos 2 | ||
2571 | #define reg_fec_data_en_len 1 | ||
2572 | #define reg_fec_data_en_lsb 0 | ||
2573 | #define xd_p_fec_dummy_reg_2 0xA392 | ||
2574 | #define fec_dummy_reg_2_pos 3 | ||
2575 | #define fec_dummy_reg_2_len 3 | ||
2576 | #define fec_dummy_reg_2_lsb 0 | ||
2577 | #define xd_p_reg_sync_chk 0xA392 | ||
2578 | #define reg_sync_chk_pos 6 | ||
2579 | #define reg_sync_chk_len 1 | ||
2580 | #define reg_sync_chk_lsb 0 | ||
2581 | #define xd_p_fec_rsd_bypass 0xA392 | ||
2582 | #define fec_rsd_bypass_pos 7 | ||
2583 | #define fec_rsd_bypass_len 1 | ||
2584 | #define fec_rsd_bypass_lsb 0 | ||
2585 | #define xd_p_fec_sw_rst 0xA393 | ||
2586 | #define fec_sw_rst_pos 0 | ||
2587 | #define fec_sw_rst_len 1 | ||
2588 | #define fec_sw_rst_lsb 0 | ||
2589 | #define xd_r_fec_vtb_pm_crc 0xA394 | ||
2590 | #define fec_vtb_pm_crc_pos 0 | ||
2591 | #define fec_vtb_pm_crc_len 8 | ||
2592 | #define fec_vtb_pm_crc_lsb 0 | ||
2593 | #define xd_r_fec_vtb_tb_7_crc 0xA395 | ||
2594 | #define fec_vtb_tb_7_crc_pos 0 | ||
2595 | #define fec_vtb_tb_7_crc_len 8 | ||
2596 | #define fec_vtb_tb_7_crc_lsb 0 | ||
2597 | #define xd_r_fec_vtb_tb_6_crc 0xA396 | ||
2598 | #define fec_vtb_tb_6_crc_pos 0 | ||
2599 | #define fec_vtb_tb_6_crc_len 8 | ||
2600 | #define fec_vtb_tb_6_crc_lsb 0 | ||
2601 | #define xd_r_fec_vtb_tb_5_crc 0xA397 | ||
2602 | #define fec_vtb_tb_5_crc_pos 0 | ||
2603 | #define fec_vtb_tb_5_crc_len 8 | ||
2604 | #define fec_vtb_tb_5_crc_lsb 0 | ||
2605 | #define xd_r_fec_vtb_tb_4_crc 0xA398 | ||
2606 | #define fec_vtb_tb_4_crc_pos 0 | ||
2607 | #define fec_vtb_tb_4_crc_len 8 | ||
2608 | #define fec_vtb_tb_4_crc_lsb 0 | ||
2609 | #define xd_r_fec_vtb_tb_3_crc 0xA399 | ||
2610 | #define fec_vtb_tb_3_crc_pos 0 | ||
2611 | #define fec_vtb_tb_3_crc_len 8 | ||
2612 | #define fec_vtb_tb_3_crc_lsb 0 | ||
2613 | #define xd_r_fec_vtb_tb_2_crc 0xA39A | ||
2614 | #define fec_vtb_tb_2_crc_pos 0 | ||
2615 | #define fec_vtb_tb_2_crc_len 8 | ||
2616 | #define fec_vtb_tb_2_crc_lsb 0 | ||
2617 | #define xd_r_fec_vtb_tb_1_crc 0xA39B | ||
2618 | #define fec_vtb_tb_1_crc_pos 0 | ||
2619 | #define fec_vtb_tb_1_crc_len 8 | ||
2620 | #define fec_vtb_tb_1_crc_lsb 0 | ||
2621 | #define xd_r_fec_vtb_tb_0_crc 0xA39C | ||
2622 | #define fec_vtb_tb_0_crc_pos 0 | ||
2623 | #define fec_vtb_tb_0_crc_len 8 | ||
2624 | #define fec_vtb_tb_0_crc_lsb 0 | ||
2625 | #define xd_r_fec_rsd_bank0_crc 0xA39D | ||
2626 | #define fec_rsd_bank0_crc_pos 0 | ||
2627 | #define fec_rsd_bank0_crc_len 8 | ||
2628 | #define fec_rsd_bank0_crc_lsb 0 | ||
2629 | #define xd_r_fec_rsd_bank1_crc 0xA39E | ||
2630 | #define fec_rsd_bank1_crc_pos 0 | ||
2631 | #define fec_rsd_bank1_crc_len 8 | ||
2632 | #define fec_rsd_bank1_crc_lsb 0 | ||
2633 | #define xd_r_fec_idi_vtb_crc 0xA39F | ||
2634 | #define fec_idi_vtb_crc_pos 0 | ||
2635 | #define fec_idi_vtb_crc_len 8 | ||
2636 | #define fec_idi_vtb_crc_lsb 0 | ||
2637 | #define xd_g_reg_tpsd_txmod 0xA3C0 | ||
2638 | #define reg_tpsd_txmod_pos 0 | ||
2639 | #define reg_tpsd_txmod_len 2 | ||
2640 | #define reg_tpsd_txmod_lsb 0 | ||
2641 | #define xd_g_reg_tpsd_gi 0xA3C0 | ||
2642 | #define reg_tpsd_gi_pos 2 | ||
2643 | #define reg_tpsd_gi_len 2 | ||
2644 | #define reg_tpsd_gi_lsb 0 | ||
2645 | #define xd_g_reg_tpsd_hier 0xA3C0 | ||
2646 | #define reg_tpsd_hier_pos 4 | ||
2647 | #define reg_tpsd_hier_len 3 | ||
2648 | #define reg_tpsd_hier_lsb 0 | ||
2649 | #define xd_g_reg_bw 0xA3C1 | ||
2650 | #define reg_bw_pos 2 | ||
2651 | #define reg_bw_len 2 | ||
2652 | #define reg_bw_lsb 0 | ||
2653 | #define xd_g_reg_dec_pri 0xA3C1 | ||
2654 | #define reg_dec_pri_pos 4 | ||
2655 | #define reg_dec_pri_len 1 | ||
2656 | #define reg_dec_pri_lsb 0 | ||
2657 | #define xd_g_reg_tpsd_const 0xA3C1 | ||
2658 | #define reg_tpsd_const_pos 6 | ||
2659 | #define reg_tpsd_const_len 2 | ||
2660 | #define reg_tpsd_const_lsb 0 | ||
2661 | #define xd_g_reg_tpsd_hpcr 0xA3C2 | ||
2662 | #define reg_tpsd_hpcr_pos 0 | ||
2663 | #define reg_tpsd_hpcr_len 3 | ||
2664 | #define reg_tpsd_hpcr_lsb 0 | ||
2665 | #define xd_g_reg_tpsd_lpcr 0xA3C2 | ||
2666 | #define reg_tpsd_lpcr_pos 3 | ||
2667 | #define reg_tpsd_lpcr_len 3 | ||
2668 | #define reg_tpsd_lpcr_lsb 0 | ||
2669 | #define xd_g_reg_ofsm_clk 0xA3D0 | ||
2670 | #define reg_ofsm_clk_pos 0 | ||
2671 | #define reg_ofsm_clk_len 3 | ||
2672 | #define reg_ofsm_clk_lsb 0 | ||
2673 | #define xd_g_reg_fclk_cfg 0xA3D1 | ||
2674 | #define reg_fclk_cfg_pos 0 | ||
2675 | #define reg_fclk_cfg_len 1 | ||
2676 | #define reg_fclk_cfg_lsb 0 | ||
2677 | #define xd_g_reg_fclk_idi 0xA3D1 | ||
2678 | #define reg_fclk_idi_pos 1 | ||
2679 | #define reg_fclk_idi_len 1 | ||
2680 | #define reg_fclk_idi_lsb 0 | ||
2681 | #define xd_g_reg_fclk_odi 0xA3D1 | ||
2682 | #define reg_fclk_odi_pos 2 | ||
2683 | #define reg_fclk_odi_len 1 | ||
2684 | #define reg_fclk_odi_lsb 0 | ||
2685 | #define xd_g_reg_fclk_rsd 0xA3D1 | ||
2686 | #define reg_fclk_rsd_pos 3 | ||
2687 | #define reg_fclk_rsd_len 1 | ||
2688 | #define reg_fclk_rsd_lsb 0 | ||
2689 | #define xd_g_reg_fclk_vtb 0xA3D1 | ||
2690 | #define reg_fclk_vtb_pos 4 | ||
2691 | #define reg_fclk_vtb_len 1 | ||
2692 | #define reg_fclk_vtb_lsb 0 | ||
2693 | #define xd_g_reg_fclk_cste 0xA3D1 | ||
2694 | #define reg_fclk_cste_pos 5 | ||
2695 | #define reg_fclk_cste_len 1 | ||
2696 | #define reg_fclk_cste_lsb 0 | ||
2697 | #define xd_g_reg_fclk_mp2if 0xA3D1 | ||
2698 | #define reg_fclk_mp2if_pos 6 | ||
2699 | #define reg_fclk_mp2if_len 1 | ||
2700 | #define reg_fclk_mp2if_lsb 0 | ||
2701 | #define xd_I2C_i2c_m_slave_addr 0xA400 | ||
2702 | #define i2c_m_slave_addr_pos 0 | ||
2703 | #define i2c_m_slave_addr_len 8 | ||
2704 | #define i2c_m_slave_addr_lsb 0 | ||
2705 | #define xd_I2C_i2c_m_data1 0xA401 | ||
2706 | #define i2c_m_data1_pos 0 | ||
2707 | #define i2c_m_data1_len 8 | ||
2708 | #define i2c_m_data1_lsb 0 | ||
2709 | #define xd_I2C_i2c_m_data2 0xA402 | ||
2710 | #define i2c_m_data2_pos 0 | ||
2711 | #define i2c_m_data2_len 8 | ||
2712 | #define i2c_m_data2_lsb 0 | ||
2713 | #define xd_I2C_i2c_m_data3 0xA403 | ||
2714 | #define i2c_m_data3_pos 0 | ||
2715 | #define i2c_m_data3_len 8 | ||
2716 | #define i2c_m_data3_lsb 0 | ||
2717 | #define xd_I2C_i2c_m_data4 0xA404 | ||
2718 | #define i2c_m_data4_pos 0 | ||
2719 | #define i2c_m_data4_len 8 | ||
2720 | #define i2c_m_data4_lsb 0 | ||
2721 | #define xd_I2C_i2c_m_data5 0xA405 | ||
2722 | #define i2c_m_data5_pos 0 | ||
2723 | #define i2c_m_data5_len 8 | ||
2724 | #define i2c_m_data5_lsb 0 | ||
2725 | #define xd_I2C_i2c_m_data6 0xA406 | ||
2726 | #define i2c_m_data6_pos 0 | ||
2727 | #define i2c_m_data6_len 8 | ||
2728 | #define i2c_m_data6_lsb 0 | ||
2729 | #define xd_I2C_i2c_m_data7 0xA407 | ||
2730 | #define i2c_m_data7_pos 0 | ||
2731 | #define i2c_m_data7_len 8 | ||
2732 | #define i2c_m_data7_lsb 0 | ||
2733 | #define xd_I2C_i2c_m_data8 0xA408 | ||
2734 | #define i2c_m_data8_pos 0 | ||
2735 | #define i2c_m_data8_len 8 | ||
2736 | #define i2c_m_data8_lsb 0 | ||
2737 | #define xd_I2C_i2c_m_data9 0xA409 | ||
2738 | #define i2c_m_data9_pos 0 | ||
2739 | #define i2c_m_data9_len 8 | ||
2740 | #define i2c_m_data9_lsb 0 | ||
2741 | #define xd_I2C_i2c_m_data10 0xA40A | ||
2742 | #define i2c_m_data10_pos 0 | ||
2743 | #define i2c_m_data10_len 8 | ||
2744 | #define i2c_m_data10_lsb 0 | ||
2745 | #define xd_I2C_i2c_m_data11 0xA40B | ||
2746 | #define i2c_m_data11_pos 0 | ||
2747 | #define i2c_m_data11_len 8 | ||
2748 | #define i2c_m_data11_lsb 0 | ||
2749 | #define xd_I2C_i2c_m_cmd_rw 0xA40C | ||
2750 | #define i2c_m_cmd_rw_pos 0 | ||
2751 | #define i2c_m_cmd_rw_len 1 | ||
2752 | #define i2c_m_cmd_rw_lsb 0 | ||
2753 | #define xd_I2C_i2c_m_cmd_rwlen 0xA40C | ||
2754 | #define i2c_m_cmd_rwlen_pos 3 | ||
2755 | #define i2c_m_cmd_rwlen_len 4 | ||
2756 | #define i2c_m_cmd_rwlen_lsb 0 | ||
2757 | #define xd_I2C_i2c_m_status_cmd_exe 0xA40D | ||
2758 | #define i2c_m_status_cmd_exe_pos 0 | ||
2759 | #define i2c_m_status_cmd_exe_len 1 | ||
2760 | #define i2c_m_status_cmd_exe_lsb 0 | ||
2761 | #define xd_I2C_i2c_m_status_wdat_done 0xA40D | ||
2762 | #define i2c_m_status_wdat_done_pos 1 | ||
2763 | #define i2c_m_status_wdat_done_len 1 | ||
2764 | #define i2c_m_status_wdat_done_lsb 0 | ||
2765 | #define xd_I2C_i2c_m_status_wdat_fail 0xA40D | ||
2766 | #define i2c_m_status_wdat_fail_pos 2 | ||
2767 | #define i2c_m_status_wdat_fail_len 1 | ||
2768 | #define i2c_m_status_wdat_fail_lsb 0 | ||
2769 | #define xd_I2C_i2c_m_period 0xA40E | ||
2770 | #define i2c_m_period_pos 0 | ||
2771 | #define i2c_m_period_len 8 | ||
2772 | #define i2c_m_period_lsb 0 | ||
2773 | #define xd_I2C_i2c_m_reg_msb_lsb 0xA40F | ||
2774 | #define i2c_m_reg_msb_lsb_pos 0 | ||
2775 | #define i2c_m_reg_msb_lsb_len 1 | ||
2776 | #define i2c_m_reg_msb_lsb_lsb 0 | ||
2777 | #define xd_I2C_reg_ofdm_rst 0xA40F | ||
2778 | #define reg_ofdm_rst_pos 1 | ||
2779 | #define reg_ofdm_rst_len 1 | ||
2780 | #define reg_ofdm_rst_lsb 0 | ||
2781 | #define xd_I2C_reg_sample_period_on_tuner 0xA40F | ||
2782 | #define reg_sample_period_on_tuner_pos 2 | ||
2783 | #define reg_sample_period_on_tuner_len 1 | ||
2784 | #define reg_sample_period_on_tuner_lsb 0 | ||
2785 | #define xd_I2C_reg_rst_i2c 0xA40F | ||
2786 | #define reg_rst_i2c_pos 3 | ||
2787 | #define reg_rst_i2c_len 1 | ||
2788 | #define reg_rst_i2c_lsb 0 | ||
2789 | #define xd_I2C_reg_ofdm_rst_en 0xA40F | ||
2790 | #define reg_ofdm_rst_en_pos 4 | ||
2791 | #define reg_ofdm_rst_en_len 1 | ||
2792 | #define reg_ofdm_rst_en_lsb 0 | ||
2793 | #define xd_I2C_reg_tuner_sda_sync_on 0xA40F | ||
2794 | #define reg_tuner_sda_sync_on_pos 5 | ||
2795 | #define reg_tuner_sda_sync_on_len 1 | ||
2796 | #define reg_tuner_sda_sync_on_lsb 0 | ||
2797 | #define xd_p_mp2if_data_access_disable_ofsm 0xA500 | ||
2798 | #define mp2if_data_access_disable_ofsm_pos 0 | ||
2799 | #define mp2if_data_access_disable_ofsm_len 1 | ||
2800 | #define mp2if_data_access_disable_ofsm_lsb 0 | ||
2801 | #define xd_p_reg_mp2_sw_rst_ofsm 0xA500 | ||
2802 | #define reg_mp2_sw_rst_ofsm_pos 1 | ||
2803 | #define reg_mp2_sw_rst_ofsm_len 1 | ||
2804 | #define reg_mp2_sw_rst_ofsm_lsb 0 | ||
2805 | #define xd_p_reg_mp2if_clk_en_ofsm 0xA500 | ||
2806 | #define reg_mp2if_clk_en_ofsm_pos 2 | ||
2807 | #define reg_mp2if_clk_en_ofsm_len 1 | ||
2808 | #define reg_mp2if_clk_en_ofsm_lsb 0 | ||
2809 | #define xd_r_mp2if_sync_byte_locked 0xA500 | ||
2810 | #define mp2if_sync_byte_locked_pos 3 | ||
2811 | #define mp2if_sync_byte_locked_len 1 | ||
2812 | #define mp2if_sync_byte_locked_lsb 0 | ||
2813 | #define xd_r_mp2if_ts_not_188 0xA500 | ||
2814 | #define mp2if_ts_not_188_pos 4 | ||
2815 | #define mp2if_ts_not_188_len 1 | ||
2816 | #define mp2if_ts_not_188_lsb 0 | ||
2817 | #define xd_r_mp2if_psb_empty 0xA500 | ||
2818 | #define mp2if_psb_empty_pos 5 | ||
2819 | #define mp2if_psb_empty_len 1 | ||
2820 | #define mp2if_psb_empty_lsb 0 | ||
2821 | #define xd_r_mp2if_psb_overflow 0xA500 | ||
2822 | #define mp2if_psb_overflow_pos 6 | ||
2823 | #define mp2if_psb_overflow_len 1 | ||
2824 | #define mp2if_psb_overflow_lsb 0 | ||
2825 | #define xd_p_mp2if_keep_sf_sync_byte_ofsm 0xA500 | ||
2826 | #define mp2if_keep_sf_sync_byte_ofsm_pos 7 | ||
2827 | #define mp2if_keep_sf_sync_byte_ofsm_len 1 | ||
2828 | #define mp2if_keep_sf_sync_byte_ofsm_lsb 0 | ||
2829 | #define xd_r_mp2if_psb_mp2if_num_pkt 0xA501 | ||
2830 | #define mp2if_psb_mp2if_num_pkt_pos 0 | ||
2831 | #define mp2if_psb_mp2if_num_pkt_len 6 | ||
2832 | #define mp2if_psb_mp2if_num_pkt_lsb 0 | ||
2833 | #define xd_p_reg_mpeg_full_speed_ofsm 0xA501 | ||
2834 | #define reg_mpeg_full_speed_ofsm_pos 6 | ||
2835 | #define reg_mpeg_full_speed_ofsm_len 1 | ||
2836 | #define reg_mpeg_full_speed_ofsm_lsb 0 | ||
2837 | #define xd_p_mp2if_mpeg_ser_mode_ofsm 0xA501 | ||
2838 | #define mp2if_mpeg_ser_mode_ofsm_pos 7 | ||
2839 | #define mp2if_mpeg_ser_mode_ofsm_len 1 | ||
2840 | #define mp2if_mpeg_ser_mode_ofsm_lsb 0 | ||
2841 | #define xd_p_reg_sw_mon51 0xA600 | ||
2842 | #define reg_sw_mon51_pos 0 | ||
2843 | #define reg_sw_mon51_len 8 | ||
2844 | #define reg_sw_mon51_lsb 0 | ||
2845 | #define xd_p_reg_top_pcsel 0xA601 | ||
2846 | #define reg_top_pcsel_pos 0 | ||
2847 | #define reg_top_pcsel_len 1 | ||
2848 | #define reg_top_pcsel_lsb 0 | ||
2849 | #define xd_p_reg_top_rs232 0xA601 | ||
2850 | #define reg_top_rs232_pos 1 | ||
2851 | #define reg_top_rs232_len 1 | ||
2852 | #define reg_top_rs232_lsb 0 | ||
2853 | #define xd_p_reg_top_pcout 0xA601 | ||
2854 | #define reg_top_pcout_pos 2 | ||
2855 | #define reg_top_pcout_len 1 | ||
2856 | #define reg_top_pcout_lsb 0 | ||
2857 | #define xd_p_reg_top_debug 0xA601 | ||
2858 | #define reg_top_debug_pos 3 | ||
2859 | #define reg_top_debug_len 1 | ||
2860 | #define reg_top_debug_lsb 0 | ||
2861 | #define xd_p_reg_top_adcdly 0xA601 | ||
2862 | #define reg_top_adcdly_pos 4 | ||
2863 | #define reg_top_adcdly_len 2 | ||
2864 | #define reg_top_adcdly_lsb 0 | ||
2865 | #define xd_p_reg_top_pwrdw 0xA601 | ||
2866 | #define reg_top_pwrdw_pos 6 | ||
2867 | #define reg_top_pwrdw_len 1 | ||
2868 | #define reg_top_pwrdw_lsb 0 | ||
2869 | #define xd_p_reg_top_pwrdw_inv 0xA601 | ||
2870 | #define reg_top_pwrdw_inv_pos 7 | ||
2871 | #define reg_top_pwrdw_inv_len 1 | ||
2872 | #define reg_top_pwrdw_inv_lsb 0 | ||
2873 | #define xd_p_reg_top_int_inv 0xA602 | ||
2874 | #define reg_top_int_inv_pos 0 | ||
2875 | #define reg_top_int_inv_len 1 | ||
2876 | #define reg_top_int_inv_lsb 0 | ||
2877 | #define xd_p_reg_top_dio_sel 0xA602 | ||
2878 | #define reg_top_dio_sel_pos 1 | ||
2879 | #define reg_top_dio_sel_len 1 | ||
2880 | #define reg_top_dio_sel_lsb 0 | ||
2881 | #define xd_p_reg_top_gpioon0 0xA603 | ||
2882 | #define reg_top_gpioon0_pos 0 | ||
2883 | #define reg_top_gpioon0_len 1 | ||
2884 | #define reg_top_gpioon0_lsb 0 | ||
2885 | #define xd_p_reg_top_gpioon1 0xA603 | ||
2886 | #define reg_top_gpioon1_pos 1 | ||
2887 | #define reg_top_gpioon1_len 1 | ||
2888 | #define reg_top_gpioon1_lsb 0 | ||
2889 | #define xd_p_reg_top_gpioon2 0xA603 | ||
2890 | #define reg_top_gpioon2_pos 2 | ||
2891 | #define reg_top_gpioon2_len 1 | ||
2892 | #define reg_top_gpioon2_lsb 0 | ||
2893 | #define xd_p_reg_top_gpioon3 0xA603 | ||
2894 | #define reg_top_gpioon3_pos 3 | ||
2895 | #define reg_top_gpioon3_len 1 | ||
2896 | #define reg_top_gpioon3_lsb 0 | ||
2897 | #define xd_p_reg_top_lockon1 0xA603 | ||
2898 | #define reg_top_lockon1_pos 4 | ||
2899 | #define reg_top_lockon1_len 1 | ||
2900 | #define reg_top_lockon1_lsb 0 | ||
2901 | #define xd_p_reg_top_lockon2 0xA603 | ||
2902 | #define reg_top_lockon2_pos 5 | ||
2903 | #define reg_top_lockon2_len 1 | ||
2904 | #define reg_top_lockon2_lsb 0 | ||
2905 | #define xd_p_reg_top_gpioo0 0xA604 | ||
2906 | #define reg_top_gpioo0_pos 0 | ||
2907 | #define reg_top_gpioo0_len 1 | ||
2908 | #define reg_top_gpioo0_lsb 0 | ||
2909 | #define xd_p_reg_top_gpioo1 0xA604 | ||
2910 | #define reg_top_gpioo1_pos 1 | ||
2911 | #define reg_top_gpioo1_len 1 | ||
2912 | #define reg_top_gpioo1_lsb 0 | ||
2913 | #define xd_p_reg_top_gpioo2 0xA604 | ||
2914 | #define reg_top_gpioo2_pos 2 | ||
2915 | #define reg_top_gpioo2_len 1 | ||
2916 | #define reg_top_gpioo2_lsb 0 | ||
2917 | #define xd_p_reg_top_gpioo3 0xA604 | ||
2918 | #define reg_top_gpioo3_pos 3 | ||
2919 | #define reg_top_gpioo3_len 1 | ||
2920 | #define reg_top_gpioo3_lsb 0 | ||
2921 | #define xd_p_reg_top_lock1 0xA604 | ||
2922 | #define reg_top_lock1_pos 4 | ||
2923 | #define reg_top_lock1_len 1 | ||
2924 | #define reg_top_lock1_lsb 0 | ||
2925 | #define xd_p_reg_top_lock2 0xA604 | ||
2926 | #define reg_top_lock2_pos 5 | ||
2927 | #define reg_top_lock2_len 1 | ||
2928 | #define reg_top_lock2_lsb 0 | ||
2929 | #define xd_p_reg_top_gpioen0 0xA605 | ||
2930 | #define reg_top_gpioen0_pos 0 | ||
2931 | #define reg_top_gpioen0_len 1 | ||
2932 | #define reg_top_gpioen0_lsb 0 | ||
2933 | #define xd_p_reg_top_gpioen1 0xA605 | ||
2934 | #define reg_top_gpioen1_pos 1 | ||
2935 | #define reg_top_gpioen1_len 1 | ||
2936 | #define reg_top_gpioen1_lsb 0 | ||
2937 | #define xd_p_reg_top_gpioen2 0xA605 | ||
2938 | #define reg_top_gpioen2_pos 2 | ||
2939 | #define reg_top_gpioen2_len 1 | ||
2940 | #define reg_top_gpioen2_lsb 0 | ||
2941 | #define xd_p_reg_top_gpioen3 0xA605 | ||
2942 | #define reg_top_gpioen3_pos 3 | ||
2943 | #define reg_top_gpioen3_len 1 | ||
2944 | #define reg_top_gpioen3_lsb 0 | ||
2945 | #define xd_p_reg_top_locken1 0xA605 | ||
2946 | #define reg_top_locken1_pos 4 | ||
2947 | #define reg_top_locken1_len 1 | ||
2948 | #define reg_top_locken1_lsb 0 | ||
2949 | #define xd_p_reg_top_locken2 0xA605 | ||
2950 | #define reg_top_locken2_pos 5 | ||
2951 | #define reg_top_locken2_len 1 | ||
2952 | #define reg_top_locken2_lsb 0 | ||
2953 | #define xd_r_reg_top_gpioi0 0xA606 | ||
2954 | #define reg_top_gpioi0_pos 0 | ||
2955 | #define reg_top_gpioi0_len 1 | ||
2956 | #define reg_top_gpioi0_lsb 0 | ||
2957 | #define xd_r_reg_top_gpioi1 0xA606 | ||
2958 | #define reg_top_gpioi1_pos 1 | ||
2959 | #define reg_top_gpioi1_len 1 | ||
2960 | #define reg_top_gpioi1_lsb 0 | ||
2961 | #define xd_r_reg_top_gpioi2 0xA606 | ||
2962 | #define reg_top_gpioi2_pos 2 | ||
2963 | #define reg_top_gpioi2_len 1 | ||
2964 | #define reg_top_gpioi2_lsb 0 | ||
2965 | #define xd_r_reg_top_gpioi3 0xA606 | ||
2966 | #define reg_top_gpioi3_pos 3 | ||
2967 | #define reg_top_gpioi3_len 1 | ||
2968 | #define reg_top_gpioi3_lsb 0 | ||
2969 | #define xd_r_reg_top_locki1 0xA606 | ||
2970 | #define reg_top_locki1_pos 4 | ||
2971 | #define reg_top_locki1_len 1 | ||
2972 | #define reg_top_locki1_lsb 0 | ||
2973 | #define xd_r_reg_top_locki2 0xA606 | ||
2974 | #define reg_top_locki2_pos 5 | ||
2975 | #define reg_top_locki2_len 1 | ||
2976 | #define reg_top_locki2_lsb 0 | ||
2977 | #define xd_p_reg_dummy_7_0 0xA608 | ||
2978 | #define reg_dummy_7_0_pos 0 | ||
2979 | #define reg_dummy_7_0_len 8 | ||
2980 | #define reg_dummy_7_0_lsb 0 | ||
2981 | #define xd_p_reg_dummy_15_8 0xA609 | ||
2982 | #define reg_dummy_15_8_pos 0 | ||
2983 | #define reg_dummy_15_8_len 8 | ||
2984 | #define reg_dummy_15_8_lsb 8 | ||
2985 | #define xd_p_reg_dummy_23_16 0xA60A | ||
2986 | #define reg_dummy_23_16_pos 0 | ||
2987 | #define reg_dummy_23_16_len 8 | ||
2988 | #define reg_dummy_23_16_lsb 16 | ||
2989 | #define xd_p_reg_dummy_31_24 0xA60B | ||
2990 | #define reg_dummy_31_24_pos 0 | ||
2991 | #define reg_dummy_31_24_len 8 | ||
2992 | #define reg_dummy_31_24_lsb 24 | ||
2993 | #define xd_p_reg_dummy_39_32 0xA60C | ||
2994 | #define reg_dummy_39_32_pos 0 | ||
2995 | #define reg_dummy_39_32_len 8 | ||
2996 | #define reg_dummy_39_32_lsb 32 | ||
2997 | #define xd_p_reg_dummy_47_40 0xA60D | ||
2998 | #define reg_dummy_47_40_pos 0 | ||
2999 | #define reg_dummy_47_40_len 8 | ||
3000 | #define reg_dummy_47_40_lsb 40 | ||
3001 | #define xd_p_reg_dummy_55_48 0xA60E | ||
3002 | #define reg_dummy_55_48_pos 0 | ||
3003 | #define reg_dummy_55_48_len 8 | ||
3004 | #define reg_dummy_55_48_lsb 48 | ||
3005 | #define xd_p_reg_dummy_63_56 0xA60F | ||
3006 | #define reg_dummy_63_56_pos 0 | ||
3007 | #define reg_dummy_63_56_len 8 | ||
3008 | #define reg_dummy_63_56_lsb 56 | ||
3009 | #define xd_p_reg_dummy_71_64 0xA610 | ||
3010 | #define reg_dummy_71_64_pos 0 | ||
3011 | #define reg_dummy_71_64_len 8 | ||
3012 | #define reg_dummy_71_64_lsb 64 | ||
3013 | #define xd_p_reg_dummy_79_72 0xA611 | ||
3014 | #define reg_dummy_79_72_pos 0 | ||
3015 | #define reg_dummy_79_72_len 8 | ||
3016 | #define reg_dummy_79_72_lsb 72 | ||
3017 | #define xd_p_reg_dummy_87_80 0xA612 | ||
3018 | #define reg_dummy_87_80_pos 0 | ||
3019 | #define reg_dummy_87_80_len 8 | ||
3020 | #define reg_dummy_87_80_lsb 80 | ||
3021 | #define xd_p_reg_dummy_95_88 0xA613 | ||
3022 | #define reg_dummy_95_88_pos 0 | ||
3023 | #define reg_dummy_95_88_len 8 | ||
3024 | #define reg_dummy_95_88_lsb 88 | ||
3025 | #define xd_p_reg_dummy_103_96 0xA614 | ||
3026 | #define reg_dummy_103_96_pos 0 | ||
3027 | #define reg_dummy_103_96_len 8 | ||
3028 | #define reg_dummy_103_96_lsb 96 | ||
3029 | |||
3030 | #define xd_p_reg_unplug_flag 0xA615 | ||
3031 | #define reg_unplug_flag_pos 0 | ||
3032 | #define reg_unplug_flag_len 1 | ||
3033 | #define reg_unplug_flag_lsb 104 | ||
3034 | |||
3035 | #define xd_p_reg_api_dca_stes_request 0xA615 | ||
3036 | #define reg_api_dca_stes_request_pos 1 | ||
3037 | #define reg_api_dca_stes_request_len 1 | ||
3038 | #define reg_api_dca_stes_request_lsb 0 | ||
3039 | |||
3040 | #define xd_p_reg_back_to_dca_flag 0xA615 | ||
3041 | #define reg_back_to_dca_flag_pos 2 | ||
3042 | #define reg_back_to_dca_flag_len 1 | ||
3043 | #define reg_back_to_dca_flag_lsb 106 | ||
3044 | |||
3045 | #define xd_p_reg_api_retrain_request 0xA615 | ||
3046 | #define reg_api_retrain_request_pos 3 | ||
3047 | #define reg_api_retrain_request_len 1 | ||
3048 | #define reg_api_retrain_request_lsb 0 | ||
3049 | |||
3050 | #define xd_p_reg_Dyn_Top_Try_flag 0xA615 | ||
3051 | #define reg_Dyn_Top_Try_flag_pos 3 | ||
3052 | #define reg_Dyn_Top_Try_flag_len 1 | ||
3053 | #define reg_Dyn_Top_Try_flag_lsb 107 | ||
3054 | |||
3055 | #define xd_p_reg_API_retrain_freeze_flag 0xA615 | ||
3056 | #define reg_API_retrain_freeze_flag_pos 4 | ||
3057 | #define reg_API_retrain_freeze_flag_len 1 | ||
3058 | #define reg_API_retrain_freeze_flag_lsb 108 | ||
3059 | |||
3060 | #define xd_p_reg_dummy_111_104 0xA615 | ||
3061 | #define reg_dummy_111_104_pos 0 | ||
3062 | #define reg_dummy_111_104_len 8 | ||
3063 | #define reg_dummy_111_104_lsb 104 | ||
3064 | #define xd_p_reg_dummy_119_112 0xA616 | ||
3065 | #define reg_dummy_119_112_pos 0 | ||
3066 | #define reg_dummy_119_112_len 8 | ||
3067 | #define reg_dummy_119_112_lsb 112 | ||
3068 | #define xd_p_reg_dummy_127_120 0xA617 | ||
3069 | #define reg_dummy_127_120_pos 0 | ||
3070 | #define reg_dummy_127_120_len 8 | ||
3071 | #define reg_dummy_127_120_lsb 120 | ||
3072 | #define xd_p_reg_dummy_135_128 0xA618 | ||
3073 | #define reg_dummy_135_128_pos 0 | ||
3074 | #define reg_dummy_135_128_len 8 | ||
3075 | #define reg_dummy_135_128_lsb 128 | ||
3076 | |||
3077 | #define xd_p_reg_dummy_143_136 0xA619 | ||
3078 | #define reg_dummy_143_136_pos 0 | ||
3079 | #define reg_dummy_143_136_len 8 | ||
3080 | #define reg_dummy_143_136_lsb 136 | ||
3081 | |||
3082 | #define xd_p_reg_CCIR_dis 0xA619 | ||
3083 | #define reg_CCIR_dis_pos 0 | ||
3084 | #define reg_CCIR_dis_len 1 | ||
3085 | #define reg_CCIR_dis_lsb 0 | ||
3086 | |||
3087 | #define xd_p_reg_dummy_151_144 0xA61A | ||
3088 | #define reg_dummy_151_144_pos 0 | ||
3089 | #define reg_dummy_151_144_len 8 | ||
3090 | #define reg_dummy_151_144_lsb 144 | ||
3091 | |||
3092 | #define xd_p_reg_dummy_159_152 0xA61B | ||
3093 | #define reg_dummy_159_152_pos 0 | ||
3094 | #define reg_dummy_159_152_len 8 | ||
3095 | #define reg_dummy_159_152_lsb 152 | ||
3096 | |||
3097 | #define xd_p_reg_dummy_167_160 0xA61C | ||
3098 | #define reg_dummy_167_160_pos 0 | ||
3099 | #define reg_dummy_167_160_len 8 | ||
3100 | #define reg_dummy_167_160_lsb 160 | ||
3101 | |||
3102 | #define xd_p_reg_dummy_175_168 0xA61D | ||
3103 | #define reg_dummy_175_168_pos 0 | ||
3104 | #define reg_dummy_175_168_len 8 | ||
3105 | #define reg_dummy_175_168_lsb 168 | ||
3106 | |||
3107 | #define xd_p_reg_dummy_183_176 0xA61E | ||
3108 | #define reg_dummy_183_176_pos 0 | ||
3109 | #define reg_dummy_183_176_len 8 | ||
3110 | #define reg_dummy_183_176_lsb 176 | ||
3111 | |||
3112 | #define xd_p_reg_ofsm_read_rbc_en 0xA61E | ||
3113 | #define reg_ofsm_read_rbc_en_pos 2 | ||
3114 | #define reg_ofsm_read_rbc_en_len 1 | ||
3115 | #define reg_ofsm_read_rbc_en_lsb 0 | ||
3116 | |||
3117 | #define xd_p_reg_ce_filter_selection_dis 0xA61E | ||
3118 | #define reg_ce_filter_selection_dis_pos 1 | ||
3119 | #define reg_ce_filter_selection_dis_len 1 | ||
3120 | #define reg_ce_filter_selection_dis_lsb 0 | ||
3121 | |||
3122 | #define xd_p_reg_OFSM_version_control_7_0 0xA611 | ||
3123 | #define reg_OFSM_version_control_7_0_pos 0 | ||
3124 | #define reg_OFSM_version_control_7_0_len 8 | ||
3125 | #define reg_OFSM_version_control_7_0_lsb 0 | ||
3126 | |||
3127 | #define xd_p_reg_OFSM_version_control_15_8 0xA61F | ||
3128 | #define reg_OFSM_version_control_15_8_pos 0 | ||
3129 | #define reg_OFSM_version_control_15_8_len 8 | ||
3130 | #define reg_OFSM_version_control_15_8_lsb 0 | ||
3131 | |||
3132 | #define xd_p_reg_OFSM_version_control_23_16 0xA620 | ||
3133 | #define reg_OFSM_version_control_23_16_pos 0 | ||
3134 | #define reg_OFSM_version_control_23_16_len 8 | ||
3135 | #define reg_OFSM_version_control_23_16_lsb 0 | ||
3136 | |||
3137 | #define xd_p_reg_dummy_191_184 0xA61F | ||
3138 | #define reg_dummy_191_184_pos 0 | ||
3139 | #define reg_dummy_191_184_len 8 | ||
3140 | #define reg_dummy_191_184_lsb 184 | ||
3141 | |||
3142 | #define xd_p_reg_dummy_199_192 0xA620 | ||
3143 | #define reg_dummy_199_192_pos 0 | ||
3144 | #define reg_dummy_199_192_len 8 | ||
3145 | #define reg_dummy_199_192_lsb 192 | ||
3146 | |||
3147 | #define xd_p_reg_ce_en 0xABC0 | ||
3148 | #define reg_ce_en_pos 0 | ||
3149 | #define reg_ce_en_len 1 | ||
3150 | #define reg_ce_en_lsb 0 | ||
3151 | #define xd_p_reg_ce_fctrl_en 0xABC0 | ||
3152 | #define reg_ce_fctrl_en_pos 1 | ||
3153 | #define reg_ce_fctrl_en_len 1 | ||
3154 | #define reg_ce_fctrl_en_lsb 0 | ||
3155 | #define xd_p_reg_ce_fste_tdi 0xABC0 | ||
3156 | #define reg_ce_fste_tdi_pos 2 | ||
3157 | #define reg_ce_fste_tdi_len 1 | ||
3158 | #define reg_ce_fste_tdi_lsb 0 | ||
3159 | #define xd_p_reg_ce_dynamic 0xABC0 | ||
3160 | #define reg_ce_dynamic_pos 3 | ||
3161 | #define reg_ce_dynamic_len 1 | ||
3162 | #define reg_ce_dynamic_lsb 0 | ||
3163 | #define xd_p_reg_ce_conf 0xABC0 | ||
3164 | #define reg_ce_conf_pos 4 | ||
3165 | #define reg_ce_conf_len 2 | ||
3166 | #define reg_ce_conf_lsb 0 | ||
3167 | #define xd_p_reg_ce_dyn12 0xABC0 | ||
3168 | #define reg_ce_dyn12_pos 6 | ||
3169 | #define reg_ce_dyn12_len 1 | ||
3170 | #define reg_ce_dyn12_lsb 0 | ||
3171 | #define xd_p_reg_ce_derot_en 0xABC0 | ||
3172 | #define reg_ce_derot_en_pos 7 | ||
3173 | #define reg_ce_derot_en_len 1 | ||
3174 | #define reg_ce_derot_en_lsb 0 | ||
3175 | #define xd_p_reg_ce_dynamic_th_7_0 0xABC1 | ||
3176 | #define reg_ce_dynamic_th_7_0_pos 0 | ||
3177 | #define reg_ce_dynamic_th_7_0_len 8 | ||
3178 | #define reg_ce_dynamic_th_7_0_lsb 0 | ||
3179 | #define xd_p_reg_ce_dynamic_th_15_8 0xABC2 | ||
3180 | #define reg_ce_dynamic_th_15_8_pos 0 | ||
3181 | #define reg_ce_dynamic_th_15_8_len 8 | ||
3182 | #define reg_ce_dynamic_th_15_8_lsb 8 | ||
3183 | #define xd_p_reg_ce_s1 0xABC3 | ||
3184 | #define reg_ce_s1_pos 0 | ||
3185 | #define reg_ce_s1_len 5 | ||
3186 | #define reg_ce_s1_lsb 0 | ||
3187 | #define xd_p_reg_ce_var_forced_value 0xABC3 | ||
3188 | #define reg_ce_var_forced_value_pos 5 | ||
3189 | #define reg_ce_var_forced_value_len 3 | ||
3190 | #define reg_ce_var_forced_value_lsb 0 | ||
3191 | #define xd_p_reg_ce_data_im_7_0 0xABC4 | ||
3192 | #define reg_ce_data_im_7_0_pos 0 | ||
3193 | #define reg_ce_data_im_7_0_len 8 | ||
3194 | #define reg_ce_data_im_7_0_lsb 0 | ||
3195 | #define xd_p_reg_ce_data_im_8 0xABC5 | ||
3196 | #define reg_ce_data_im_8_pos 0 | ||
3197 | #define reg_ce_data_im_8_len 1 | ||
3198 | #define reg_ce_data_im_8_lsb 0 | ||
3199 | #define xd_p_reg_ce_data_re_6_0 0xABC5 | ||
3200 | #define reg_ce_data_re_6_0_pos 1 | ||
3201 | #define reg_ce_data_re_6_0_len 7 | ||
3202 | #define reg_ce_data_re_6_0_lsb 0 | ||
3203 | #define xd_p_reg_ce_data_re_8_7 0xABC6 | ||
3204 | #define reg_ce_data_re_8_7_pos 0 | ||
3205 | #define reg_ce_data_re_8_7_len 2 | ||
3206 | #define reg_ce_data_re_8_7_lsb 7 | ||
3207 | #define xd_p_reg_ce_tone_5_0 0xABC6 | ||
3208 | #define reg_ce_tone_5_0_pos 2 | ||
3209 | #define reg_ce_tone_5_0_len 6 | ||
3210 | #define reg_ce_tone_5_0_lsb 0 | ||
3211 | #define xd_p_reg_ce_tone_12_6 0xABC7 | ||
3212 | #define reg_ce_tone_12_6_pos 0 | ||
3213 | #define reg_ce_tone_12_6_len 7 | ||
3214 | #define reg_ce_tone_12_6_lsb 6 | ||
3215 | #define xd_p_reg_ce_centroid_drift_th 0xABC8 | ||
3216 | #define reg_ce_centroid_drift_th_pos 0 | ||
3217 | #define reg_ce_centroid_drift_th_len 8 | ||
3218 | #define reg_ce_centroid_drift_th_lsb 0 | ||
3219 | #define xd_p_reg_ce_centroid_count_max 0xABC9 | ||
3220 | #define reg_ce_centroid_count_max_pos 0 | ||
3221 | #define reg_ce_centroid_count_max_len 4 | ||
3222 | #define reg_ce_centroid_count_max_lsb 0 | ||
3223 | #define xd_p_reg_ce_centroid_bias_inc_7_0 0xABCA | ||
3224 | #define reg_ce_centroid_bias_inc_7_0_pos 0 | ||
3225 | #define reg_ce_centroid_bias_inc_7_0_len 8 | ||
3226 | #define reg_ce_centroid_bias_inc_7_0_lsb 0 | ||
3227 | #define xd_p_reg_ce_centroid_bias_inc_8 0xABCB | ||
3228 | #define reg_ce_centroid_bias_inc_8_pos 0 | ||
3229 | #define reg_ce_centroid_bias_inc_8_len 1 | ||
3230 | #define reg_ce_centroid_bias_inc_8_lsb 0 | ||
3231 | #define xd_p_reg_ce_var_th0_7_0 0xABCC | ||
3232 | #define reg_ce_var_th0_7_0_pos 0 | ||
3233 | #define reg_ce_var_th0_7_0_len 8 | ||
3234 | #define reg_ce_var_th0_7_0_lsb 0 | ||
3235 | #define xd_p_reg_ce_var_th0_15_8 0xABCD | ||
3236 | #define reg_ce_var_th0_15_8_pos 0 | ||
3237 | #define reg_ce_var_th0_15_8_len 8 | ||
3238 | #define reg_ce_var_th0_15_8_lsb 8 | ||
3239 | #define xd_p_reg_ce_var_th1_7_0 0xABCE | ||
3240 | #define reg_ce_var_th1_7_0_pos 0 | ||
3241 | #define reg_ce_var_th1_7_0_len 8 | ||
3242 | #define reg_ce_var_th1_7_0_lsb 0 | ||
3243 | #define xd_p_reg_ce_var_th1_15_8 0xABCF | ||
3244 | #define reg_ce_var_th1_15_8_pos 0 | ||
3245 | #define reg_ce_var_th1_15_8_len 8 | ||
3246 | #define reg_ce_var_th1_15_8_lsb 8 | ||
3247 | #define xd_p_reg_ce_var_th2_7_0 0xABD0 | ||
3248 | #define reg_ce_var_th2_7_0_pos 0 | ||
3249 | #define reg_ce_var_th2_7_0_len 8 | ||
3250 | #define reg_ce_var_th2_7_0_lsb 0 | ||
3251 | #define xd_p_reg_ce_var_th2_15_8 0xABD1 | ||
3252 | #define reg_ce_var_th2_15_8_pos 0 | ||
3253 | #define reg_ce_var_th2_15_8_len 8 | ||
3254 | #define reg_ce_var_th2_15_8_lsb 8 | ||
3255 | #define xd_p_reg_ce_var_th3_7_0 0xABD2 | ||
3256 | #define reg_ce_var_th3_7_0_pos 0 | ||
3257 | #define reg_ce_var_th3_7_0_len 8 | ||
3258 | #define reg_ce_var_th3_7_0_lsb 0 | ||
3259 | #define xd_p_reg_ce_var_th3_15_8 0xABD3 | ||
3260 | #define reg_ce_var_th3_15_8_pos 0 | ||
3261 | #define reg_ce_var_th3_15_8_len 8 | ||
3262 | #define reg_ce_var_th3_15_8_lsb 8 | ||
3263 | #define xd_p_reg_ce_var_th4_7_0 0xABD4 | ||
3264 | #define reg_ce_var_th4_7_0_pos 0 | ||
3265 | #define reg_ce_var_th4_7_0_len 8 | ||
3266 | #define reg_ce_var_th4_7_0_lsb 0 | ||
3267 | #define xd_p_reg_ce_var_th4_15_8 0xABD5 | ||
3268 | #define reg_ce_var_th4_15_8_pos 0 | ||
3269 | #define reg_ce_var_th4_15_8_len 8 | ||
3270 | #define reg_ce_var_th4_15_8_lsb 8 | ||
3271 | #define xd_p_reg_ce_var_th5_7_0 0xABD6 | ||
3272 | #define reg_ce_var_th5_7_0_pos 0 | ||
3273 | #define reg_ce_var_th5_7_0_len 8 | ||
3274 | #define reg_ce_var_th5_7_0_lsb 0 | ||
3275 | #define xd_p_reg_ce_var_th5_15_8 0xABD7 | ||
3276 | #define reg_ce_var_th5_15_8_pos 0 | ||
3277 | #define reg_ce_var_th5_15_8_len 8 | ||
3278 | #define reg_ce_var_th5_15_8_lsb 8 | ||
3279 | #define xd_p_reg_ce_var_th6_7_0 0xABD8 | ||
3280 | #define reg_ce_var_th6_7_0_pos 0 | ||
3281 | #define reg_ce_var_th6_7_0_len 8 | ||
3282 | #define reg_ce_var_th6_7_0_lsb 0 | ||
3283 | #define xd_p_reg_ce_var_th6_15_8 0xABD9 | ||
3284 | #define reg_ce_var_th6_15_8_pos 0 | ||
3285 | #define reg_ce_var_th6_15_8_len 8 | ||
3286 | #define reg_ce_var_th6_15_8_lsb 8 | ||
3287 | #define xd_p_reg_ce_fctrl_reset 0xABDA | ||
3288 | #define reg_ce_fctrl_reset_pos 0 | ||
3289 | #define reg_ce_fctrl_reset_len 1 | ||
3290 | #define reg_ce_fctrl_reset_lsb 0 | ||
3291 | #define xd_p_reg_ce_cent_auto_clr_en 0xABDA | ||
3292 | #define reg_ce_cent_auto_clr_en_pos 1 | ||
3293 | #define reg_ce_cent_auto_clr_en_len 1 | ||
3294 | #define reg_ce_cent_auto_clr_en_lsb 0 | ||
3295 | #define xd_p_reg_ce_fctrl_auto_reset_en 0xABDA | ||
3296 | #define reg_ce_fctrl_auto_reset_en_pos 2 | ||
3297 | #define reg_ce_fctrl_auto_reset_en_len 1 | ||
3298 | #define reg_ce_fctrl_auto_reset_en_lsb 0 | ||
3299 | #define xd_p_reg_ce_var_forced_en 0xABDA | ||
3300 | #define reg_ce_var_forced_en_pos 3 | ||
3301 | #define reg_ce_var_forced_en_len 1 | ||
3302 | #define reg_ce_var_forced_en_lsb 0 | ||
3303 | #define xd_p_reg_ce_cent_forced_en 0xABDA | ||
3304 | #define reg_ce_cent_forced_en_pos 4 | ||
3305 | #define reg_ce_cent_forced_en_len 1 | ||
3306 | #define reg_ce_cent_forced_en_lsb 0 | ||
3307 | #define xd_p_reg_ce_var_max 0xABDA | ||
3308 | #define reg_ce_var_max_pos 5 | ||
3309 | #define reg_ce_var_max_len 3 | ||
3310 | #define reg_ce_var_max_lsb 0 | ||
3311 | #define xd_p_reg_ce_cent_forced_value_7_0 0xABDB | ||
3312 | #define reg_ce_cent_forced_value_7_0_pos 0 | ||
3313 | #define reg_ce_cent_forced_value_7_0_len 8 | ||
3314 | #define reg_ce_cent_forced_value_7_0_lsb 0 | ||
3315 | #define xd_p_reg_ce_cent_forced_value_11_8 0xABDC | ||
3316 | #define reg_ce_cent_forced_value_11_8_pos 0 | ||
3317 | #define reg_ce_cent_forced_value_11_8_len 4 | ||
3318 | #define reg_ce_cent_forced_value_11_8_lsb 8 | ||
3319 | #define xd_p_reg_ce_fctrl_rd 0xABDD | ||
3320 | #define reg_ce_fctrl_rd_pos 0 | ||
3321 | #define reg_ce_fctrl_rd_len 1 | ||
3322 | #define reg_ce_fctrl_rd_lsb 0 | ||
3323 | #define xd_p_reg_ce_centroid_max_6_0 0xABDD | ||
3324 | #define reg_ce_centroid_max_6_0_pos 1 | ||
3325 | #define reg_ce_centroid_max_6_0_len 7 | ||
3326 | #define reg_ce_centroid_max_6_0_lsb 0 | ||
3327 | #define xd_p_reg_ce_centroid_max_11_7 0xABDE | ||
3328 | #define reg_ce_centroid_max_11_7_pos 0 | ||
3329 | #define reg_ce_centroid_max_11_7_len 5 | ||
3330 | #define reg_ce_centroid_max_11_7_lsb 7 | ||
3331 | #define xd_p_reg_ce_var 0xABDF | ||
3332 | #define reg_ce_var_pos 0 | ||
3333 | #define reg_ce_var_len 3 | ||
3334 | #define reg_ce_var_lsb 0 | ||
3335 | #define xd_p_reg_ce_fctrl_rdy 0xABDF | ||
3336 | #define reg_ce_fctrl_rdy_pos 3 | ||
3337 | #define reg_ce_fctrl_rdy_len 1 | ||
3338 | #define reg_ce_fctrl_rdy_lsb 0 | ||
3339 | #define xd_p_reg_ce_centroid_out_3_0 0xABDF | ||
3340 | #define reg_ce_centroid_out_3_0_pos 4 | ||
3341 | #define reg_ce_centroid_out_3_0_len 4 | ||
3342 | #define reg_ce_centroid_out_3_0_lsb 0 | ||
3343 | #define xd_p_reg_ce_centroid_out_11_4 0xABE0 | ||
3344 | #define reg_ce_centroid_out_11_4_pos 0 | ||
3345 | #define reg_ce_centroid_out_11_4_len 8 | ||
3346 | #define reg_ce_centroid_out_11_4_lsb 4 | ||
3347 | #define xd_p_reg_ce_bias_7_0 0xABE1 | ||
3348 | #define reg_ce_bias_7_0_pos 0 | ||
3349 | #define reg_ce_bias_7_0_len 8 | ||
3350 | #define reg_ce_bias_7_0_lsb 0 | ||
3351 | #define xd_p_reg_ce_bias_11_8 0xABE2 | ||
3352 | #define reg_ce_bias_11_8_pos 0 | ||
3353 | #define reg_ce_bias_11_8_len 4 | ||
3354 | #define reg_ce_bias_11_8_lsb 8 | ||
3355 | #define xd_p_reg_ce_m1_3_0 0xABE2 | ||
3356 | #define reg_ce_m1_3_0_pos 4 | ||
3357 | #define reg_ce_m1_3_0_len 4 | ||
3358 | #define reg_ce_m1_3_0_lsb 0 | ||
3359 | #define xd_p_reg_ce_m1_11_4 0xABE3 | ||
3360 | #define reg_ce_m1_11_4_pos 0 | ||
3361 | #define reg_ce_m1_11_4_len 8 | ||
3362 | #define reg_ce_m1_11_4_lsb 4 | ||
3363 | #define xd_p_reg_ce_rh0_7_0 0xABE4 | ||
3364 | #define reg_ce_rh0_7_0_pos 0 | ||
3365 | #define reg_ce_rh0_7_0_len 8 | ||
3366 | #define reg_ce_rh0_7_0_lsb 0 | ||
3367 | #define xd_p_reg_ce_rh0_15_8 0xABE5 | ||
3368 | #define reg_ce_rh0_15_8_pos 0 | ||
3369 | #define reg_ce_rh0_15_8_len 8 | ||
3370 | #define reg_ce_rh0_15_8_lsb 8 | ||
3371 | #define xd_p_reg_ce_rh0_23_16 0xABE6 | ||
3372 | #define reg_ce_rh0_23_16_pos 0 | ||
3373 | #define reg_ce_rh0_23_16_len 8 | ||
3374 | #define reg_ce_rh0_23_16_lsb 16 | ||
3375 | #define xd_p_reg_ce_rh0_31_24 0xABE7 | ||
3376 | #define reg_ce_rh0_31_24_pos 0 | ||
3377 | #define reg_ce_rh0_31_24_len 8 | ||
3378 | #define reg_ce_rh0_31_24_lsb 24 | ||
3379 | #define xd_p_reg_ce_rh3_real_7_0 0xABE8 | ||
3380 | #define reg_ce_rh3_real_7_0_pos 0 | ||
3381 | #define reg_ce_rh3_real_7_0_len 8 | ||
3382 | #define reg_ce_rh3_real_7_0_lsb 0 | ||
3383 | #define xd_p_reg_ce_rh3_real_15_8 0xABE9 | ||
3384 | #define reg_ce_rh3_real_15_8_pos 0 | ||
3385 | #define reg_ce_rh3_real_15_8_len 8 | ||
3386 | #define reg_ce_rh3_real_15_8_lsb 8 | ||
3387 | #define xd_p_reg_ce_rh3_real_23_16 0xABEA | ||
3388 | #define reg_ce_rh3_real_23_16_pos 0 | ||
3389 | #define reg_ce_rh3_real_23_16_len 8 | ||
3390 | #define reg_ce_rh3_real_23_16_lsb 16 | ||
3391 | #define xd_p_reg_ce_rh3_real_31_24 0xABEB | ||
3392 | #define reg_ce_rh3_real_31_24_pos 0 | ||
3393 | #define reg_ce_rh3_real_31_24_len 8 | ||
3394 | #define reg_ce_rh3_real_31_24_lsb 24 | ||
3395 | #define xd_p_reg_ce_rh3_imag_7_0 0xABEC | ||
3396 | #define reg_ce_rh3_imag_7_0_pos 0 | ||
3397 | #define reg_ce_rh3_imag_7_0_len 8 | ||
3398 | #define reg_ce_rh3_imag_7_0_lsb 0 | ||
3399 | #define xd_p_reg_ce_rh3_imag_15_8 0xABED | ||
3400 | #define reg_ce_rh3_imag_15_8_pos 0 | ||
3401 | #define reg_ce_rh3_imag_15_8_len 8 | ||
3402 | #define reg_ce_rh3_imag_15_8_lsb 8 | ||
3403 | #define xd_p_reg_ce_rh3_imag_23_16 0xABEE | ||
3404 | #define reg_ce_rh3_imag_23_16_pos 0 | ||
3405 | #define reg_ce_rh3_imag_23_16_len 8 | ||
3406 | #define reg_ce_rh3_imag_23_16_lsb 16 | ||
3407 | #define xd_p_reg_ce_rh3_imag_31_24 0xABEF | ||
3408 | #define reg_ce_rh3_imag_31_24_pos 0 | ||
3409 | #define reg_ce_rh3_imag_31_24_len 8 | ||
3410 | #define reg_ce_rh3_imag_31_24_lsb 24 | ||
3411 | #define xd_p_reg_feq_fix_eh2_7_0 0xABF0 | ||
3412 | #define reg_feq_fix_eh2_7_0_pos 0 | ||
3413 | #define reg_feq_fix_eh2_7_0_len 8 | ||
3414 | #define reg_feq_fix_eh2_7_0_lsb 0 | ||
3415 | #define xd_p_reg_feq_fix_eh2_15_8 0xABF1 | ||
3416 | #define reg_feq_fix_eh2_15_8_pos 0 | ||
3417 | #define reg_feq_fix_eh2_15_8_len 8 | ||
3418 | #define reg_feq_fix_eh2_15_8_lsb 8 | ||
3419 | #define xd_p_reg_feq_fix_eh2_23_16 0xABF2 | ||
3420 | #define reg_feq_fix_eh2_23_16_pos 0 | ||
3421 | #define reg_feq_fix_eh2_23_16_len 8 | ||
3422 | #define reg_feq_fix_eh2_23_16_lsb 16 | ||
3423 | #define xd_p_reg_feq_fix_eh2_31_24 0xABF3 | ||
3424 | #define reg_feq_fix_eh2_31_24_pos 0 | ||
3425 | #define reg_feq_fix_eh2_31_24_len 8 | ||
3426 | #define reg_feq_fix_eh2_31_24_lsb 24 | ||
3427 | #define xd_p_reg_ce_m2_central_7_0 0xABF4 | ||
3428 | #define reg_ce_m2_central_7_0_pos 0 | ||
3429 | #define reg_ce_m2_central_7_0_len 8 | ||
3430 | #define reg_ce_m2_central_7_0_lsb 0 | ||
3431 | #define xd_p_reg_ce_m2_central_15_8 0xABF5 | ||
3432 | #define reg_ce_m2_central_15_8_pos 0 | ||
3433 | #define reg_ce_m2_central_15_8_len 8 | ||
3434 | #define reg_ce_m2_central_15_8_lsb 8 | ||
3435 | #define xd_p_reg_ce_fftshift 0xABF6 | ||
3436 | #define reg_ce_fftshift_pos 0 | ||
3437 | #define reg_ce_fftshift_len 4 | ||
3438 | #define reg_ce_fftshift_lsb 0 | ||
3439 | #define xd_p_reg_ce_fftshift1 0xABF6 | ||
3440 | #define reg_ce_fftshift1_pos 4 | ||
3441 | #define reg_ce_fftshift1_len 4 | ||
3442 | #define reg_ce_fftshift1_lsb 0 | ||
3443 | #define xd_p_reg_ce_fftshift2 0xABF7 | ||
3444 | #define reg_ce_fftshift2_pos 0 | ||
3445 | #define reg_ce_fftshift2_len 4 | ||
3446 | #define reg_ce_fftshift2_lsb 0 | ||
3447 | #define xd_p_reg_ce_top_mobile 0xABF7 | ||
3448 | #define reg_ce_top_mobile_pos 4 | ||
3449 | #define reg_ce_top_mobile_len 1 | ||
3450 | #define reg_ce_top_mobile_lsb 0 | ||
3451 | #define xd_p_reg_strong_sginal_detected 0xA2BC | ||
3452 | #define reg_strong_sginal_detected_pos 2 | ||
3453 | #define reg_strong_sginal_detected_len 1 | ||
3454 | #define reg_strong_sginal_detected_lsb 0 | ||
3455 | |||
3456 | #define XD_MP2IF_BASE 0xB000 | ||
3457 | #define XD_MP2IF_CSR (0x00 + XD_MP2IF_BASE) | ||
3458 | #define XD_MP2IF_DMX_CTRL (0x03 + XD_MP2IF_BASE) | ||
3459 | #define XD_MP2IF_PID_IDX (0x04 + XD_MP2IF_BASE) | ||
3460 | #define XD_MP2IF_PID_DATA_L (0x05 + XD_MP2IF_BASE) | ||
3461 | #define XD_MP2IF_PID_DATA_H (0x06 + XD_MP2IF_BASE) | ||
3462 | #define XD_MP2IF_MISC (0x07 + XD_MP2IF_BASE) | ||
3463 | |||
3464 | extern struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d); | ||
3465 | extern int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, | ||
3466 | u8 * value); | ||
3467 | extern int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg, | ||
3468 | u8 * values, int len); | ||
3469 | extern int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, | ||
3470 | u8 value); | ||
3471 | extern int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg, | ||
3472 | u8 * values, int len); | ||
3473 | extern int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, | ||
3474 | u8 addr, u8 * values, int len); | ||
3475 | extern int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg, | ||
3476 | u8 * values, int len); | ||
3477 | extern int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, | ||
3478 | u8 pos, u8 len, u8 * value); | ||
3479 | extern int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, | ||
3480 | u8 pos, u8 len, u8 value); | ||
3481 | extern int af9005_send_command(struct dvb_usb_device *d, u8 command, | ||
3482 | u8 * wbuf, int wlen, u8 * rbuf, int rlen); | ||
3483 | extern int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, | ||
3484 | u8 * values, int len); | ||
3485 | extern int af9005_tuner_attach(struct dvb_usb_adapter *adap); | ||
3486 | extern int af9005_led_control(struct dvb_usb_device *d, int onoff); | ||
3487 | |||
3488 | extern u8 regmask[8]; | ||
3489 | |||
3490 | /* remote control decoder */ | ||
3491 | extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, | ||
3492 | u32 * event, int *state); | ||
3493 | extern struct dvb_usb_rc_key af9005_rc_keys[]; | ||
3494 | extern int af9005_rc_keys_size; | ||
3495 | |||
3496 | #endif | ||
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index bac2ae3b4a1f..04e31cf7d530 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
@@ -354,41 +354,35 @@ static struct mt352_config cxusb_mt352_config = { | |||
354 | /* Callbacks for DVB USB */ | 354 | /* Callbacks for DVB USB */ |
355 | static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) | 355 | static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) |
356 | { | 356 | { |
357 | u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 }; | 357 | dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap, |
358 | adap->pll_addr = 0x61; | 358 | DVB_PLL_FMD1216ME); |
359 | memcpy(adap->pll_init, bpll, 4); | ||
360 | adap->pll_desc = &dvb_pll_fmd1216me; | ||
361 | |||
362 | adap->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; | ||
363 | adap->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; | ||
364 | |||
365 | return 0; | 359 | return 0; |
366 | } | 360 | } |
367 | 361 | ||
368 | static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap) | 362 | static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap) |
369 | { | 363 | { |
370 | dvb_attach(dvb_pll_attach, adap->fe, 0x61, | 364 | dvb_attach(dvb_pll_attach, adap->fe, 0x61, |
371 | NULL, &dvb_pll_thomson_dtt7579); | 365 | NULL, DVB_PLL_THOMSON_DTT7579); |
372 | return 0; | 366 | return 0; |
373 | } | 367 | } |
374 | 368 | ||
375 | static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap) | 369 | static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap) |
376 | { | 370 | { |
377 | dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, &dvb_pll_lg_z201); | 371 | dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, DVB_PLL_LG_Z201); |
378 | return 0; | 372 | return 0; |
379 | } | 373 | } |
380 | 374 | ||
381 | static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap) | 375 | static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap) |
382 | { | 376 | { |
383 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, | 377 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, |
384 | NULL, &dvb_pll_thomson_dtt7579); | 378 | NULL, DVB_PLL_THOMSON_DTT7579); |
385 | return 0; | 379 | return 0; |
386 | } | 380 | } |
387 | 381 | ||
388 | static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) | 382 | static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) |
389 | { | 383 | { |
390 | dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap, | 384 | dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap, |
391 | &dvb_pll_lg_tdvs_h06xf); | 385 | DVB_PLL_LG_TDVS_H06XF); |
392 | return 0; | 386 | return 0; |
393 | } | 387 | } |
394 | 388 | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index 5143e426d283..9a184da01c47 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c | |||
@@ -295,7 +295,7 @@ int dibusb_dib3000mc_tuner_attach(struct dvb_usb_adapter *adap) | |||
295 | tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1); | 295 | tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1); |
296 | if (dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk3000p_mt2060_config, if1) == NULL) { | 296 | if (dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk3000p_mt2060_config, if1) == NULL) { |
297 | /* not found - use panasonic pll parameters */ | 297 | /* not found - use panasonic pll parameters */ |
298 | if (dvb_attach(dvb_pll_attach, adap->fe, 0x60, tun_i2c, &dvb_pll_env57h1xd5) == NULL) | 298 | if (dvb_attach(dvb_pll_attach, adap->fe, 0x60, tun_i2c, DVB_PLL_ENV57H1XD5) == NULL) |
299 | return -ENOMEM; | 299 | return -ENOMEM; |
300 | } else { | 300 | } else { |
301 | st->mt2060_present = 1; | 301 | st->mt2060_present = 1; |
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index 7a6ae8f482e0..043cadae0859 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c | |||
@@ -14,6 +14,14 @@ | |||
14 | */ | 14 | */ |
15 | #include "dibusb.h" | 15 | #include "dibusb.h" |
16 | 16 | ||
17 | static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
18 | { | ||
19 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
20 | struct dibusb_state *st = adap->priv; | ||
21 | |||
22 | return st->ops.tuner_pass_ctrl(fe, enable, st->tuner_addr); | ||
23 | } | ||
24 | |||
17 | static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap) | 25 | static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap) |
18 | { | 26 | { |
19 | struct dib3000_config demod_cfg; | 27 | struct dib3000_config demod_cfg; |
@@ -21,21 +29,34 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap) | |||
21 | 29 | ||
22 | demod_cfg.demod_address = 0x8; | 30 | demod_cfg.demod_address = 0x8; |
23 | 31 | ||
24 | if ((adap->fe = dib3000mb_attach(&demod_cfg,&adap->dev->i2c_adap,&st->ops)) == NULL) | 32 | if ((adap->fe = dvb_attach(dib3000mb_attach, &demod_cfg, |
33 | &adap->dev->i2c_adap, &st->ops)) == NULL) | ||
25 | return -ENODEV; | 34 | return -ENODEV; |
26 | 35 | ||
27 | adap->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; | 36 | adap->fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl; |
28 | adap->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; | ||
29 | |||
30 | adap->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; | ||
31 | 37 | ||
32 | return 0; | 38 | return 0; |
33 | } | 39 | } |
34 | 40 | ||
35 | static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap) | 41 | static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap) |
36 | { | 42 | { |
37 | adap->pll_addr = 0x61; | 43 | struct dibusb_state *st = adap->priv; |
38 | adap->pll_desc = &dvb_pll_tua6010xs; | 44 | |
45 | st->tuner_addr = 0x61; | ||
46 | |||
47 | dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap, | ||
48 | DVB_PLL_TUA6010XS); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap) | ||
53 | { | ||
54 | struct dibusb_state *st = adap->priv; | ||
55 | |||
56 | st->tuner_addr = 0x60; | ||
57 | |||
58 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, &adap->dev->i2c_adap, | ||
59 | DVB_PLL_TDA665X); | ||
39 | return 0; | 60 | return 0; |
40 | } | 61 | } |
41 | 62 | ||
@@ -50,30 +71,28 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap) | |||
50 | { .flags = 0, .buf = b, .len = 2 }, | 71 | { .flags = 0, .buf = b, .len = 2 }, |
51 | { .flags = I2C_M_RD, .buf = b2, .len = 1 }, | 72 | { .flags = I2C_M_RD, .buf = b2, .len = 1 }, |
52 | }; | 73 | }; |
74 | struct dibusb_state *st = adap->priv; | ||
53 | 75 | ||
54 | /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */ | 76 | /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */ |
55 | msg[0].addr = msg[1].addr = 0x60; | 77 | msg[0].addr = msg[1].addr = st->tuner_addr = 0x60; |
56 | 78 | ||
57 | if (adap->tuner_pass_ctrl) | 79 | if (adap->fe->ops.i2c_gate_ctrl) |
58 | adap->tuner_pass_ctrl(adap->fe,1,msg[0].addr); | 80 | adap->fe->ops.i2c_gate_ctrl(adap->fe,1); |
59 | 81 | ||
60 | if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) { | 82 | if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) { |
61 | err("tuner i2c write failed."); | 83 | err("tuner i2c write failed."); |
62 | ret = -EREMOTEIO; | 84 | ret = -EREMOTEIO; |
63 | } | 85 | } |
64 | 86 | ||
65 | if (adap->tuner_pass_ctrl) | 87 | if (adap->fe->ops.i2c_gate_ctrl) |
66 | adap->tuner_pass_ctrl(adap->fe,0,msg[0].addr); | 88 | adap->fe->ops.i2c_gate_ctrl(adap->fe,0); |
67 | 89 | ||
68 | if (b2[0] == 0xfe) { | 90 | if (b2[0] == 0xfe) { |
69 | info("This device has the Thomson Cable onboard. Which is default."); | 91 | info("This device has the Thomson Cable onboard. Which is default."); |
70 | dibusb_thomson_tuner_attach(adap); | 92 | ret = dibusb_thomson_tuner_attach(adap); |
71 | } else { | 93 | } else { |
72 | u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab }; | ||
73 | info("This device has the Panasonic ENV77H11D5 onboard."); | 94 | info("This device has the Panasonic ENV77H11D5 onboard."); |
74 | adap->pll_addr = 0x60; | 95 | ret = dibusb_panasonic_tuner_attach(adap); |
75 | memcpy(adap->pll_init,bpll,4); | ||
76 | adap->pll_desc = &dvb_pll_tda665x; | ||
77 | } | 96 | } |
78 | 97 | ||
79 | return ret; | 98 | return ret; |
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h index b60781032742..8e847aa73ba1 100644 --- a/drivers/media/dvb/dvb-usb/dibusb.h +++ b/drivers/media/dvb/dvb-usb/dibusb.h | |||
@@ -99,6 +99,7 @@ | |||
99 | struct dibusb_state { | 99 | struct dibusb_state { |
100 | struct dib_fe_xfer_ops ops; | 100 | struct dib_fe_xfer_ops ops; |
101 | int mt2060_present; | 101 | int mt2060_present; |
102 | u8 tuner_addr; | ||
102 | }; | 103 | }; |
103 | 104 | ||
104 | struct dibusb_device_state { | 105 | struct dibusb_device_state { |
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index b5acb11c0bc9..bca1e0905739 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c | |||
@@ -118,7 +118,8 @@ static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_f | |||
118 | { | 118 | { |
119 | struct dvb_usb_adapter *adap = fe->dvb->priv; | 119 | struct dvb_usb_adapter *adap = fe->dvb->priv; |
120 | u8 b[5]; | 120 | u8 b[5]; |
121 | dvb_usb_tuner_calc_regs(fe,fep,b, 5); | 121 | |
122 | fe->ops.tuner_ops.calc_regs(fe, fep, b, sizeof(b)); | ||
122 | if (fe->ops.i2c_gate_ctrl) | 123 | if (fe->ops.i2c_gate_ctrl) |
123 | fe->ops.i2c_gate_ctrl(fe, 1); | 124 | fe->ops.i2c_gate_ctrl(fe, 1); |
124 | return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0); | 125 | return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0); |
@@ -130,12 +131,14 @@ static struct nxt6000_config digitv_nxt6000_config = { | |||
130 | 131 | ||
131 | static int digitv_frontend_attach(struct dvb_usb_adapter *adap) | 132 | static int digitv_frontend_attach(struct dvb_usb_adapter *adap) |
132 | { | 133 | { |
134 | struct digitv_state *st = adap->dev->priv; | ||
135 | |||
133 | if ((adap->fe = dvb_attach(mt352_attach, &digitv_mt352_config, &adap->dev->i2c_adap)) != NULL) { | 136 | if ((adap->fe = dvb_attach(mt352_attach, &digitv_mt352_config, &adap->dev->i2c_adap)) != NULL) { |
134 | adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; | 137 | st->is_nxt6000 = 0; |
135 | return 0; | 138 | return 0; |
136 | } | 139 | } |
137 | if ((adap->fe = dvb_attach(nxt6000_attach, &digitv_nxt6000_config, &adap->dev->i2c_adap)) != NULL) { | 140 | if ((adap->fe = dvb_attach(nxt6000_attach, &digitv_nxt6000_config, &adap->dev->i2c_adap)) != NULL) { |
138 | adap->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params; | 141 | st->is_nxt6000 = 1; |
139 | return 0; | 142 | return 0; |
140 | } | 143 | } |
141 | return -EIO; | 144 | return -EIO; |
@@ -143,8 +146,14 @@ static int digitv_frontend_attach(struct dvb_usb_adapter *adap) | |||
143 | 146 | ||
144 | static int digitv_tuner_attach(struct dvb_usb_adapter *adap) | 147 | static int digitv_tuner_attach(struct dvb_usb_adapter *adap) |
145 | { | 148 | { |
146 | adap->pll_addr = 0x60; | 149 | struct digitv_state *st = adap->dev->priv; |
147 | adap->pll_desc = &dvb_pll_tded4; | 150 | |
151 | if (!dvb_attach(dvb_pll_attach, adap->fe, 0x60, NULL, DVB_PLL_TDED4)) | ||
152 | return -ENODEV; | ||
153 | |||
154 | if (st->is_nxt6000) | ||
155 | adap->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params; | ||
156 | |||
148 | return 0; | 157 | return 0; |
149 | } | 158 | } |
150 | 159 | ||
@@ -273,6 +282,8 @@ static struct dvb_usb_device_properties digitv_properties = { | |||
273 | .usb_ctrl = CYPRESS_FX2, | 282 | .usb_ctrl = CYPRESS_FX2, |
274 | .firmware = "dvb-usb-digitv-02.fw", | 283 | .firmware = "dvb-usb-digitv-02.fw", |
275 | 284 | ||
285 | .size_of_priv = sizeof(struct digitv_state), | ||
286 | |||
276 | .num_adapters = 1, | 287 | .num_adapters = 1, |
277 | .adapter = { | 288 | .adapter = { |
278 | { | 289 | { |
diff --git a/drivers/media/dvb/dvb-usb/digitv.h b/drivers/media/dvb/dvb-usb/digitv.h index 477ee428a70e..8b43e3db8691 100644 --- a/drivers/media/dvb/dvb-usb/digitv.h +++ b/drivers/media/dvb/dvb-usb/digitv.h | |||
@@ -4,6 +4,10 @@ | |||
4 | #define DVB_USB_LOG_PREFIX "digitv" | 4 | #define DVB_USB_LOG_PREFIX "digitv" |
5 | #include "dvb-usb.h" | 5 | #include "dvb-usb.h" |
6 | 6 | ||
7 | struct digitv_state { | ||
8 | int is_nxt6000; | ||
9 | }; | ||
10 | |||
7 | extern int dvb_usb_digitv_debug; | 11 | extern int dvb_usb_digitv_debug; |
8 | #define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args) | 12 | #define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args) |
9 | 13 | ||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index 088b6dee3a7f..23428cd30756 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c | |||
@@ -46,82 +46,3 @@ int dvb_usb_i2c_exit(struct dvb_usb_device *d) | |||
46 | d->state &= ~DVB_USB_STATE_I2C; | 46 | d->state &= ~DVB_USB_STATE_I2C; |
47 | return 0; | 47 | return 0; |
48 | } | 48 | } |
49 | |||
50 | int dvb_usb_tuner_init_i2c(struct dvb_frontend *fe) | ||
51 | { | ||
52 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
53 | struct i2c_msg msg = { .addr = adap->pll_addr, .flags = 0, .buf = adap->pll_init, .len = 4 }; | ||
54 | int ret = 0; | ||
55 | |||
56 | /* if pll_desc is not used */ | ||
57 | if (adap->pll_desc == NULL) | ||
58 | return 0; | ||
59 | |||
60 | if (adap->tuner_pass_ctrl) | ||
61 | adap->tuner_pass_ctrl(fe, 1, adap->pll_addr); | ||
62 | |||
63 | deb_pll("pll init: %x\n",adap->pll_addr); | ||
64 | deb_pll("pll-buf: %x %x %x %x\n",adap->pll_init[0], adap->pll_init[1], | ||
65 | adap->pll_init[2], adap->pll_init[3]); | ||
66 | |||
67 | if (fe->ops.i2c_gate_ctrl) | ||
68 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
69 | if (i2c_transfer (&adap->dev->i2c_adap, &msg, 1) != 1) { | ||
70 | err("tuner i2c write failed for pll_init."); | ||
71 | ret = -EREMOTEIO; | ||
72 | } | ||
73 | msleep(1); | ||
74 | |||
75 | if (adap->tuner_pass_ctrl) | ||
76 | adap->tuner_pass_ctrl(fe,0,adap->pll_addr); | ||
77 | return ret; | ||
78 | } | ||
79 | EXPORT_SYMBOL(dvb_usb_tuner_init_i2c); | ||
80 | |||
81 | int dvb_usb_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 *b, int buf_len) | ||
82 | { | ||
83 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
84 | |||
85 | if (buf_len != 5) | ||
86 | return -EINVAL; | ||
87 | if (adap->pll_desc == NULL) | ||
88 | return 0; | ||
89 | |||
90 | deb_pll("pll addr: %x, freq: %d %p\n",adap->pll_addr, fep->frequency, adap->pll_desc); | ||
91 | |||
92 | b[0] = adap->pll_addr; | ||
93 | dvb_pll_configure(adap->pll_desc, &b[1], fep->frequency, fep->u.ofdm.bandwidth); | ||
94 | |||
95 | deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]); | ||
96 | |||
97 | return 5; | ||
98 | } | ||
99 | EXPORT_SYMBOL(dvb_usb_tuner_calc_regs); | ||
100 | |||
101 | int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) | ||
102 | { | ||
103 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
104 | int ret = 0; | ||
105 | u8 b[5]; | ||
106 | struct i2c_msg msg = { .addr = adap->pll_addr, .flags = 0, .buf = &b[1], .len = 4 }; | ||
107 | |||
108 | dvb_usb_tuner_calc_regs(fe,fep,b,5); | ||
109 | |||
110 | if (adap->tuner_pass_ctrl) | ||
111 | adap->tuner_pass_ctrl(fe, 1, adap->pll_addr); | ||
112 | |||
113 | if (fe->ops.i2c_gate_ctrl) | ||
114 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
115 | |||
116 | if (i2c_transfer(&adap->dev->i2c_adap, &msg, 1) != 1) { | ||
117 | err("tuner i2c write failed for pll_set."); | ||
118 | ret = -EREMOTEIO; | ||
119 | } | ||
120 | msleep(1); | ||
121 | |||
122 | if (adap->tuner_pass_ctrl) | ||
123 | adap->tuner_pass_ctrl(fe, 0, adap->pll_addr); | ||
124 | |||
125 | return ret; | ||
126 | } | ||
127 | EXPORT_SYMBOL(dvb_usb_tuner_set_params_i2c); | ||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 403081689de1..4dfab02a8a0d 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -11,7 +11,9 @@ | |||
11 | 11 | ||
12 | /* Vendor IDs */ | 12 | /* Vendor IDs */ |
13 | #define USB_VID_ADSTECH 0x06e1 | 13 | #define USB_VID_ADSTECH 0x06e1 |
14 | #define USB_VID_AFATECH 0x15a4 | ||
14 | #define USB_VID_ALCOR_MICRO 0x058f | 15 | #define USB_VID_ALCOR_MICRO 0x058f |
16 | #define USB_VID_ALINK 0x05e3 | ||
15 | #define USB_VID_ANCHOR 0x0547 | 17 | #define USB_VID_ANCHOR 0x0547 |
16 | #define USB_VID_ANUBIS_ELECTRONIC 0x10fd | 18 | #define USB_VID_ANUBIS_ELECTRONIC 0x10fd |
17 | #define USB_VID_AVERMEDIA 0x07ca | 19 | #define USB_VID_AVERMEDIA 0x07ca |
@@ -35,6 +37,7 @@ | |||
35 | #define USB_VID_MSI 0x0db0 | 37 | #define USB_VID_MSI 0x0db0 |
36 | #define USB_VID_OPERA1 0x695c | 38 | #define USB_VID_OPERA1 0x695c |
37 | #define USB_VID_PINNACLE 0x2304 | 39 | #define USB_VID_PINNACLE 0x2304 |
40 | #define USB_VID_TERRATEC 0x0ccd | ||
38 | #define USB_VID_VISIONPLUS 0x13d3 | 41 | #define USB_VID_VISIONPLUS 0x13d3 |
39 | #define USB_VID_TWINHAN 0x1822 | 42 | #define USB_VID_TWINHAN 0x1822 |
40 | #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 | 43 | #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 |
@@ -44,6 +47,8 @@ | |||
44 | /* Product IDs */ | 47 | /* Product IDs */ |
45 | #define USB_PID_ADSTECH_USB2_COLD 0xa333 | 48 | #define USB_PID_ADSTECH_USB2_COLD 0xa333 |
46 | #define USB_PID_ADSTECH_USB2_WARM 0xa334 | 49 | #define USB_PID_ADSTECH_USB2_WARM 0xa334 |
50 | #define USB_PID_AFATECH_AF9005 0x9020 | ||
51 | #define USB_VID_ALINK_DTU 0xf170 | ||
47 | #define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 | 52 | #define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 |
48 | #define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 | 53 | #define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 |
49 | #define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 | 54 | #define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 |
@@ -69,6 +74,7 @@ | |||
69 | #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 | 74 | #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 |
70 | #define USB_PID_KWORLD_VSTREAM_COLD 0x17de | 75 | #define USB_PID_KWORLD_VSTREAM_COLD 0x17de |
71 | #define USB_PID_KWORLD_VSTREAM_WARM 0x17df | 76 | #define USB_PID_KWORLD_VSTREAM_WARM 0x17df |
77 | #define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 | ||
72 | #define USB_PID_TWINHAN_VP7041_COLD 0x3201 | 78 | #define USB_PID_TWINHAN_VP7041_COLD 0x3201 |
73 | #define USB_PID_TWINHAN_VP7041_WARM 0x3202 | 79 | #define USB_PID_TWINHAN_VP7041_WARM 0x3202 |
74 | #define USB_PID_TWINHAN_VP7020_COLD 0x3203 | 80 | #define USB_PID_TWINHAN_VP7020_COLD 0x3203 |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index 9200a30dd1b9..7b9f35bfb4f0 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | |||
@@ -110,7 +110,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) | |||
110 | input_dev->name = "IR-receiver inside an USB DVB receiver"; | 110 | input_dev->name = "IR-receiver inside an USB DVB receiver"; |
111 | input_dev->phys = d->rc_phys; | 111 | input_dev->phys = d->rc_phys; |
112 | usb_to_input_id(d->udev, &input_dev->id); | 112 | usb_to_input_id(d->udev, &input_dev->id); |
113 | input_dev->cdev.dev = &d->udev->dev; | 113 | input_dev->dev.parent = &d->udev->dev; |
114 | 114 | ||
115 | /* set the bits for the keys */ | 115 | /* set the bits for the keys */ |
116 | deb_rc("key map size: %d\n", d->props.rc_key_map_size); | 116 | deb_rc("key map size: %d\n", d->props.rc_key_map_size); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index 6f824a569e14..d1b3c7b81fff 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h | |||
@@ -297,12 +297,6 @@ struct dvb_usb_adapter { | |||
297 | int feedcount; | 297 | int feedcount; |
298 | int pid_filtering; | 298 | int pid_filtering; |
299 | 299 | ||
300 | /* tuner programming information */ | ||
301 | u8 pll_addr; | ||
302 | u8 pll_init[4]; | ||
303 | struct dvb_pll_desc *pll_desc; | ||
304 | int (*tuner_pass_ctrl) (struct dvb_frontend *, int, u8); | ||
305 | |||
306 | /* dvb */ | 300 | /* dvb */ |
307 | struct dvb_adapter dvb_adap; | 301 | struct dvb_adapter dvb_adap; |
308 | struct dmxdev dmxdev; | 302 | struct dmxdev dmxdev; |
@@ -388,11 +382,6 @@ extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16); | |||
388 | /* commonly used remote control parsing */ | 382 | /* commonly used remote control parsing */ |
389 | extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); | 383 | extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); |
390 | 384 | ||
391 | /* commonly used pll init and set functions */ | ||
392 | extern int dvb_usb_tuner_init_i2c(struct dvb_frontend *); | ||
393 | extern int dvb_usb_tuner_calc_regs(struct dvb_frontend *, struct dvb_frontend_parameters *, u8 *buf, int buf_len); | ||
394 | extern int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); | ||
395 | |||
396 | /* commonly used firmware download types and function */ | 385 | /* commonly used firmware download types and function */ |
397 | struct hexline { | 386 | struct hexline { |
398 | u8 len; | 387 | u8 len; |
diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c index e0587e663591..f01d99c1c43c 100644 --- a/drivers/media/dvb/dvb-usb/gl861.c +++ b/drivers/media/dvb/dvb-usb/gl861.c | |||
@@ -157,6 +157,7 @@ static int gl861_probe(struct usb_interface *intf, | |||
157 | 157 | ||
158 | static struct usb_device_id gl861_table [] = { | 158 | static struct usb_device_id gl861_table [] = { |
159 | { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801) }, | 159 | { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801) }, |
160 | { USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU) }, | ||
160 | { } /* Terminating entry */ | 161 | { } /* Terminating entry */ |
161 | }; | 162 | }; |
162 | MODULE_DEVICE_TABLE (usb, gl861_table); | 163 | MODULE_DEVICE_TABLE (usb, gl861_table); |
@@ -187,12 +188,16 @@ static struct dvb_usb_device_properties gl861_properties = { | |||
187 | }}, | 188 | }}, |
188 | .i2c_algo = &gl861_i2c_algo, | 189 | .i2c_algo = &gl861_i2c_algo, |
189 | 190 | ||
190 | .num_device_descs = 1, | 191 | .num_device_descs = 2, |
191 | .devices = { | 192 | .devices = { |
192 | { "MSI Mega Sky 55801 DVB-T USB2.0", | 193 | { "MSI Mega Sky 55801 DVB-T USB2.0", |
193 | { &gl861_table[0], NULL }, | 194 | { &gl861_table[0], NULL }, |
194 | { NULL }, | 195 | { NULL }, |
195 | }, | 196 | }, |
197 | { "A-LINK DTU DVB-T USB2.0", | ||
198 | { &gl861_table[1], NULL }, | ||
199 | { NULL }, | ||
200 | }, | ||
196 | } | 201 | } |
197 | }; | 202 | }; |
198 | 203 | ||
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c index c546ddeda5d4..a956bc503a4c 100644 --- a/drivers/media/dvb/dvb-usb/m920x.c +++ b/drivers/media/dvb/dvb-usb/m920x.c | |||
@@ -22,6 +22,8 @@ static int dvb_usb_m920x_debug; | |||
22 | module_param_named(debug,dvb_usb_m920x_debug, int, 0644); | 22 | module_param_named(debug,dvb_usb_m920x_debug, int, 0644); |
23 | MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); | 23 | MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); |
24 | 24 | ||
25 | static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid); | ||
26 | |||
25 | static inline int m920x_read(struct usb_device *udev, u8 request, u16 value, | 27 | static inline int m920x_read(struct usb_device *udev, u8 request, u16 value, |
26 | u16 index, void *data, int size) | 28 | u16 index, void *data, int size) |
27 | { | 29 | { |
@@ -57,7 +59,8 @@ static inline int m920x_write(struct usb_device *udev, u8 request, | |||
57 | 59 | ||
58 | static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq) | 60 | static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq) |
59 | { | 61 | { |
60 | int ret = 0; | 62 | int ret = 0, i, epi, flags = 0; |
63 | int adap_enabled[M9206_MAX_ADAPTERS] = { 0 }; | ||
61 | 64 | ||
62 | /* Remote controller init. */ | 65 | /* Remote controller init. */ |
63 | if (d->props.rc_query) { | 66 | if (d->props.rc_query) { |
@@ -76,9 +79,51 @@ static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq) | |||
76 | deb("Initialising remote control success\n"); | 79 | deb("Initialising remote control success\n"); |
77 | } | 80 | } |
78 | 81 | ||
82 | for (i = 0; i < d->props.num_adapters; i++) | ||
83 | flags |= d->adapter[i].props.caps; | ||
84 | |||
85 | /* Some devices(Dposh) might crash if we attempt touch at all. */ | ||
86 | if (flags & DVB_USB_ADAP_HAS_PID_FILTER) { | ||
87 | for (i = 0; i < d->props.num_adapters; i++) { | ||
88 | epi = d->adapter[i].props.stream.endpoint - 0x81; | ||
89 | |||
90 | if (epi < 0 || epi >= M9206_MAX_ADAPTERS) { | ||
91 | printk(KERN_INFO "m920x: Unexpected adapter endpoint!\n"); | ||
92 | return -EINVAL; | ||
93 | } | ||
94 | |||
95 | adap_enabled[epi] = 1; | ||
96 | } | ||
97 | |||
98 | for (i = 0; i < M9206_MAX_ADAPTERS; i++) { | ||
99 | if (adap_enabled[i]) | ||
100 | continue; | ||
101 | |||
102 | if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x0)) != 0) | ||
103 | return ret; | ||
104 | |||
105 | if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x02f5)) != 0) | ||
106 | return ret; | ||
107 | } | ||
108 | } | ||
109 | |||
79 | return ret; | 110 | return ret; |
80 | } | 111 | } |
81 | 112 | ||
113 | static int m920x_init_ep(struct usb_interface *intf) | ||
114 | { | ||
115 | struct usb_device *udev = interface_to_usbdev(intf); | ||
116 | struct usb_host_interface *alt; | ||
117 | |||
118 | if ((alt = usb_altnum_to_altsetting(intf, 1)) == NULL) { | ||
119 | deb("No alt found!\n"); | ||
120 | return -ENODEV; | ||
121 | } | ||
122 | |||
123 | return usb_set_interface(udev, alt->desc.bInterfaceNumber, | ||
124 | alt->desc.bAlternateSetting); | ||
125 | } | ||
126 | |||
82 | static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | 127 | static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) |
83 | { | 128 | { |
84 | struct m920x_state *m = d->priv; | 129 | struct m920x_state *m = d->priv; |
@@ -211,8 +256,7 @@ static struct i2c_algorithm m920x_i2c_algo = { | |||
211 | }; | 256 | }; |
212 | 257 | ||
213 | /* pid filter */ | 258 | /* pid filter */ |
214 | static int m920x_set_filter(struct dvb_usb_adapter *adap, | 259 | static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid) |
215 | int type, int idx, int pid) | ||
216 | { | 260 | { |
217 | int ret = 0; | 261 | int ret = 0; |
218 | 262 | ||
@@ -221,10 +265,10 @@ static int m920x_set_filter(struct dvb_usb_adapter *adap, | |||
221 | 265 | ||
222 | pid |= 0x8000; | 266 | pid |= 0x8000; |
223 | 267 | ||
224 | if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0) | 268 | if ((ret = m920x_write(d->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0) |
225 | return ret; | 269 | return ret; |
226 | 270 | ||
227 | if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0) | 271 | if ((ret = m920x_write(d->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0) |
228 | return ret; | 272 | return ret; |
229 | 273 | ||
230 | return ret; | 274 | return ret; |
@@ -233,40 +277,35 @@ static int m920x_set_filter(struct dvb_usb_adapter *adap, | |||
233 | static int m920x_update_filters(struct dvb_usb_adapter *adap) | 277 | static int m920x_update_filters(struct dvb_usb_adapter *adap) |
234 | { | 278 | { |
235 | struct m920x_state *m = adap->dev->priv; | 279 | struct m920x_state *m = adap->dev->priv; |
236 | int enabled = m->filtering_enabled; | 280 | int enabled = m->filtering_enabled[adap->id]; |
237 | int i, ret = 0, filter = 0; | 281 | int i, ret = 0, filter = 0; |
282 | int ep = adap->props.stream.endpoint; | ||
238 | 283 | ||
239 | for (i = 0; i < M9206_MAX_FILTERS; i++) | 284 | for (i = 0; i < M9206_MAX_FILTERS; i++) |
240 | if (m->filters[i] == 8192) | 285 | if (m->filters[adap->id][i] == 8192) |
241 | enabled = 0; | 286 | enabled = 0; |
242 | 287 | ||
243 | /* Disable all filters */ | 288 | /* Disable all filters */ |
244 | if ((ret = m920x_set_filter(adap, 0x81, 1, enabled)) != 0) | 289 | if ((ret = m920x_set_filter(adap->dev, ep, 1, enabled)) != 0) |
245 | return ret; | 290 | return ret; |
246 | 291 | ||
247 | for (i = 0; i < M9206_MAX_FILTERS; i++) | 292 | for (i = 0; i < M9206_MAX_FILTERS; i++) |
248 | if ((ret = m920x_set_filter(adap, 0x81, i + 2, 0)) != 0) | 293 | if ((ret = m920x_set_filter(adap->dev, ep, i + 2, 0)) != 0) |
249 | return ret; | 294 | return ret; |
250 | 295 | ||
251 | if ((ret = m920x_set_filter(adap, 0x82, 0, 0x0)) != 0) | ||
252 | return ret; | ||
253 | |||
254 | /* Set */ | 296 | /* Set */ |
255 | if (enabled) { | 297 | if (enabled) { |
256 | for (i = 0; i < M9206_MAX_FILTERS; i++) { | 298 | for (i = 0; i < M9206_MAX_FILTERS; i++) { |
257 | if (m->filters[i] == 0) | 299 | if (m->filters[adap->id][i] == 0) |
258 | continue; | 300 | continue; |
259 | 301 | ||
260 | if ((ret = m920x_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0) | 302 | if ((ret = m920x_set_filter(adap->dev, ep, filter + 2, m->filters[adap->id][i])) != 0) |
261 | return ret; | 303 | return ret; |
262 | 304 | ||
263 | filter++; | 305 | filter++; |
264 | } | 306 | } |
265 | } | 307 | } |
266 | 308 | ||
267 | if ((ret = m920x_set_filter(adap, 0x82, 0, 0x02f5)) != 0) | ||
268 | return ret; | ||
269 | |||
270 | return ret; | 309 | return ret; |
271 | } | 310 | } |
272 | 311 | ||
@@ -274,7 +313,7 @@ static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) | |||
274 | { | 313 | { |
275 | struct m920x_state *m = adap->dev->priv; | 314 | struct m920x_state *m = adap->dev->priv; |
276 | 315 | ||
277 | m->filtering_enabled = onoff ? 1 : 0; | 316 | m->filtering_enabled[adap->id] = onoff ? 1 : 0; |
278 | 317 | ||
279 | return m920x_update_filters(adap); | 318 | return m920x_update_filters(adap); |
280 | } | 319 | } |
@@ -283,7 +322,7 @@ static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, in | |||
283 | { | 322 | { |
284 | struct m920x_state *m = adap->dev->priv; | 323 | struct m920x_state *m = adap->dev->priv; |
285 | 324 | ||
286 | m->filters[index] = onoff ? pid : 0; | 325 | m->filters[adap->id][index] = onoff ? pid : 0; |
287 | 326 | ||
288 | return m920x_update_filters(adap); | 327 | return m920x_update_filters(adap); |
289 | } | 328 | } |
@@ -368,6 +407,7 @@ static int m920x_identify_state(struct usb_device *udev, | |||
368 | /* demod configurations */ | 407 | /* demod configurations */ |
369 | static int m920x_mt352_demod_init(struct dvb_frontend *fe) | 408 | static int m920x_mt352_demod_init(struct dvb_frontend *fe) |
370 | { | 409 | { |
410 | int ret; | ||
371 | u8 config[] = { CONFIG, 0x3d }; | 411 | u8 config[] = { CONFIG, 0x3d }; |
372 | u8 clock[] = { CLOCK_CTL, 0x30 }; | 412 | u8 clock[] = { CLOCK_CTL, 0x30 }; |
373 | u8 reset[] = { RESET, 0x80 }; | 413 | u8 reset[] = { RESET, 0x80 }; |
@@ -377,17 +417,25 @@ static int m920x_mt352_demod_init(struct dvb_frontend *fe) | |||
377 | u8 unk1[] = { 0x93, 0x1a }; | 417 | u8 unk1[] = { 0x93, 0x1a }; |
378 | u8 unk2[] = { 0xb5, 0x7a }; | 418 | u8 unk2[] = { 0xb5, 0x7a }; |
379 | 419 | ||
380 | mt352_write(fe, config, ARRAY_SIZE(config)); | ||
381 | mt352_write(fe, clock, ARRAY_SIZE(clock)); | ||
382 | mt352_write(fe, reset, ARRAY_SIZE(reset)); | ||
383 | mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl)); | ||
384 | mt352_write(fe, agc, ARRAY_SIZE(agc)); | ||
385 | mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc)); | ||
386 | mt352_write(fe, unk1, ARRAY_SIZE(unk1)); | ||
387 | mt352_write(fe, unk2, ARRAY_SIZE(unk2)); | ||
388 | |||
389 | deb("Demod init!\n"); | 420 | deb("Demod init!\n"); |
390 | 421 | ||
422 | if ((ret = mt352_write(fe, config, ARRAY_SIZE(config))) != 0) | ||
423 | return ret; | ||
424 | if ((ret = mt352_write(fe, clock, ARRAY_SIZE(clock))) != 0) | ||
425 | return ret; | ||
426 | if ((ret = mt352_write(fe, reset, ARRAY_SIZE(reset))) != 0) | ||
427 | return ret; | ||
428 | if ((ret = mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl))) != 0) | ||
429 | return ret; | ||
430 | if ((ret = mt352_write(fe, agc, ARRAY_SIZE(agc))) != 0) | ||
431 | return ret; | ||
432 | if ((ret = mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc))) != 0) | ||
433 | return ret; | ||
434 | if ((ret = mt352_write(fe, unk1, ARRAY_SIZE(unk1))) != 0) | ||
435 | return ret; | ||
436 | if ((ret = mt352_write(fe, unk2, ARRAY_SIZE(unk2))) != 0) | ||
437 | return ret; | ||
438 | |||
391 | return 0; | 439 | return 0; |
392 | } | 440 | } |
393 | 441 | ||
@@ -558,8 +606,7 @@ static struct dvb_usb_device_properties dposh_properties; | |||
558 | static int m920x_probe(struct usb_interface *intf, | 606 | static int m920x_probe(struct usb_interface *intf, |
559 | const struct usb_device_id *id) | 607 | const struct usb_device_id *id) |
560 | { | 608 | { |
561 | struct dvb_usb_device *d; | 609 | struct dvb_usb_device *d = NULL; |
562 | struct usb_host_interface *alt; | ||
563 | int ret; | 610 | int ret; |
564 | struct m920x_inits *rc_init_seq = NULL; | 611 | struct m920x_inits *rc_init_seq = NULL; |
565 | int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber; | 612 | int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber; |
@@ -604,23 +651,13 @@ static int m920x_probe(struct usb_interface *intf, | |||
604 | * tvwalkertwin_properties already configured both | 651 | * tvwalkertwin_properties already configured both |
605 | * tuners, so there is nothing for us to do here | 652 | * tuners, so there is nothing for us to do here |
606 | */ | 653 | */ |
607 | |||
608 | return -ENODEV; | ||
609 | } | 654 | } |
610 | 655 | ||
611 | found: | 656 | found: |
612 | alt = usb_altnum_to_altsetting(intf, 1); | 657 | if ((ret = m920x_init_ep(intf)) < 0) |
613 | if (alt == NULL) { | ||
614 | deb("No alt found!\n"); | ||
615 | return -ENODEV; | ||
616 | } | ||
617 | |||
618 | ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, | ||
619 | alt->desc.bAlternateSetting); | ||
620 | if (ret < 0) | ||
621 | return ret; | 658 | return ret; |
622 | 659 | ||
623 | if ((ret = m920x_init(d, rc_init_seq)) != 0) | 660 | if (d && (ret = m920x_init(d, rc_init_seq)) != 0) |
624 | return ret; | 661 | return ret; |
625 | 662 | ||
626 | return ret; | 663 | return ret; |
@@ -737,9 +774,9 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = { | |||
737 | * | 774 | * |
738 | * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A | 775 | * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A |
739 | * TDA10046 #0 is located at i2c address 0x08 | 776 | * TDA10046 #0 is located at i2c address 0x08 |
740 | * TDA10046 #1 is located at i2c address 0x0b (presently disabled - not yet working) | 777 | * TDA10046 #1 is located at i2c address 0x0b |
741 | * TDA8275A #0 is located at i2c address 0x60 | 778 | * TDA8275A #0 is located at i2c address 0x60 |
742 | * TDA8275A #1 is located at i2c address 0x61 (presently disabled - not yet working) | 779 | * TDA8275A #1 is located at i2c address 0x61 |
743 | */ | 780 | */ |
744 | static struct dvb_usb_device_properties tvwalkertwin_properties = { | 781 | static struct dvb_usb_device_properties tvwalkertwin_properties = { |
745 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 782 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
@@ -756,7 +793,7 @@ static struct dvb_usb_device_properties tvwalkertwin_properties = { | |||
756 | .size_of_priv = sizeof(struct m920x_state), | 793 | .size_of_priv = sizeof(struct m920x_state), |
757 | 794 | ||
758 | .identify_state = m920x_identify_state, | 795 | .identify_state = m920x_identify_state, |
759 | .num_adapters = 1, | 796 | .num_adapters = 2, |
760 | .adapter = {{ | 797 | .adapter = {{ |
761 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | 798 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | |
762 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | 799 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, |
diff --git a/drivers/media/dvb/dvb-usb/m920x.h b/drivers/media/dvb/dvb-usb/m920x.h index 2c8942d04222..37532890accd 100644 --- a/drivers/media/dvb/dvb-usb/m920x.h +++ b/drivers/media/dvb/dvb-usb/m920x.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #define M9206_FW 0x30 | 18 | #define M9206_FW 0x30 |
19 | 19 | ||
20 | #define M9206_MAX_FILTERS 8 | 20 | #define M9206_MAX_FILTERS 8 |
21 | #define M9206_MAX_ADAPTERS 2 | ||
21 | 22 | ||
22 | /* | 23 | /* |
23 | sequences found in logs: | 24 | sequences found in logs: |
@@ -60,8 +61,8 @@ response to a write, is unknown. | |||
60 | */ | 61 | */ |
61 | 62 | ||
62 | struct m920x_state { | 63 | struct m920x_state { |
63 | u16 filters[M9206_MAX_FILTERS]; | 64 | u16 filters[M9206_MAX_ADAPTERS][M9206_MAX_FILTERS]; |
64 | int filtering_enabled; | 65 | int filtering_enabled[M9206_MAX_ADAPTERS]; |
65 | int rep_count; | 66 | int rep_count; |
66 | }; | 67 | }; |
67 | 68 | ||
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c index 518d7ad217df..d7c04951ceab 100644 --- a/drivers/media/dvb/dvb-usb/opera1.c +++ b/drivers/media/dvb/dvb-usb/opera1.c | |||
@@ -263,7 +263,7 @@ static int opera1_tuner_attach(struct dvb_usb_adapter *adap) | |||
263 | { | 263 | { |
264 | dvb_attach( | 264 | dvb_attach( |
265 | dvb_pll_attach, adap->fe, 0xc0>>1, | 265 | dvb_pll_attach, adap->fe, 0xc0>>1, |
266 | &adap->dev->i2c_adap, &dvb_pll_opera1 | 266 | &adap->dev->i2c_adap, DVB_PLL_OPERA1 |
267 | ); | 267 | ); |
268 | return 0; | 268 | return 0; |
269 | } | 269 | } |
@@ -435,9 +435,9 @@ static int opera1_xilinx_load_firmware(struct usb_device *dev, | |||
435 | { | 435 | { |
436 | const struct firmware *fw = NULL; | 436 | const struct firmware *fw = NULL; |
437 | u8 *b, *p; | 437 | u8 *b, *p; |
438 | int ret = 0, i; | 438 | int ret = 0, i,fpgasize=40; |
439 | u8 testval; | 439 | u8 testval; |
440 | info("start downloading fpga firmware"); | 440 | info("start downloading fpga firmware %s",filename); |
441 | 441 | ||
442 | if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) { | 442 | if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) { |
443 | err("did not find the firmware file. (%s) " | 443 | err("did not find the firmware file. (%s) " |
@@ -454,17 +454,20 @@ static int opera1_xilinx_load_firmware(struct usb_device *dev, | |||
454 | /* clear fpga ? */ | 454 | /* clear fpga ? */ |
455 | opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1, | 455 | opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1, |
456 | OPERA_WRITE_MSG); | 456 | OPERA_WRITE_MSG); |
457 | for (i = 0; p[i] != 0 && i < fw->size;) { | 457 | for (i = 0; i < fw->size;) { |
458 | if ( (fw->size - i) <fpgasize){ | ||
459 | fpgasize=fw->size-i; | ||
460 | } | ||
458 | b = (u8 *) p + i; | 461 | b = (u8 *) p + i; |
459 | if (opera1_xilinx_rw | 462 | if (opera1_xilinx_rw |
460 | (dev, OPERA_WRITE_FX2, 0x0, b + 1, b[0], | 463 | (dev, OPERA_WRITE_FX2, 0x0, b , fpgasize, |
461 | OPERA_WRITE_MSG) != b[0] | 464 | OPERA_WRITE_MSG) != fpgasize |
462 | ) { | 465 | ) { |
463 | err("error while transferring firmware"); | 466 | err("error while transferring firmware"); |
464 | ret = -EINVAL; | 467 | ret = -EINVAL; |
465 | break; | 468 | break; |
466 | } | 469 | } |
467 | i = i + 1 + b[0]; | 470 | i = i + fpgasize; |
468 | } | 471 | } |
469 | /* restart the CPU */ | 472 | /* restart the CPU */ |
470 | if (ret || opera1_xilinx_rw | 473 | if (ret || opera1_xilinx_rw |
@@ -534,18 +537,16 @@ static struct dvb_usb_device_properties opera1_properties = { | |||
534 | static int opera1_probe(struct usb_interface *intf, | 537 | static int opera1_probe(struct usb_interface *intf, |
535 | const struct usb_device_id *id) | 538 | const struct usb_device_id *id) |
536 | { | 539 | { |
537 | struct dvb_usb_device *d; | ||
538 | struct usb_device *udev = interface_to_usbdev(intf); | 540 | struct usb_device *udev = interface_to_usbdev(intf); |
539 | 541 | ||
540 | if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM && | 542 | if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM && |
541 | udev->descriptor.idVendor == USB_VID_OPERA1 && | 543 | udev->descriptor.idVendor == USB_VID_OPERA1 && |
542 | (d == NULL | 544 | opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga-01.fw") != 0 |
543 | || opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga.fw") != 0) | 545 | ) { |
544 | ) { | ||
545 | return -EINVAL; | 546 | return -EINVAL; |
546 | } | 547 | } |
547 | 548 | ||
548 | if (dvb_usb_device_init(intf, &opera1_properties, THIS_MODULE, &d) != 0) | 549 | if (dvb_usb_device_init(intf, &opera1_properties, THIS_MODULE, NULL) != 0) |
549 | return -EINVAL; | 550 | return -EINVAL; |
550 | return 0; | 551 | return 0; |
551 | } | 552 | } |
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c index f77b48f76582..0dcab3d4e236 100644 --- a/drivers/media/dvb/dvb-usb/umt-010.c +++ b/drivers/media/dvb/dvb-usb/umt-010.c | |||
@@ -65,9 +65,7 @@ static int umt_mt352_frontend_attach(struct dvb_usb_adapter *adap) | |||
65 | 65 | ||
66 | static int umt_tuner_attach (struct dvb_usb_adapter *adap) | 66 | static int umt_tuner_attach (struct dvb_usb_adapter *adap) |
67 | { | 67 | { |
68 | adap->pll_addr = 0x61; | 68 | dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, DVB_PLL_TUA6034); |
69 | adap->pll_desc = &dvb_pll_tua6034; | ||
70 | adap->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; | ||
71 | return 0; | 69 | return 0; |
72 | } | 70 | } |
73 | 71 | ||
@@ -84,8 +82,8 @@ static int umt_probe(struct usb_interface *intf, | |||
84 | 82 | ||
85 | /* do not change the order of the ID table */ | 83 | /* do not change the order of the ID table */ |
86 | static struct usb_device_id umt_table [] = { | 84 | static struct usb_device_id umt_table [] = { |
87 | /* 00 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) }, | 85 | /* 00 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) }, |
88 | /* 01 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) }, | 86 | /* 01 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) }, |
89 | { } /* Terminating entry */ | 87 | { } /* Terminating entry */ |
90 | }; | 88 | }; |
91 | MODULE_DEVICE_TABLE (usb, umt_table); | 89 | MODULE_DEVICE_TABLE (usb, umt_table); |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 27f386585d43..156b062e02c4 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the kernel DVB frontend device drivers. | 2 | # Makefile for the kernel DVB frontend device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ | 5 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ |
6 | 6 | ||
7 | obj-$(CONFIG_DVB_PLL) += dvb-pll.o | 7 | obj-$(CONFIG_DVB_PLL) += dvb-pll.o |
8 | obj-$(CONFIG_DVB_STV0299) += stv0299.o | 8 | obj-$(CONFIG_DVB_STV0299) += stv0299.o |
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 335219ebce2d..1dc164d5488c 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include "dvb_frontend.h" | 34 | #include "dvb_frontend.h" |
35 | #include "dvb-pll.h" | ||
36 | #include "cx22702.h" | 35 | #include "cx22702.h" |
37 | 36 | ||
38 | 37 | ||
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c index 732e94aaa364..0834c0677fef 100644 --- a/drivers/media/dvb/frontends/cx24123.c +++ b/drivers/media/dvb/frontends/cx24123.c | |||
@@ -917,7 +917,7 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
917 | static int cx24123_tune(struct dvb_frontend* fe, | 917 | static int cx24123_tune(struct dvb_frontend* fe, |
918 | struct dvb_frontend_parameters* params, | 918 | struct dvb_frontend_parameters* params, |
919 | unsigned int mode_flags, | 919 | unsigned int mode_flags, |
920 | int *delay, | 920 | unsigned int *delay, |
921 | fe_status_t *status) | 921 | fe_status_t *status) |
922 | { | 922 | { |
923 | int retval = 0; | 923 | int retval = 0; |
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 5f96ffda91ad..0c0b94767bc1 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -24,6 +24,23 @@ | |||
24 | 24 | ||
25 | #include "dvb-pll.h" | 25 | #include "dvb-pll.h" |
26 | 26 | ||
27 | struct dvb_pll_desc { | ||
28 | char *name; | ||
29 | u32 min; | ||
30 | u32 max; | ||
31 | u32 iffreq; | ||
32 | void (*set)(u8 *buf, const struct dvb_frontend_parameters *params); | ||
33 | u8 *initdata; | ||
34 | u8 *sleepdata; | ||
35 | int count; | ||
36 | struct { | ||
37 | u32 limit; | ||
38 | u32 stepsize; | ||
39 | u8 config; | ||
40 | u8 cb; | ||
41 | } entries[12]; | ||
42 | }; | ||
43 | |||
27 | /* ----------------------------------------------------------- */ | 44 | /* ----------------------------------------------------------- */ |
28 | /* descriptions */ | 45 | /* descriptions */ |
29 | 46 | ||
@@ -38,7 +55,13 @@ | |||
38 | 0x50 = AGC Take over point = 103 dBuV */ | 55 | 0x50 = AGC Take over point = 103 dBuV */ |
39 | static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 }; | 56 | static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 }; |
40 | 57 | ||
41 | struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { | 58 | /* 0x04 = 166.67 kHz divider |
59 | |||
60 | 0x80 = AGC Time constant 50ms Iagc = 9 uA | ||
61 | 0x20 = AGC Take over point = 112 dBuV */ | ||
62 | static u8 tua603x_agc112[] = { 2, 0x80|0x40|0x18|0x04|0x01, 0x80|0x20 }; | ||
63 | |||
64 | static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { | ||
42 | .name = "Thomson dtt7579", | 65 | .name = "Thomson dtt7579", |
43 | .min = 177000000, | 66 | .min = 177000000, |
44 | .max = 858000000, | 67 | .max = 858000000, |
@@ -52,9 +75,8 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { | |||
52 | { 999999999, 166667, 0xf4, 0x08 }, | 75 | { 999999999, 166667, 0xf4, 0x08 }, |
53 | }, | 76 | }, |
54 | }; | 77 | }; |
55 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7579); | ||
56 | 78 | ||
57 | struct dvb_pll_desc dvb_pll_thomson_dtt7610 = { | 79 | static struct dvb_pll_desc dvb_pll_thomson_dtt7610 = { |
58 | .name = "Thomson dtt7610", | 80 | .name = "Thomson dtt7610", |
59 | .min = 44000000, | 81 | .min = 44000000, |
60 | .max = 958000000, | 82 | .max = 958000000, |
@@ -66,19 +88,19 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7610 = { | |||
66 | { 999999999, 62500, 0x8e, 0x3c }, | 88 | { 999999999, 62500, 0x8e, 0x3c }, |
67 | }, | 89 | }, |
68 | }; | 90 | }; |
69 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7610); | ||
70 | 91 | ||
71 | static void thomson_dtt759x_bw(u8 *buf, u32 freq, int bandwidth) | 92 | static void thomson_dtt759x_bw(u8 *buf, |
93 | const struct dvb_frontend_parameters *params) | ||
72 | { | 94 | { |
73 | if (BANDWIDTH_7_MHZ == bandwidth) | 95 | if (BANDWIDTH_7_MHZ == params->u.ofdm.bandwidth) |
74 | buf[3] |= 0x10; | 96 | buf[3] |= 0x10; |
75 | } | 97 | } |
76 | 98 | ||
77 | struct dvb_pll_desc dvb_pll_thomson_dtt759x = { | 99 | static struct dvb_pll_desc dvb_pll_thomson_dtt759x = { |
78 | .name = "Thomson dtt759x", | 100 | .name = "Thomson dtt759x", |
79 | .min = 177000000, | 101 | .min = 177000000, |
80 | .max = 896000000, | 102 | .max = 896000000, |
81 | .setbw = thomson_dtt759x_bw, | 103 | .set = thomson_dtt759x_bw, |
82 | .iffreq= 36166667, | 104 | .iffreq= 36166667, |
83 | .sleepdata = (u8[]){ 2, 0x84, 0x03 }, | 105 | .sleepdata = (u8[]){ 2, 0x84, 0x03 }, |
84 | .count = 5, | 106 | .count = 5, |
@@ -90,9 +112,8 @@ struct dvb_pll_desc dvb_pll_thomson_dtt759x = { | |||
90 | { 999999999, 166667, 0xfc, 0x08 }, | 112 | { 999999999, 166667, 0xfc, 0x08 }, |
91 | }, | 113 | }, |
92 | }; | 114 | }; |
93 | EXPORT_SYMBOL(dvb_pll_thomson_dtt759x); | ||
94 | 115 | ||
95 | struct dvb_pll_desc dvb_pll_lg_z201 = { | 116 | static struct dvb_pll_desc dvb_pll_lg_z201 = { |
96 | .name = "LG z201", | 117 | .name = "LG z201", |
97 | .min = 174000000, | 118 | .min = 174000000, |
98 | .max = 862000000, | 119 | .max = 862000000, |
@@ -107,9 +128,8 @@ struct dvb_pll_desc dvb_pll_lg_z201 = { | |||
107 | { 999999999, 166667, 0xfc, 0x04 }, | 128 | { 999999999, 166667, 0xfc, 0x04 }, |
108 | }, | 129 | }, |
109 | }; | 130 | }; |
110 | EXPORT_SYMBOL(dvb_pll_lg_z201); | ||
111 | 131 | ||
112 | struct dvb_pll_desc dvb_pll_microtune_4042 = { | 132 | static struct dvb_pll_desc dvb_pll_microtune_4042 = { |
113 | .name = "Microtune 4042 FI5", | 133 | .name = "Microtune 4042 FI5", |
114 | .min = 57000000, | 134 | .min = 57000000, |
115 | .max = 858000000, | 135 | .max = 858000000, |
@@ -121,9 +141,8 @@ struct dvb_pll_desc dvb_pll_microtune_4042 = { | |||
121 | { 999999999, 62500, 0x8e, 0x31 }, | 141 | { 999999999, 62500, 0x8e, 0x31 }, |
122 | }, | 142 | }, |
123 | }; | 143 | }; |
124 | EXPORT_SYMBOL(dvb_pll_microtune_4042); | ||
125 | 144 | ||
126 | struct dvb_pll_desc dvb_pll_thomson_dtt761x = { | 145 | static struct dvb_pll_desc dvb_pll_thomson_dtt761x = { |
127 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ | 146 | /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ |
128 | .name = "Thomson dtt761x", | 147 | .name = "Thomson dtt761x", |
129 | .min = 57000000, | 148 | .min = 57000000, |
@@ -137,9 +156,8 @@ struct dvb_pll_desc dvb_pll_thomson_dtt761x = { | |||
137 | { 999999999, 62500, 0x8e, 0x3c }, | 156 | { 999999999, 62500, 0x8e, 0x3c }, |
138 | }, | 157 | }, |
139 | }; | 158 | }; |
140 | EXPORT_SYMBOL(dvb_pll_thomson_dtt761x); | ||
141 | 159 | ||
142 | struct dvb_pll_desc dvb_pll_unknown_1 = { | 160 | static struct dvb_pll_desc dvb_pll_unknown_1 = { |
143 | .name = "unknown 1", /* used by dntv live dvb-t */ | 161 | .name = "unknown 1", /* used by dntv live dvb-t */ |
144 | .min = 174000000, | 162 | .min = 174000000, |
145 | .max = 862000000, | 163 | .max = 862000000, |
@@ -157,12 +175,11 @@ struct dvb_pll_desc dvb_pll_unknown_1 = { | |||
157 | { 999999999, 166667, 0xfc, 0x08 }, | 175 | { 999999999, 166667, 0xfc, 0x08 }, |
158 | }, | 176 | }, |
159 | }; | 177 | }; |
160 | EXPORT_SYMBOL(dvb_pll_unknown_1); | ||
161 | 178 | ||
162 | /* Infineon TUA6010XS | 179 | /* Infineon TUA6010XS |
163 | * used in Thomson Cable Tuner | 180 | * used in Thomson Cable Tuner |
164 | */ | 181 | */ |
165 | struct dvb_pll_desc dvb_pll_tua6010xs = { | 182 | static struct dvb_pll_desc dvb_pll_tua6010xs = { |
166 | .name = "Infineon TUA6010XS", | 183 | .name = "Infineon TUA6010XS", |
167 | .min = 44250000, | 184 | .min = 44250000, |
168 | .max = 858000000, | 185 | .max = 858000000, |
@@ -174,10 +191,9 @@ struct dvb_pll_desc dvb_pll_tua6010xs = { | |||
174 | { 999999999, 62500, 0x8e, 0x85 }, | 191 | { 999999999, 62500, 0x8e, 0x85 }, |
175 | }, | 192 | }, |
176 | }; | 193 | }; |
177 | EXPORT_SYMBOL(dvb_pll_tua6010xs); | ||
178 | 194 | ||
179 | /* Panasonic env57h1xd5 (some Philips PLL ?) */ | 195 | /* Panasonic env57h1xd5 (some Philips PLL ?) */ |
180 | struct dvb_pll_desc dvb_pll_env57h1xd5 = { | 196 | static struct dvb_pll_desc dvb_pll_env57h1xd5 = { |
181 | .name = "Panasonic ENV57H1XD5", | 197 | .name = "Panasonic ENV57H1XD5", |
182 | .min = 44250000, | 198 | .min = 44250000, |
183 | .max = 858000000, | 199 | .max = 858000000, |
@@ -190,23 +206,23 @@ struct dvb_pll_desc dvb_pll_env57h1xd5 = { | |||
190 | { 999999999, 166667, 0xc2, 0xa4 }, | 206 | { 999999999, 166667, 0xc2, 0xa4 }, |
191 | }, | 207 | }, |
192 | }; | 208 | }; |
193 | EXPORT_SYMBOL(dvb_pll_env57h1xd5); | ||
194 | 209 | ||
195 | /* Philips TDA6650/TDA6651 | 210 | /* Philips TDA6650/TDA6651 |
196 | * used in Panasonic ENV77H11D5 | 211 | * used in Panasonic ENV77H11D5 |
197 | */ | 212 | */ |
198 | static void tda665x_bw(u8 *buf, u32 freq, int bandwidth) | 213 | static void tda665x_bw(u8 *buf, const struct dvb_frontend_parameters *params) |
199 | { | 214 | { |
200 | if (bandwidth == BANDWIDTH_8_MHZ) | 215 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) |
201 | buf[3] |= 0x08; | 216 | buf[3] |= 0x08; |
202 | } | 217 | } |
203 | 218 | ||
204 | struct dvb_pll_desc dvb_pll_tda665x = { | 219 | static struct dvb_pll_desc dvb_pll_tda665x = { |
205 | .name = "Philips TDA6650/TDA6651", | 220 | .name = "Philips TDA6650/TDA6651", |
206 | .min = 44250000, | 221 | .min = 44250000, |
207 | .max = 858000000, | 222 | .max = 858000000, |
208 | .setbw = tda665x_bw, | 223 | .set = tda665x_bw, |
209 | .iffreq= 36166667, | 224 | .iffreq= 36166667, |
225 | .initdata = (u8[]){ 4, 0x0b, 0xf5, 0x85, 0xab }, | ||
210 | .count = 12, | 226 | .count = 12, |
211 | .entries = { | 227 | .entries = { |
212 | { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ }, | 228 | { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ }, |
@@ -223,36 +239,34 @@ struct dvb_pll_desc dvb_pll_tda665x = { | |||
223 | { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, | 239 | { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, |
224 | } | 240 | } |
225 | }; | 241 | }; |
226 | EXPORT_SYMBOL(dvb_pll_tda665x); | ||
227 | 242 | ||
228 | /* Infineon TUA6034 | 243 | /* Infineon TUA6034 |
229 | * used in LG TDTP E102P | 244 | * used in LG TDTP E102P |
230 | */ | 245 | */ |
231 | static void tua6034_bw(u8 *buf, u32 freq, int bandwidth) | 246 | static void tua6034_bw(u8 *buf, const struct dvb_frontend_parameters *params) |
232 | { | 247 | { |
233 | if (BANDWIDTH_7_MHZ != bandwidth) | 248 | if (BANDWIDTH_7_MHZ != params->u.ofdm.bandwidth) |
234 | buf[3] |= 0x08; | 249 | buf[3] |= 0x08; |
235 | } | 250 | } |
236 | 251 | ||
237 | struct dvb_pll_desc dvb_pll_tua6034 = { | 252 | static struct dvb_pll_desc dvb_pll_tua6034 = { |
238 | .name = "Infineon TUA6034", | 253 | .name = "Infineon TUA6034", |
239 | .min = 44250000, | 254 | .min = 44250000, |
240 | .max = 858000000, | 255 | .max = 858000000, |
241 | .iffreq= 36166667, | 256 | .iffreq= 36166667, |
242 | .count = 3, | 257 | .count = 3, |
243 | .setbw = tua6034_bw, | 258 | .set = tua6034_bw, |
244 | .entries = { | 259 | .entries = { |
245 | { 174500000, 62500, 0xce, 0x01 }, | 260 | { 174500000, 62500, 0xce, 0x01 }, |
246 | { 230000000, 62500, 0xce, 0x02 }, | 261 | { 230000000, 62500, 0xce, 0x02 }, |
247 | { 999999999, 62500, 0xce, 0x04 }, | 262 | { 999999999, 62500, 0xce, 0x04 }, |
248 | }, | 263 | }, |
249 | }; | 264 | }; |
250 | EXPORT_SYMBOL(dvb_pll_tua6034); | ||
251 | 265 | ||
252 | /* Infineon TUA6034 | 266 | /* Infineon TUA6034 |
253 | * used in LG TDVS-H061F, LG TDVS-H062F and LG TDVS-H064F | 267 | * used in LG TDVS-H061F, LG TDVS-H062F and LG TDVS-H064F |
254 | */ | 268 | */ |
255 | struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { | 269 | static struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { |
256 | .name = "LG TDVS-H06xF", | 270 | .name = "LG TDVS-H06xF", |
257 | .min = 54000000, | 271 | .min = 54000000, |
258 | .max = 863000000, | 272 | .max = 863000000, |
@@ -265,23 +279,25 @@ struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { | |||
265 | { 999999999, 62500, 0xce, 0x04 }, | 279 | { 999999999, 62500, 0xce, 0x04 }, |
266 | }, | 280 | }, |
267 | }; | 281 | }; |
268 | EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf); | ||
269 | 282 | ||
270 | /* Philips FMD1216ME | 283 | /* Philips FMD1216ME |
271 | * used in Medion Hybrid PCMCIA card and USB Box | 284 | * used in Medion Hybrid PCMCIA card and USB Box |
272 | */ | 285 | */ |
273 | static void fmd1216me_bw(u8 *buf, u32 freq, int bandwidth) | 286 | static void fmd1216me_bw(u8 *buf, const struct dvb_frontend_parameters *params) |
274 | { | 287 | { |
275 | if (bandwidth == BANDWIDTH_8_MHZ && freq >= 158870000) | 288 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ && |
289 | params->frequency >= 158870000) | ||
276 | buf[3] |= 0x08; | 290 | buf[3] |= 0x08; |
277 | } | 291 | } |
278 | 292 | ||
279 | struct dvb_pll_desc dvb_pll_fmd1216me = { | 293 | static struct dvb_pll_desc dvb_pll_fmd1216me = { |
280 | .name = "Philips FMD1216ME", | 294 | .name = "Philips FMD1216ME", |
281 | .min = 50870000, | 295 | .min = 50870000, |
282 | .max = 858000000, | 296 | .max = 858000000, |
283 | .iffreq= 36125000, | 297 | .iffreq= 36125000, |
284 | .setbw = fmd1216me_bw, | 298 | .set = fmd1216me_bw, |
299 | .initdata = tua603x_agc112, | ||
300 | .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, | ||
285 | .count = 7, | 301 | .count = 7, |
286 | .entries = { | 302 | .entries = { |
287 | { 143870000, 166667, 0xbc, 0x41 }, | 303 | { 143870000, 166667, 0xbc, 0x41 }, |
@@ -293,23 +309,22 @@ struct dvb_pll_desc dvb_pll_fmd1216me = { | |||
293 | { 999999999, 166667, 0xfc, 0x44 }, | 309 | { 999999999, 166667, 0xfc, 0x44 }, |
294 | } | 310 | } |
295 | }; | 311 | }; |
296 | EXPORT_SYMBOL(dvb_pll_fmd1216me); | ||
297 | 312 | ||
298 | /* ALPS TDED4 | 313 | /* ALPS TDED4 |
299 | * used in Nebula-Cards and USB boxes | 314 | * used in Nebula-Cards and USB boxes |
300 | */ | 315 | */ |
301 | static void tded4_bw(u8 *buf, u32 freq, int bandwidth) | 316 | static void tded4_bw(u8 *buf, const struct dvb_frontend_parameters *params) |
302 | { | 317 | { |
303 | if (bandwidth == BANDWIDTH_8_MHZ) | 318 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) |
304 | buf[3] |= 0x04; | 319 | buf[3] |= 0x04; |
305 | } | 320 | } |
306 | 321 | ||
307 | struct dvb_pll_desc dvb_pll_tded4 = { | 322 | static struct dvb_pll_desc dvb_pll_tded4 = { |
308 | .name = "ALPS TDED4", | 323 | .name = "ALPS TDED4", |
309 | .min = 47000000, | 324 | .min = 47000000, |
310 | .max = 863000000, | 325 | .max = 863000000, |
311 | .iffreq= 36166667, | 326 | .iffreq= 36166667, |
312 | .setbw = tded4_bw, | 327 | .set = tded4_bw, |
313 | .count = 4, | 328 | .count = 4, |
314 | .entries = { | 329 | .entries = { |
315 | { 153000000, 166667, 0x85, 0x01 }, | 330 | { 153000000, 166667, 0x85, 0x01 }, |
@@ -318,12 +333,11 @@ struct dvb_pll_desc dvb_pll_tded4 = { | |||
318 | { 999999999, 166667, 0x85, 0x88 }, | 333 | { 999999999, 166667, 0x85, 0x88 }, |
319 | } | 334 | } |
320 | }; | 335 | }; |
321 | EXPORT_SYMBOL(dvb_pll_tded4); | ||
322 | 336 | ||
323 | /* ALPS TDHU2 | 337 | /* ALPS TDHU2 |
324 | * used in AverTVHD MCE A180 | 338 | * used in AverTVHD MCE A180 |
325 | */ | 339 | */ |
326 | struct dvb_pll_desc dvb_pll_tdhu2 = { | 340 | static struct dvb_pll_desc dvb_pll_tdhu2 = { |
327 | .name = "ALPS TDHU2", | 341 | .name = "ALPS TDHU2", |
328 | .min = 54000000, | 342 | .min = 54000000, |
329 | .max = 864000000, | 343 | .max = 864000000, |
@@ -336,16 +350,29 @@ struct dvb_pll_desc dvb_pll_tdhu2 = { | |||
336 | { 999999999, 62500, 0x85, 0x88 }, | 350 | { 999999999, 62500, 0x85, 0x88 }, |
337 | } | 351 | } |
338 | }; | 352 | }; |
339 | EXPORT_SYMBOL(dvb_pll_tdhu2); | ||
340 | 353 | ||
341 | /* Philips TUV1236D | 354 | /* Philips TUV1236D |
342 | * used in ATI HDTV Wonder | 355 | * used in ATI HDTV Wonder |
343 | */ | 356 | */ |
344 | struct dvb_pll_desc dvb_pll_tuv1236d = { | 357 | static void tuv1236d_rf(u8 *buf, const struct dvb_frontend_parameters *params) |
358 | { | ||
359 | switch (params->u.vsb.modulation) { | ||
360 | case QAM_64: | ||
361 | case QAM_256: | ||
362 | buf[3] |= 0x08; | ||
363 | break; | ||
364 | case VSB_8: | ||
365 | default: | ||
366 | buf[3] &= ~0x08; | ||
367 | } | ||
368 | } | ||
369 | |||
370 | static struct dvb_pll_desc dvb_pll_tuv1236d = { | ||
345 | .name = "Philips TUV1236D", | 371 | .name = "Philips TUV1236D", |
346 | .min = 54000000, | 372 | .min = 54000000, |
347 | .max = 864000000, | 373 | .max = 864000000, |
348 | .iffreq= 44000000, | 374 | .iffreq= 44000000, |
375 | .set = tuv1236d_rf, | ||
349 | .count = 3, | 376 | .count = 3, |
350 | .entries = { | 377 | .entries = { |
351 | { 157250000, 62500, 0xc6, 0x41 }, | 378 | { 157250000, 62500, 0xc6, 0x41 }, |
@@ -353,12 +380,11 @@ struct dvb_pll_desc dvb_pll_tuv1236d = { | |||
353 | { 999999999, 62500, 0xc6, 0x44 }, | 380 | { 999999999, 62500, 0xc6, 0x44 }, |
354 | }, | 381 | }, |
355 | }; | 382 | }; |
356 | EXPORT_SYMBOL(dvb_pll_tuv1236d); | ||
357 | 383 | ||
358 | /* Samsung TBMV30111IN / TBMV30712IN1 | 384 | /* Samsung TBMV30111IN / TBMV30712IN1 |
359 | * used in Air2PC ATSC - 2nd generation (nxt2002) | 385 | * used in Air2PC ATSC - 2nd generation (nxt2002) |
360 | */ | 386 | */ |
361 | struct dvb_pll_desc dvb_pll_samsung_tbmv = { | 387 | static struct dvb_pll_desc dvb_pll_samsung_tbmv = { |
362 | .name = "Samsung TBMV30111IN / TBMV30712IN1", | 388 | .name = "Samsung TBMV30111IN / TBMV30712IN1", |
363 | .min = 54000000, | 389 | .min = 54000000, |
364 | .max = 860000000, | 390 | .max = 860000000, |
@@ -373,12 +399,11 @@ struct dvb_pll_desc dvb_pll_samsung_tbmv = { | |||
373 | { 999999999, 166667, 0xfc, 0x02 }, | 399 | { 999999999, 166667, 0xfc, 0x02 }, |
374 | } | 400 | } |
375 | }; | 401 | }; |
376 | EXPORT_SYMBOL(dvb_pll_samsung_tbmv); | ||
377 | 402 | ||
378 | /* | 403 | /* |
379 | * Philips SD1878 Tuner. | 404 | * Philips SD1878 Tuner. |
380 | */ | 405 | */ |
381 | struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { | 406 | static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { |
382 | .name = "Philips SD1878", | 407 | .name = "Philips SD1878", |
383 | .min = 950000, | 408 | .min = 950000, |
384 | .max = 2150000, | 409 | .max = 2150000, |
@@ -391,19 +416,18 @@ struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { | |||
391 | { 2150000, 500, 0xc4, 0xc0}, | 416 | { 2150000, 500, 0xc4, 0xc0}, |
392 | }, | 417 | }, |
393 | }; | 418 | }; |
394 | EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); | ||
395 | 419 | ||
396 | /* | 420 | /* |
397 | * Philips TD1316 Tuner. | 421 | * Philips TD1316 Tuner. |
398 | */ | 422 | */ |
399 | static void td1316_bw(u8 *buf, u32 freq, int bandwidth) | 423 | static void td1316_bw(u8 *buf, const struct dvb_frontend_parameters *params) |
400 | { | 424 | { |
401 | u8 band; | 425 | u8 band; |
402 | 426 | ||
403 | /* determine band */ | 427 | /* determine band */ |
404 | if (freq < 161000000) | 428 | if (params->frequency < 161000000) |
405 | band = 1; | 429 | band = 1; |
406 | else if (freq < 444000000) | 430 | else if (params->frequency < 444000000) |
407 | band = 2; | 431 | band = 2; |
408 | else | 432 | else |
409 | band = 4; | 433 | band = 4; |
@@ -411,16 +435,16 @@ static void td1316_bw(u8 *buf, u32 freq, int bandwidth) | |||
411 | buf[3] |= band; | 435 | buf[3] |= band; |
412 | 436 | ||
413 | /* setup PLL filter */ | 437 | /* setup PLL filter */ |
414 | if (bandwidth == BANDWIDTH_8_MHZ) | 438 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) |
415 | buf[3] |= 1 << 3; | 439 | buf[3] |= 1 << 3; |
416 | } | 440 | } |
417 | 441 | ||
418 | struct dvb_pll_desc dvb_pll_philips_td1316 = { | 442 | static struct dvb_pll_desc dvb_pll_philips_td1316 = { |
419 | .name = "Philips TD1316", | 443 | .name = "Philips TD1316", |
420 | .min = 87000000, | 444 | .min = 87000000, |
421 | .max = 895000000, | 445 | .max = 895000000, |
422 | .iffreq= 36166667, | 446 | .iffreq= 36166667, |
423 | .setbw = td1316_bw, | 447 | .set = td1316_bw, |
424 | .count = 9, | 448 | .count = 9, |
425 | .entries = { | 449 | .entries = { |
426 | { 93834000, 166667, 0xca, 0x60}, | 450 | { 93834000, 166667, 0xca, 0x60}, |
@@ -434,10 +458,9 @@ struct dvb_pll_desc dvb_pll_philips_td1316 = { | |||
434 | { 858834000, 166667, 0xca, 0xe0}, | 458 | { 858834000, 166667, 0xca, 0xe0}, |
435 | }, | 459 | }, |
436 | }; | 460 | }; |
437 | EXPORT_SYMBOL(dvb_pll_philips_td1316); | ||
438 | 461 | ||
439 | /* FE6600 used on DViCO Hybrid */ | 462 | /* FE6600 used on DViCO Hybrid */ |
440 | struct dvb_pll_desc dvb_pll_thomson_fe6600 = { | 463 | static struct dvb_pll_desc dvb_pll_thomson_fe6600 = { |
441 | .name = "Thomson FE6600", | 464 | .name = "Thomson FE6600", |
442 | .min = 44250000, | 465 | .min = 44250000, |
443 | .max = 858000000, | 466 | .max = 858000000, |
@@ -450,19 +473,19 @@ struct dvb_pll_desc dvb_pll_thomson_fe6600 = { | |||
450 | { 999999999, 166667, 0xf4, 0x18 }, | 473 | { 999999999, 166667, 0xf4, 0x18 }, |
451 | } | 474 | } |
452 | }; | 475 | }; |
453 | EXPORT_SYMBOL(dvb_pll_thomson_fe6600); | 476 | |
454 | static void opera1_bw(u8 *buf, u32 freq, int bandwidth) | 477 | static void opera1_bw(u8 *buf, const struct dvb_frontend_parameters *params) |
455 | { | 478 | { |
456 | if (bandwidth == BANDWIDTH_8_MHZ) | 479 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) |
457 | buf[2] |= 0x08; | 480 | buf[2] |= 0x08; |
458 | } | 481 | } |
459 | 482 | ||
460 | struct dvb_pll_desc dvb_pll_opera1 = { | 483 | static struct dvb_pll_desc dvb_pll_opera1 = { |
461 | .name = "Opera Tuner", | 484 | .name = "Opera Tuner", |
462 | .min = 900000, | 485 | .min = 900000, |
463 | .max = 2250000, | 486 | .max = 2250000, |
464 | .iffreq= 0, | 487 | .iffreq= 0, |
465 | .setbw = opera1_bw, | 488 | .set = opera1_bw, |
466 | .count = 8, | 489 | .count = 8, |
467 | .entries = { | 490 | .entries = { |
468 | { 1064000, 500, 0xe5, 0xc6 }, | 491 | { 1064000, 500, 0xe5, 0xc6 }, |
@@ -475,7 +498,54 @@ struct dvb_pll_desc dvb_pll_opera1 = { | |||
475 | { 2250000, 500, 0xe5, 0xc4 }, | 498 | { 2250000, 500, 0xe5, 0xc4 }, |
476 | } | 499 | } |
477 | }; | 500 | }; |
478 | EXPORT_SYMBOL(dvb_pll_opera1); | 501 | |
502 | /* Philips FCV1236D | ||
503 | */ | ||
504 | struct dvb_pll_desc dvb_pll_fcv1236d = { | ||
505 | /* Bit_0: RF Input select | ||
506 | * Bit_1: 0=digital, 1=analog | ||
507 | */ | ||
508 | .name = "Philips FCV1236D", | ||
509 | .min = 53000000, | ||
510 | .max = 803000000, | ||
511 | .iffreq= 44000000, | ||
512 | .count = 3, | ||
513 | .entries = { | ||
514 | { 159000000, 62500, 0x8e, 0xa0 }, | ||
515 | { 453000000, 62500, 0x8e, 0x90 }, | ||
516 | { 999999999, 62500, 0x8e, 0x30 }, | ||
517 | }, | ||
518 | }; | ||
519 | |||
520 | /* ----------------------------------------------------------- */ | ||
521 | |||
522 | static struct dvb_pll_desc *pll_list[] = { | ||
523 | [DVB_PLL_UNDEFINED] = NULL, | ||
524 | [DVB_PLL_THOMSON_DTT7579] = &dvb_pll_thomson_dtt7579, | ||
525 | [DVB_PLL_THOMSON_DTT759X] = &dvb_pll_thomson_dtt759x, | ||
526 | [DVB_PLL_THOMSON_DTT7610] = &dvb_pll_thomson_dtt7610, | ||
527 | [DVB_PLL_LG_Z201] = &dvb_pll_lg_z201, | ||
528 | [DVB_PLL_MICROTUNE_4042] = &dvb_pll_microtune_4042, | ||
529 | [DVB_PLL_THOMSON_DTT761X] = &dvb_pll_thomson_dtt761x, | ||
530 | [DVB_PLL_UNKNOWN_1] = &dvb_pll_unknown_1, | ||
531 | [DVB_PLL_TUA6010XS] = &dvb_pll_tua6010xs, | ||
532 | [DVB_PLL_ENV57H1XD5] = &dvb_pll_env57h1xd5, | ||
533 | [DVB_PLL_TUA6034] = &dvb_pll_tua6034, | ||
534 | [DVB_PLL_LG_TDVS_H06XF] = &dvb_pll_lg_tdvs_h06xf, | ||
535 | [DVB_PLL_TDA665X] = &dvb_pll_tda665x, | ||
536 | [DVB_PLL_FMD1216ME] = &dvb_pll_fmd1216me, | ||
537 | [DVB_PLL_TDED4] = &dvb_pll_tded4, | ||
538 | [DVB_PLL_TUV1236D] = &dvb_pll_tuv1236d, | ||
539 | [DVB_PLL_TDHU2] = &dvb_pll_tdhu2, | ||
540 | [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv, | ||
541 | [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261, | ||
542 | [DVB_PLL_PHILIPS_TD1316] = &dvb_pll_philips_td1316, | ||
543 | [DVB_PLL_THOMSON_FE6600] = &dvb_pll_thomson_fe6600, | ||
544 | [DVB_PLL_OPERA1] = &dvb_pll_opera1, | ||
545 | [DVB_PLL_FCV1236D] = &dvb_pll_fcv1236d, | ||
546 | }; | ||
547 | |||
548 | /* ----------------------------------------------------------- */ | ||
479 | 549 | ||
480 | struct dvb_pll_priv { | 550 | struct dvb_pll_priv { |
481 | /* i2c details */ | 551 | /* i2c details */ |
@@ -497,35 +567,37 @@ static int debug = 0; | |||
497 | module_param(debug, int, 0644); | 567 | module_param(debug, int, 0644); |
498 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | 568 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); |
499 | 569 | ||
500 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | 570 | static int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, |
501 | u32 freq, int bandwidth) | 571 | const struct dvb_frontend_parameters *params) |
502 | { | 572 | { |
503 | u32 div; | 573 | u32 div; |
504 | int i; | 574 | int i; |
505 | 575 | ||
506 | if (freq != 0 && (freq < desc->min || freq > desc->max)) | 576 | if (params->frequency != 0 && (params->frequency < desc->min || |
507 | return -EINVAL; | 577 | params->frequency > desc->max)) |
578 | return -EINVAL; | ||
508 | 579 | ||
509 | for (i = 0; i < desc->count; i++) { | 580 | for (i = 0; i < desc->count; i++) { |
510 | if (freq > desc->entries[i].limit) | 581 | if (params->frequency > desc->entries[i].limit) |
511 | continue; | 582 | continue; |
512 | break; | 583 | break; |
513 | } | 584 | } |
585 | |||
514 | if (debug) | 586 | if (debug) |
515 | printk("pll: %s: freq=%d bw=%d | i=%d/%d\n", | 587 | printk("pll: %s: freq=%d | i=%d/%d\n", desc->name, |
516 | desc->name, freq, bandwidth, i, desc->count); | 588 | params->frequency, i, desc->count); |
517 | if (i == desc->count) | 589 | if (i == desc->count) |
518 | return -EINVAL; | 590 | return -EINVAL; |
519 | 591 | ||
520 | div = (freq + desc->iffreq + desc->entries[i].stepsize/2) / | 592 | div = (params->frequency + desc->iffreq + |
521 | desc->entries[i].stepsize; | 593 | desc->entries[i].stepsize/2) / desc->entries[i].stepsize; |
522 | buf[0] = div >> 8; | 594 | buf[0] = div >> 8; |
523 | buf[1] = div & 0xff; | 595 | buf[1] = div & 0xff; |
524 | buf[2] = desc->entries[i].config; | 596 | buf[2] = desc->entries[i].config; |
525 | buf[3] = desc->entries[i].cb; | 597 | buf[3] = desc->entries[i].cb; |
526 | 598 | ||
527 | if (desc->setbw) | 599 | if (desc->set) |
528 | desc->setbw(buf, freq, bandwidth); | 600 | desc->set(buf, params); |
529 | 601 | ||
530 | if (debug) | 602 | if (debug) |
531 | printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", | 603 | printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", |
@@ -534,7 +606,6 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
534 | // calculate the frequency we set it to | 606 | // calculate the frequency we set it to |
535 | return (div * desc->entries[i].stepsize) - desc->iffreq; | 607 | return (div * desc->entries[i].stepsize) - desc->iffreq; |
536 | } | 608 | } |
537 | EXPORT_SYMBOL(dvb_pll_configure); | ||
538 | 609 | ||
539 | static int dvb_pll_release(struct dvb_frontend *fe) | 610 | static int dvb_pll_release(struct dvb_frontend *fe) |
540 | { | 611 | { |
@@ -578,18 +649,12 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, | |||
578 | { .addr = priv->pll_i2c_address, .flags = 0, | 649 | { .addr = priv->pll_i2c_address, .flags = 0, |
579 | .buf = buf, .len = sizeof(buf) }; | 650 | .buf = buf, .len = sizeof(buf) }; |
580 | int result; | 651 | int result; |
581 | u32 bandwidth = 0, frequency = 0; | 652 | u32 frequency = 0; |
582 | 653 | ||
583 | if (priv->i2c == NULL) | 654 | if (priv->i2c == NULL) |
584 | return -EINVAL; | 655 | return -EINVAL; |
585 | 656 | ||
586 | // DVBT bandwidth only just now | 657 | if ((result = dvb_pll_configure(priv->pll_desc, buf, params)) < 0) |
587 | if (fe->ops.info.type == FE_OFDM) { | ||
588 | bandwidth = params->u.ofdm.bandwidth; | ||
589 | } | ||
590 | |||
591 | if ((result = dvb_pll_configure(priv->pll_desc, buf, | ||
592 | params->frequency, bandwidth)) < 0) | ||
593 | return result; | 658 | return result; |
594 | else | 659 | else |
595 | frequency = result; | 660 | frequency = result; |
@@ -601,7 +666,7 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, | |||
601 | } | 666 | } |
602 | 667 | ||
603 | priv->frequency = frequency; | 668 | priv->frequency = frequency; |
604 | priv->bandwidth = bandwidth; | 669 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; |
605 | 670 | ||
606 | return 0; | 671 | return 0; |
607 | } | 672 | } |
@@ -612,18 +677,12 @@ static int dvb_pll_calc_regs(struct dvb_frontend *fe, | |||
612 | { | 677 | { |
613 | struct dvb_pll_priv *priv = fe->tuner_priv; | 678 | struct dvb_pll_priv *priv = fe->tuner_priv; |
614 | int result; | 679 | int result; |
615 | u32 bandwidth = 0, frequency = 0; | 680 | u32 frequency = 0; |
616 | 681 | ||
617 | if (buf_len < 5) | 682 | if (buf_len < 5) |
618 | return -EINVAL; | 683 | return -EINVAL; |
619 | 684 | ||
620 | // DVBT bandwidth only just now | 685 | if ((result = dvb_pll_configure(priv->pll_desc, buf+1, params)) < 0) |
621 | if (fe->ops.info.type == FE_OFDM) { | ||
622 | bandwidth = params->u.ofdm.bandwidth; | ||
623 | } | ||
624 | |||
625 | if ((result = dvb_pll_configure(priv->pll_desc, buf+1, | ||
626 | params->frequency, bandwidth)) < 0) | ||
627 | return result; | 686 | return result; |
628 | else | 687 | else |
629 | frequency = result; | 688 | frequency = result; |
@@ -631,7 +690,7 @@ static int dvb_pll_calc_regs(struct dvb_frontend *fe, | |||
631 | buf[0] = priv->pll_i2c_address; | 690 | buf[0] = priv->pll_i2c_address; |
632 | 691 | ||
633 | priv->frequency = frequency; | 692 | priv->frequency = frequency; |
634 | priv->bandwidth = bandwidth; | 693 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; |
635 | 694 | ||
636 | return 5; | 695 | return 5; |
637 | } | 696 | } |
@@ -687,13 +746,18 @@ static struct dvb_tuner_ops dvb_pll_tuner_ops = { | |||
687 | 746 | ||
688 | struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, | 747 | struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, |
689 | struct i2c_adapter *i2c, | 748 | struct i2c_adapter *i2c, |
690 | struct dvb_pll_desc *desc) | 749 | unsigned int pll_desc_id) |
691 | { | 750 | { |
692 | u8 b1 [] = { 0 }; | 751 | u8 b1 [] = { 0 }; |
693 | struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, | 752 | struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, |
694 | .buf = b1, .len = 1 }; | 753 | .buf = b1, .len = 1 }; |
695 | struct dvb_pll_priv *priv = NULL; | 754 | struct dvb_pll_priv *priv = NULL; |
696 | int ret; | 755 | int ret; |
756 | struct dvb_pll_desc *desc; | ||
757 | |||
758 | BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list)); | ||
759 | |||
760 | desc = pll_list[pll_desc_id]; | ||
697 | 761 | ||
698 | if (i2c != NULL) { | 762 | if (i2c != NULL) { |
699 | if (fe->ops.i2c_gate_ctrl) | 763 | if (fe->ops.i2c_gate_ctrl) |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 5209f46f0893..e93a8104052b 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
@@ -8,50 +8,29 @@ | |||
8 | #include <linux/i2c.h> | 8 | #include <linux/i2c.h> |
9 | #include "dvb_frontend.h" | 9 | #include "dvb_frontend.h" |
10 | 10 | ||
11 | struct dvb_pll_desc { | 11 | #define DVB_PLL_UNDEFINED 0 |
12 | char *name; | 12 | #define DVB_PLL_THOMSON_DTT7579 1 |
13 | u32 min; | 13 | #define DVB_PLL_THOMSON_DTT759X 2 |
14 | u32 max; | 14 | #define DVB_PLL_THOMSON_DTT7610 3 |
15 | u32 iffreq; | 15 | #define DVB_PLL_LG_Z201 4 |
16 | void (*setbw)(u8 *buf, u32 freq, int bandwidth); | 16 | #define DVB_PLL_MICROTUNE_4042 5 |
17 | u8 *initdata; | 17 | #define DVB_PLL_THOMSON_DTT761X 6 |
18 | u8 *sleepdata; | 18 | #define DVB_PLL_UNKNOWN_1 7 |
19 | int count; | 19 | #define DVB_PLL_TUA6010XS 8 |
20 | struct { | 20 | #define DVB_PLL_ENV57H1XD5 9 |
21 | u32 limit; | 21 | #define DVB_PLL_TUA6034 10 |
22 | u32 stepsize; | 22 | #define DVB_PLL_LG_TDVS_H06XF 11 |
23 | u8 config; | 23 | #define DVB_PLL_TDA665X 12 |
24 | u8 cb; | 24 | #define DVB_PLL_FMD1216ME 13 |
25 | } entries[12]; | 25 | #define DVB_PLL_TDED4 14 |
26 | }; | 26 | #define DVB_PLL_TUV1236D 15 |
27 | 27 | #define DVB_PLL_TDHU2 16 | |
28 | extern struct dvb_pll_desc dvb_pll_thomson_dtt7579; | 28 | #define DVB_PLL_SAMSUNG_TBMV 17 |
29 | extern struct dvb_pll_desc dvb_pll_thomson_dtt759x; | 29 | #define DVB_PLL_PHILIPS_SD1878_TDA8261 18 |
30 | extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; | 30 | #define DVB_PLL_PHILIPS_TD1316 19 |
31 | extern struct dvb_pll_desc dvb_pll_lg_z201; | 31 | #define DVB_PLL_THOMSON_FE6600 20 |
32 | extern struct dvb_pll_desc dvb_pll_microtune_4042; | 32 | #define DVB_PLL_OPERA1 21 |
33 | extern struct dvb_pll_desc dvb_pll_thomson_dtt761x; | 33 | #define DVB_PLL_FCV1236D 22 |
34 | extern struct dvb_pll_desc dvb_pll_unknown_1; | ||
35 | |||
36 | extern struct dvb_pll_desc dvb_pll_tua6010xs; | ||
37 | extern struct dvb_pll_desc dvb_pll_env57h1xd5; | ||
38 | extern struct dvb_pll_desc dvb_pll_tua6034; | ||
39 | extern struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf; | ||
40 | extern struct dvb_pll_desc dvb_pll_tda665x; | ||
41 | extern struct dvb_pll_desc dvb_pll_fmd1216me; | ||
42 | extern struct dvb_pll_desc dvb_pll_tded4; | ||
43 | |||
44 | extern struct dvb_pll_desc dvb_pll_tuv1236d; | ||
45 | extern struct dvb_pll_desc dvb_pll_tdhu2; | ||
46 | extern struct dvb_pll_desc dvb_pll_samsung_tbmv; | ||
47 | extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; | ||
48 | extern struct dvb_pll_desc dvb_pll_philips_td1316; | ||
49 | |||
50 | extern struct dvb_pll_desc dvb_pll_thomson_fe6600; | ||
51 | extern struct dvb_pll_desc dvb_pll_opera1; | ||
52 | |||
53 | extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | ||
54 | u32 freq, int bandwidth); | ||
55 | 34 | ||
56 | /** | 35 | /** |
57 | * Attach a dvb-pll to the supplied frontend structure. | 36 | * Attach a dvb-pll to the supplied frontend structure. |
@@ -59,19 +38,19 @@ extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
59 | * @param fe Frontend to attach to. | 38 | * @param fe Frontend to attach to. |
60 | * @param pll_addr i2c address of the PLL (if used). | 39 | * @param pll_addr i2c address of the PLL (if used). |
61 | * @param i2c i2c adapter to use (set to NULL if not used). | 40 | * @param i2c i2c adapter to use (set to NULL if not used). |
62 | * @param desc dvb_pll_desc to use. | 41 | * @param pll_desc_id dvb_pll_desc to use. |
63 | * @return Frontend pointer on success, NULL on failure | 42 | * @return Frontend pointer on success, NULL on failure |
64 | */ | 43 | */ |
65 | #if defined(CONFIG_DVB_PLL) || (defined(CONFIG_DVB_PLL_MODULE) && defined(MODULE)) | 44 | #if defined(CONFIG_DVB_PLL) || (defined(CONFIG_DVB_PLL_MODULE) && defined(MODULE)) |
66 | extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, | 45 | extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, |
67 | int pll_addr, | 46 | int pll_addr, |
68 | struct i2c_adapter *i2c, | 47 | struct i2c_adapter *i2c, |
69 | struct dvb_pll_desc *desc); | 48 | unsigned int pll_desc_id); |
70 | #else | 49 | #else |
71 | static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, | 50 | static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, |
72 | int pll_addr, | 51 | int pll_addr, |
73 | struct i2c_adapter *i2c, | 52 | struct i2c_adapter *i2c, |
74 | struct dvb_pll_desc *desc) | 53 | unsigned int pll_desc_id) |
75 | { | 54 | { |
76 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | 55 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); |
77 | return NULL; | 56 | return NULL; |
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c index b809f83d9563..ddc84899cf86 100644 --- a/drivers/media/dvb/frontends/nxt200x.c +++ b/drivers/media/dvb/frontends/nxt200x.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <linux/string.h> | 49 | #include <linux/string.h> |
50 | 50 | ||
51 | #include "dvb_frontend.h" | 51 | #include "dvb_frontend.h" |
52 | #include "dvb-pll.h" | ||
53 | #include "nxt200x.h" | 52 | #include "nxt200x.h" |
54 | 53 | ||
55 | struct nxt200x_state { | 54 | struct nxt200x_state { |
@@ -546,11 +545,6 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
546 | nxt200x_writebytes(state, 0x17, buf, 1); | 545 | nxt200x_writebytes(state, 0x17, buf, 1); |
547 | } | 546 | } |
548 | 547 | ||
549 | /* get tuning information */ | ||
550 | if (fe->ops.tuner_ops.calc_regs) { | ||
551 | fe->ops.tuner_ops.calc_regs(fe, p, buf, 5); | ||
552 | } | ||
553 | |||
554 | /* set additional params */ | 548 | /* set additional params */ |
555 | switch (p->u.vsb.modulation) { | 549 | switch (p->u.vsb.modulation) { |
556 | case QAM_64: | 550 | case QAM_64: |
@@ -559,27 +553,24 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
559 | /* This is just a guess since I am unable to test it */ | 553 | /* This is just a guess since I am unable to test it */ |
560 | if (state->config->set_ts_params) | 554 | if (state->config->set_ts_params) |
561 | state->config->set_ts_params(fe, 1); | 555 | state->config->set_ts_params(fe, 1); |
562 | |||
563 | /* set input */ | ||
564 | if (state->config->set_pll_input) | ||
565 | state->config->set_pll_input(buf+1, 1); | ||
566 | break; | 556 | break; |
567 | case VSB_8: | 557 | case VSB_8: |
568 | /* Set non-punctured clock for VSB */ | 558 | /* Set non-punctured clock for VSB */ |
569 | if (state->config->set_ts_params) | 559 | if (state->config->set_ts_params) |
570 | state->config->set_ts_params(fe, 0); | 560 | state->config->set_ts_params(fe, 0); |
571 | |||
572 | /* set input */ | ||
573 | if (state->config->set_pll_input) | ||
574 | state->config->set_pll_input(buf+1, 0); | ||
575 | break; | 561 | break; |
576 | default: | 562 | default: |
577 | return -EINVAL; | 563 | return -EINVAL; |
578 | break; | 564 | break; |
579 | } | 565 | } |
580 | 566 | ||
581 | /* write frequency information */ | 567 | if (fe->ops.tuner_ops.calc_regs) { |
582 | nxt200x_writetuner(state, buf); | 568 | /* get tuning information */ |
569 | fe->ops.tuner_ops.calc_regs(fe, p, buf, 5); | ||
570 | |||
571 | /* write frequency information */ | ||
572 | nxt200x_writetuner(state, buf); | ||
573 | } | ||
583 | 574 | ||
584 | /* reset the agc now that tuning has been completed */ | 575 | /* reset the agc now that tuning has been completed */ |
585 | nxt200x_agc_reset(state); | 576 | nxt200x_agc_reset(state); |
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h index 28bc5591b319..bb0ef58d7972 100644 --- a/drivers/media/dvb/frontends/nxt200x.h +++ b/drivers/media/dvb/frontends/nxt200x.h | |||
@@ -38,9 +38,6 @@ struct nxt200x_config | |||
38 | /* the demodulator's i2c address */ | 38 | /* the demodulator's i2c address */ |
39 | u8 demod_address; | 39 | u8 demod_address; |
40 | 40 | ||
41 | /* used to set pll input */ | ||
42 | int (*set_pll_input)(u8* buf, int input); | ||
43 | |||
44 | /* need to set device param for start_dma */ | 41 | /* need to set device param for start_dma */ |
45 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 42 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
46 | }; | 43 | }; |
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index 4e0aca7c67aa..3cc8b444b8f2 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c | |||
@@ -45,7 +45,6 @@ | |||
45 | 45 | ||
46 | #include "dvb_math.h" | 46 | #include "dvb_math.h" |
47 | #include "dvb_frontend.h" | 47 | #include "dvb_frontend.h" |
48 | #include "dvb-pll.h" | ||
49 | #include "or51132.h" | 48 | #include "or51132.h" |
50 | 49 | ||
51 | static int debug; | 50 | static int debug; |
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c index 048d7cfe12d3..f46d5a46683a 100644 --- a/drivers/media/dvb/frontends/or51211.c +++ b/drivers/media/dvb/frontends/or51211.c | |||
@@ -223,38 +223,13 @@ static int or51211_set_parameters(struct dvb_frontend* fe, | |||
223 | struct dvb_frontend_parameters *param) | 223 | struct dvb_frontend_parameters *param) |
224 | { | 224 | { |
225 | struct or51211_state* state = fe->demodulator_priv; | 225 | struct or51211_state* state = fe->demodulator_priv; |
226 | u32 freq = 0; | ||
227 | u16 tunerfreq = 0; | ||
228 | u8 buf[4]; | ||
229 | 226 | ||
230 | /* Change only if we are actually changing the channel */ | 227 | /* Change only if we are actually changing the channel */ |
231 | if (state->current_frequency != param->frequency) { | 228 | if (state->current_frequency != param->frequency) { |
232 | freq = 44000 + (param->frequency/1000); | 229 | if (fe->ops.tuner_ops.set_params) { |
233 | tunerfreq = freq * 16/1000; | 230 | fe->ops.tuner_ops.set_params(fe, param); |
234 | 231 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | |
235 | dprintk("set_parameters frequency = %d (tunerfreq = %d)\n", | ||
236 | param->frequency,tunerfreq); | ||
237 | |||
238 | buf[0] = (tunerfreq >> 8) & 0x7F; | ||
239 | buf[1] = (tunerfreq & 0xFF); | ||
240 | buf[2] = 0x8E; | ||
241 | |||
242 | if (param->frequency < 157250000) { | ||
243 | buf[3] = 0xA0; | ||
244 | dprintk("set_parameters VHF low range\n"); | ||
245 | } else if (param->frequency < 454000000) { | ||
246 | buf[3] = 0x90; | ||
247 | dprintk("set_parameters VHF high range\n"); | ||
248 | } else { | ||
249 | buf[3] = 0x30; | ||
250 | dprintk("set_parameters UHF range\n"); | ||
251 | } | 232 | } |
252 | dprintk("set_parameters tuner bytes: 0x%02x 0x%02x " | ||
253 | "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]); | ||
254 | |||
255 | if (i2c_writebytes(state,0xC2>>1,buf,4)) | ||
256 | printk(KERN_WARNING "or51211:set_parameters error " | ||
257 | "writing to tuner\n"); | ||
258 | 233 | ||
259 | /* Set to ATSC mode */ | 234 | /* Set to ATSC mode */ |
260 | or51211_setmode(fe,0); | 235 | or51211_setmode(fe,0); |
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 18768d2f6d40..6c607302c1b6 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c | |||
@@ -249,7 +249,7 @@ static int stv0299_get_symbolrate (struct stv0299_state* state) | |||
249 | dprintk ("%s\n", __FUNCTION__); | 249 | dprintk ("%s\n", __FUNCTION__); |
250 | 250 | ||
251 | stv0299_readregs (state, 0x1f, sfr, 3); | 251 | stv0299_readregs (state, 0x1f, sfr, 3); |
252 | stv0299_readregs (state, 0x1a, &rtf, 1); | 252 | stv0299_readregs (state, 0x1a, (u8 *)&rtf, 1); |
253 | 253 | ||
254 | srate = (sfr[0] << 8) | sfr[1]; | 254 | srate = (sfr[0] << 8) | sfr[1]; |
255 | srate *= Mclk; | 255 | srate *= Mclk; |
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c index da796e784be3..4bb06f97938b 100644 --- a/drivers/media/dvb/frontends/tda10023.c +++ b/drivers/media/dvb/frontends/tda10023.c | |||
@@ -478,7 +478,7 @@ struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, | |||
478 | state->i2c = i2c; | 478 | state->i2c = i2c; |
479 | memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); | 479 | memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); |
480 | state->pwm = pwm; | 480 | state->pwm = pwm; |
481 | for (i=0; i < sizeof(tda10023_inittab)/sizeof(*tda10023_inittab);i+=3) { | 481 | for (i=0; i < ARRAY_SIZE(tda10023_inittab);i+=3) { |
482 | if (tda10023_inittab[i] == 0x00) { | 482 | if (tda10023_inittab[i] == 0x00) { |
483 | state->reg0 = tda10023_inittab[i+2]; | 483 | state->reg0 = tda10023_inittab[i+2]; |
484 | break; | 484 | break; |
diff --git a/drivers/media/dvb/pluto2/Makefile b/drivers/media/dvb/pluto2/Makefile index ce6a9aaf937e..7ac128724df8 100644 --- a/drivers/media/dvb/pluto2/Makefile +++ b/drivers/media/dvb/pluto2/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | obj-$(CONFIG_DVB_PLUTO2) += pluto2.o | 1 | obj-$(CONFIG_DVB_PLUTO2) += pluto2.o |
2 | 2 | ||
3 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | 3 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ |
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index 7751628e1415..6d53289b3276 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig | |||
@@ -108,7 +108,7 @@ config DVB_BUDGET_AV | |||
108 | tristate "Budget cards with analog video inputs" | 108 | tristate "Budget cards with analog video inputs" |
109 | depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 | 109 | depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 |
110 | select VIDEO_SAA7146_VV | 110 | select VIDEO_SAA7146_VV |
111 | select DVB_PLL | 111 | select DVB_PLL if !DVB_FE_CUSTOMISE |
112 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | 112 | select DVB_STV0299 if !DVB_FE_CUSTOMISE |
113 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE | 113 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE |
114 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE | 114 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE |
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile index aa85ecdc6c80..2c1145236ee6 100644 --- a/drivers/media/dvb/ttpci/Makefile +++ b/drivers/media/dvb/ttpci/Makefile | |||
@@ -11,7 +11,7 @@ obj-$(CONFIG_DVB_BUDGET_CI) += budget-core.o budget-ci.o ttpci-eeprom.o | |||
11 | obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-core.o budget-patch.o ttpci-eeprom.o | 11 | obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-core.o budget-patch.o ttpci-eeprom.o |
12 | obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o ttpci-eeprom.o | 12 | obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o ttpci-eeprom.o |
13 | 13 | ||
14 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | 14 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ |
15 | 15 | ||
16 | hostprogs-y := fdump | 16 | hostprogs-y := fdump |
17 | 17 | ||
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index ef1108c0bf11..2cee9e3bd29f 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -137,6 +137,15 @@ static void init_av7110_av(struct av7110 *av7110) | |||
137 | if (ret < 0) | 137 | if (ret < 0) |
138 | printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret); | 138 | printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret); |
139 | 139 | ||
140 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType, | ||
141 | 1, (u16) av7110->display_ar); | ||
142 | if (ret < 0) | ||
143 | printk("dvb-ttpci: unable to set aspect ratio\n"); | ||
144 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, | ||
145 | 1, av7110->display_panscan); | ||
146 | if (ret < 0) | ||
147 | printk("dvb-ttpci: unable to set pan scan\n"); | ||
148 | |||
140 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 2, wss_cfg_4_3); | 149 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 2, wss_cfg_4_3); |
141 | if (ret < 0) | 150 | if (ret < 0) |
142 | printk("dvb-ttpci: unable to configure 4:3 wss\n"); | 151 | printk("dvb-ttpci: unable to configure 4:3 wss\n"); |
@@ -2639,12 +2648,12 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, | |||
2639 | av7110->mixer.volume_left = volume; | 2648 | av7110->mixer.volume_left = volume; |
2640 | av7110->mixer.volume_right = volume; | 2649 | av7110->mixer.volume_right = volume; |
2641 | 2650 | ||
2642 | init_av7110_av(av7110); | ||
2643 | |||
2644 | ret = av7110_register(av7110); | 2651 | ret = av7110_register(av7110); |
2645 | if (ret < 0) | 2652 | if (ret < 0) |
2646 | goto err_arm_thread_stop_10; | 2653 | goto err_arm_thread_stop_10; |
2647 | 2654 | ||
2655 | init_av7110_av(av7110); | ||
2656 | |||
2648 | /* special case DVB-C: these cards have an analog tuner | 2657 | /* special case DVB-C: these cards have an analog tuner |
2649 | plus need some special handling, so we have separate | 2658 | plus need some special handling, so we have separate |
2650 | saa7146_ext_vv data for these... */ | 2659 | saa7146_ext_vv data for these... */ |
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index 115002b0390c..0cb439527498 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h | |||
@@ -194,6 +194,7 @@ struct av7110 { | |||
194 | 194 | ||
195 | int video_blank; | 195 | int video_blank; |
196 | struct video_status videostate; | 196 | struct video_status videostate; |
197 | u16 display_panscan; | ||
197 | int display_ar; | 198 | int display_ar; |
198 | int trickmode; | 199 | int trickmode; |
199 | #define TRICK_NONE 0 | 200 | #define TRICK_NONE 0 |
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index 58678c05aa53..d75e7e48addc 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c | |||
@@ -391,7 +391,7 @@ static int get_video_format(struct av7110 *av7110, u8 *buf, int count) | |||
391 | ****************************************************************************/ | 391 | ****************************************************************************/ |
392 | 392 | ||
393 | static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, | 393 | static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, |
394 | const char *buf, unsigned long count) | 394 | const u8 *buf, unsigned long count) |
395 | { | 395 | { |
396 | unsigned long todo = count; | 396 | unsigned long todo = count; |
397 | int free; | 397 | int free; |
@@ -436,7 +436,7 @@ static void play_audio_cb(u8 *buf, int count, void *priv) | |||
436 | #define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ | 436 | #define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ |
437 | dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) | 437 | dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) |
438 | 438 | ||
439 | static ssize_t dvb_play(struct av7110 *av7110, const u8 __user *buf, | 439 | static ssize_t dvb_play(struct av7110 *av7110, const char __user *buf, |
440 | unsigned long count, int nonblock, int type) | 440 | unsigned long count, int nonblock, int type) |
441 | { | 441 | { |
442 | unsigned long todo = count, n; | 442 | unsigned long todo = count, n; |
@@ -499,7 +499,7 @@ static ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf, | |||
499 | return count - todo; | 499 | return count - todo; |
500 | } | 500 | } |
501 | 501 | ||
502 | static ssize_t dvb_aplay(struct av7110 *av7110, const u8 __user *buf, | 502 | static ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf, |
503 | unsigned long count, int nonblock, int type) | 503 | unsigned long count, int nonblock, int type) |
504 | { | 504 | { |
505 | unsigned long todo = count, n; | 505 | unsigned long todo = count, n; |
@@ -959,7 +959,7 @@ static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x | |||
959 | 959 | ||
960 | #define MIN_IFRAME 400000 | 960 | #define MIN_IFRAME 400000 |
961 | 961 | ||
962 | static int play_iframe(struct av7110 *av7110, u8 __user *buf, unsigned int len, int nonblock) | 962 | static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) |
963 | { | 963 | { |
964 | int i, n; | 964 | int i, n; |
965 | 965 | ||
@@ -1082,19 +1082,18 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1082 | case VIDEO_SET_DISPLAY_FORMAT: | 1082 | case VIDEO_SET_DISPLAY_FORMAT: |
1083 | { | 1083 | { |
1084 | video_displayformat_t format = (video_displayformat_t) arg; | 1084 | video_displayformat_t format = (video_displayformat_t) arg; |
1085 | u16 val = 0; | ||
1086 | 1085 | ||
1087 | switch (format) { | 1086 | switch (format) { |
1088 | case VIDEO_PAN_SCAN: | 1087 | case VIDEO_PAN_SCAN: |
1089 | val = VID_PAN_SCAN_PREF; | 1088 | av7110->display_panscan = VID_PAN_SCAN_PREF; |
1090 | break; | 1089 | break; |
1091 | 1090 | ||
1092 | case VIDEO_LETTER_BOX: | 1091 | case VIDEO_LETTER_BOX: |
1093 | val = VID_VC_AND_PS_PREF; | 1092 | av7110->display_panscan = VID_VC_AND_PS_PREF; |
1094 | break; | 1093 | break; |
1095 | 1094 | ||
1096 | case VIDEO_CENTER_CUT_OUT: | 1095 | case VIDEO_CENTER_CUT_OUT: |
1097 | val = VID_CENTRE_CUT_PREF; | 1096 | av7110->display_panscan = VID_CENTRE_CUT_PREF; |
1098 | break; | 1097 | break; |
1099 | 1098 | ||
1100 | default: | 1099 | default: |
@@ -1104,7 +1103,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1104 | break; | 1103 | break; |
1105 | av7110->videostate.display_format = format; | 1104 | av7110->videostate.display_format = format; |
1106 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, | 1105 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, |
1107 | 1, (u16) val); | 1106 | 1, av7110->display_panscan); |
1108 | break; | 1107 | break; |
1109 | } | 1108 | } |
1110 | 1109 | ||
@@ -1466,8 +1465,9 @@ int av7110_av_register(struct av7110 *av7110) | |||
1466 | av7110->videostate.play_state = VIDEO_STOPPED; | 1465 | av7110->videostate.play_state = VIDEO_STOPPED; |
1467 | av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; | 1466 | av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; |
1468 | av7110->videostate.video_format = VIDEO_FORMAT_4_3; | 1467 | av7110->videostate.video_format = VIDEO_FORMAT_4_3; |
1469 | av7110->videostate.display_format = VIDEO_CENTER_CUT_OUT; | 1468 | av7110->videostate.display_format = VIDEO_LETTER_BOX; |
1470 | av7110->display_ar = VIDEO_FORMAT_4_3; | 1469 | av7110->display_ar = VIDEO_FORMAT_4_3; |
1470 | av7110->display_panscan = VID_VC_AND_PS_PREF; | ||
1471 | 1471 | ||
1472 | init_waitqueue_head(&av7110->video_events.wait_queue); | 1472 | init_waitqueue_head(&av7110->video_events.wait_queue); |
1473 | spin_lock_init(&av7110->video_events.lock); | 1473 | spin_lock_init(&av7110->video_events.lock); |
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c index e1c1294bb767..c58e3fc509ed 100644 --- a/drivers/media/dvb/ttpci/av7110_ca.c +++ b/drivers/media/dvb/ttpci/av7110_ca.c | |||
@@ -151,7 +151,7 @@ static ssize_t ci_ll_write(struct dvb_ringbuffer *cibuf, struct file *file, | |||
151 | { | 151 | { |
152 | int free; | 152 | int free; |
153 | int non_blocking = file->f_flags & O_NONBLOCK; | 153 | int non_blocking = file->f_flags & O_NONBLOCK; |
154 | char *page = (char *)__get_free_page(GFP_USER); | 154 | u8 *page = (u8 *)__get_free_page(GFP_USER); |
155 | int res; | 155 | int res; |
156 | 156 | ||
157 | if (!page) | 157 | if (!page) |
@@ -208,7 +208,7 @@ static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file, | |||
208 | return -EINVAL; | 208 | return -EINVAL; |
209 | DVB_RINGBUFFER_SKIP(cibuf, 2); | 209 | DVB_RINGBUFFER_SKIP(cibuf, 2); |
210 | 210 | ||
211 | return dvb_ringbuffer_read(cibuf, buf, len, 1); | 211 | return dvb_ringbuffer_read(cibuf, (u8 *)buf, len, 1); |
212 | } | 212 | } |
213 | 213 | ||
214 | static int dvb_ca_open(struct inode *inode, struct file *file) | 214 | static int dvb_ca_open(struct inode *inode, struct file *file) |
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index 70aee4eb5da4..515e8232e020 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c | |||
@@ -158,7 +158,7 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len) | |||
158 | } | 158 | } |
159 | dprintk(4, "writing DRAM block %d\n", i); | 159 | dprintk(4, "writing DRAM block %d\n", i); |
160 | mwdebi(av7110, DEBISWAB, bootblock, | 160 | mwdebi(av7110, DEBISWAB, bootblock, |
161 | ((char*)data) + i * AV7110_BOOT_MAX_SIZE, AV7110_BOOT_MAX_SIZE); | 161 | ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, AV7110_BOOT_MAX_SIZE); |
162 | bootblock ^= 0x1400; | 162 | bootblock ^= 0x1400; |
163 | iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4); | 163 | iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4); |
164 | iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, AV7110_BOOT_MAX_SIZE, 2); | 164 | iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, AV7110_BOOT_MAX_SIZE, 2); |
@@ -173,10 +173,10 @@ static int load_dram(struct av7110 *av7110, u32 *data, int len) | |||
173 | } | 173 | } |
174 | if (rest > 4) | 174 | if (rest > 4) |
175 | mwdebi(av7110, DEBISWAB, bootblock, | 175 | mwdebi(av7110, DEBISWAB, bootblock, |
176 | ((char*)data) + i * AV7110_BOOT_MAX_SIZE, rest); | 176 | ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, rest); |
177 | else | 177 | else |
178 | mwdebi(av7110, DEBISWAB, bootblock, | 178 | mwdebi(av7110, DEBISWAB, bootblock, |
179 | ((char*)data) + i * AV7110_BOOT_MAX_SIZE - 4, rest + 4); | 179 | ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE - 4, rest + 4); |
180 | 180 | ||
181 | iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4); | 181 | iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4); |
182 | iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, rest, 2); | 182 | iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, rest, 2); |
@@ -751,7 +751,7 @@ static int FlushText(struct av7110 *av7110) | |||
751 | return 0; | 751 | return 0; |
752 | } | 752 | } |
753 | 753 | ||
754 | static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) | 754 | static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf) |
755 | { | 755 | { |
756 | int i, ret; | 756 | int i, ret; |
757 | unsigned long start; | 757 | unsigned long start; |
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h index 673d9b3f064c..74d940f75da6 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.h +++ b/drivers/media/dvb/ttpci/av7110_hw.h | |||
@@ -393,7 +393,7 @@ static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, | |||
393 | } | 393 | } |
394 | 394 | ||
395 | /* buffer writes */ | 395 | /* buffer writes */ |
396 | static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, char *val, int count) | 396 | static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, u8 *val, int count) |
397 | { | 397 | { |
398 | memcpy(av7110->debi_virt, val, count); | 398 | memcpy(av7110->debi_virt, val, count); |
399 | av7110_debiwrite(av7110, config, addr, 0, count); | 399 | av7110_debiwrite(av7110, config, addr, 0, count); |
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c index a97f166bb523..6322800ee12b 100644 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ b/drivers/media/dvb/ttpci/av7110_ir.c | |||
@@ -356,7 +356,7 @@ int __devinit av7110_ir_init(struct av7110 *av7110) | |||
356 | input_dev->id.vendor = av7110->dev->pci->vendor; | 356 | input_dev->id.vendor = av7110->dev->pci->vendor; |
357 | input_dev->id.product = av7110->dev->pci->device; | 357 | input_dev->id.product = av7110->dev->pci->device; |
358 | } | 358 | } |
359 | input_dev->cdev.dev = &av7110->dev->pci->dev; | 359 | input_dev->dev.parent = &av7110->dev->pci->dev; |
360 | /* initial keymap */ | 360 | /* initial keymap */ |
361 | memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map); | 361 | memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map); |
362 | input_register_keys(&av7110->ir); | 362 | input_register_keys(&av7110->ir); |
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index fcd9994058d0..87afaebc0703 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c | |||
@@ -333,7 +333,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | |||
333 | return -EINVAL; | 333 | return -EINVAL; |
334 | 334 | ||
335 | memset(t, 0, sizeof(*t)); | 335 | memset(t, 0, sizeof(*t)); |
336 | strcpy(t->name, "Television"); | 336 | strcpy((char *)t->name, "Television"); |
337 | 337 | ||
338 | t->type = V4L2_TUNER_ANALOG_TV; | 338 | t->type = V4L2_TUNER_ANALOG_TV; |
339 | t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | | 339 | t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | |
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 0e817d6f1ce5..0aee7a13a070 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
@@ -828,29 +828,6 @@ static u8 philips_sd1878_inittab[] = { | |||
828 | 0xff, 0xff | 828 | 0xff, 0xff |
829 | }; | 829 | }; |
830 | 830 | ||
831 | static int philips_sd1878_tda8261_tuner_set_params(struct dvb_frontend *fe, | ||
832 | struct dvb_frontend_parameters *params) | ||
833 | { | ||
834 | u8 buf[4]; | ||
835 | int rc; | ||
836 | struct i2c_msg tuner_msg = {.addr=0x60,.flags=0,.buf=buf,.len=sizeof(buf)}; | ||
837 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
838 | |||
839 | if((params->frequency < 950000) || (params->frequency > 2150000)) | ||
840 | return -EINVAL; | ||
841 | |||
842 | rc=dvb_pll_configure(&dvb_pll_philips_sd1878_tda8261, buf, | ||
843 | params->frequency, 0); | ||
844 | if(rc < 0) return rc; | ||
845 | |||
846 | if (fe->ops.i2c_gate_ctrl) | ||
847 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
848 | if(i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) | ||
849 | return -EIO; | ||
850 | |||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe, | 831 | static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe, |
855 | u32 srate, u32 ratio) | 832 | u32 srate, u32 ratio) |
856 | { | 833 | { |
@@ -921,6 +898,7 @@ static u8 read_pwm(struct budget_av *budget_av) | |||
921 | #define SUBID_DVBS_TV_STAR 0x0014 | 898 | #define SUBID_DVBS_TV_STAR 0x0014 |
922 | #define SUBID_DVBS_TV_STAR_CI 0x0016 | 899 | #define SUBID_DVBS_TV_STAR_CI 0x0016 |
923 | #define SUBID_DVBS_EASYWATCH_1 0x001a | 900 | #define SUBID_DVBS_EASYWATCH_1 0x001a |
901 | #define SUBID_DVBS_EASYWATCH_2 0x001b | ||
924 | #define SUBID_DVBS_EASYWATCH 0x001e | 902 | #define SUBID_DVBS_EASYWATCH 0x001e |
925 | 903 | ||
926 | #define SUBID_DVBC_EASYWATCH 0x002a | 904 | #define SUBID_DVBC_EASYWATCH 0x002a |
@@ -982,10 +960,13 @@ static void frontend_init(struct budget_av *budget_av) | |||
982 | case SUBID_DVBS_TV_STAR_CI: | 960 | case SUBID_DVBS_TV_STAR_CI: |
983 | case SUBID_DVBS_CYNERGY1200N: | 961 | case SUBID_DVBS_CYNERGY1200N: |
984 | case SUBID_DVBS_EASYWATCH: | 962 | case SUBID_DVBS_EASYWATCH: |
963 | case SUBID_DVBS_EASYWATCH_2: | ||
985 | fe = dvb_attach(stv0299_attach, &philips_sd1878_config, | 964 | fe = dvb_attach(stv0299_attach, &philips_sd1878_config, |
986 | &budget_av->budget.i2c_adap); | 965 | &budget_av->budget.i2c_adap); |
987 | if (fe) { | 966 | if (fe) { |
988 | fe->ops.tuner_ops.set_params = philips_sd1878_tda8261_tuner_set_params; | 967 | dvb_attach(dvb_pll_attach, fe, 0x60, |
968 | &budget_av->budget.i2c_adap, | ||
969 | DVB_PLL_PHILIPS_SD1878_TDA8261); | ||
989 | } | 970 | } |
990 | break; | 971 | break; |
991 | 972 | ||
@@ -1264,6 +1245,7 @@ MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); | |||
1264 | MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); | 1245 | MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); |
1265 | MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); | 1246 | MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); |
1266 | MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); | 1247 | MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); |
1248 | MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S); | ||
1267 | MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); | 1249 | MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); |
1268 | MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3); | 1250 | MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3); |
1269 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); | 1251 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); |
@@ -1287,6 +1269,7 @@ static struct pci_device_id pci_tbl[] = { | |||
1287 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), | 1269 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), |
1288 | MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), | 1270 | MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), |
1289 | MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), | 1271 | MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), |
1272 | MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b), | ||
1290 | MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a), | 1273 | MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a), |
1291 | MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c), | 1274 | MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c), |
1292 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), | 1275 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), |
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 9d42f88ebb0e..873c3ba296f2 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -206,7 +206,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
206 | input_dev->id.vendor = saa->pci->vendor; | 206 | input_dev->id.vendor = saa->pci->vendor; |
207 | input_dev->id.product = saa->pci->device; | 207 | input_dev->id.product = saa->pci->device; |
208 | } | 208 | } |
209 | input_dev->cdev.dev = &saa->pci->dev; | 209 | input_dev->dev.parent = &saa->pci->dev; |
210 | 210 | ||
211 | /* Select keymap and address */ | 211 | /* Select keymap and address */ |
212 | switch (budget_ci->budget.dev->pci->subsystem_device) { | 212 | switch (budget_ci->budget.dev->pci->subsystem_device) { |
diff --git a/drivers/media/dvb/ttusb-budget/Makefile b/drivers/media/dvb/ttusb-budget/Makefile index 6ab97f6b53fc..fbe2b9514c21 100644 --- a/drivers/media/dvb/ttusb-budget/Makefile +++ b/drivers/media/dvb/ttusb-budget/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o | 1 | obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o |
2 | 2 | ||
3 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends | 3 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends |
diff --git a/drivers/media/dvb/ttusb-dec/Makefile b/drivers/media/dvb/ttusb-dec/Makefile index b41bf1f06a9f..2d70a8269391 100644 --- a/drivers/media/dvb/ttusb-dec/Makefile +++ b/drivers/media/dvb/ttusb-dec/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o | 1 | obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o |
2 | 2 | ||
3 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ | 3 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 194b102140ef..f8bf9fe37d36 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
@@ -324,8 +324,8 @@ config RADIO_ZOLTRIX_PORT | |||
324 | Enter the I/O port of your Zoltrix radio card. | 324 | Enter the I/O port of your Zoltrix radio card. |
325 | 325 | ||
326 | config USB_DSBR | 326 | config USB_DSBR |
327 | tristate "D-Link USB FM radio support (EXPERIMENTAL)" | 327 | tristate "D-Link/GemTek USB FM radio support" |
328 | depends on USB && VIDEO_V4L2 && EXPERIMENTAL | 328 | depends on USB && VIDEO_V4L2 |
329 | ---help--- | 329 | ---help--- |
330 | Say Y here if you want to connect this type of radio to your | 330 | Say Y here if you want to connect this type of radio to your |
331 | computer's USB port. Note that the audio is not digital, and | 331 | computer's USB port. Note that the audio is not digital, and |
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 5adc27c3ced9..ce940b1b787f 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
@@ -392,7 +392,6 @@ static struct video_device rtrack_radio= | |||
392 | .owner = THIS_MODULE, | 392 | .owner = THIS_MODULE, |
393 | .name = "RadioTrack radio", | 393 | .name = "RadioTrack radio", |
394 | .type = VID_TYPE_TUNER, | 394 | .type = VID_TYPE_TUNER, |
395 | .hardware = 0, | ||
396 | .fops = &rtrack_fops, | 395 | .fops = &rtrack_fops, |
397 | .vidioc_querycap = vidioc_querycap, | 396 | .vidioc_querycap = vidioc_querycap, |
398 | .vidioc_g_tuner = vidioc_g_tuner, | 397 | .vidioc_g_tuner = vidioc_g_tuner, |
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 9f1addae6928..9b1f7a99dac0 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c | |||
@@ -355,7 +355,6 @@ static struct video_device aztech_radio= | |||
355 | .owner = THIS_MODULE, | 355 | .owner = THIS_MODULE, |
356 | .name = "Aztech radio", | 356 | .name = "Aztech radio", |
357 | .type = VID_TYPE_TUNER, | 357 | .type = VID_TYPE_TUNER, |
358 | .hardware = 0, | ||
359 | .fops = &aztech_fops, | 358 | .fops = &aztech_fops, |
360 | .vidioc_querycap = vidioc_querycap, | 359 | .vidioc_querycap = vidioc_querycap, |
361 | .vidioc_g_tuner = vidioc_g_tuner, | 360 | .vidioc_g_tuner = vidioc_g_tuner, |
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 5e6f17df204b..4db05b2b1b6e 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c | |||
@@ -377,7 +377,6 @@ static struct video_device vdev_template = { | |||
377 | .owner = THIS_MODULE, | 377 | .owner = THIS_MODULE, |
378 | .name = "Gemtek PCI Radio", | 378 | .name = "Gemtek PCI Radio", |
379 | .type = VID_TYPE_TUNER, | 379 | .type = VID_TYPE_TUNER, |
380 | .hardware = 0, | ||
381 | .fops = &gemtek_pci_fops, | 380 | .fops = &gemtek_pci_fops, |
382 | .vidioc_querycap = vidioc_querycap, | 381 | .vidioc_querycap = vidioc_querycap, |
383 | .vidioc_g_tuner = vidioc_g_tuner, | 382 | .vidioc_g_tuner = vidioc_g_tuner, |
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index b04b6a7fff7c..eab8c80a2e47 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
@@ -330,7 +330,6 @@ static struct video_device gemtek_radio= | |||
330 | .owner = THIS_MODULE, | 330 | .owner = THIS_MODULE, |
331 | .name = "GemTek radio", | 331 | .name = "GemTek radio", |
332 | .type = VID_TYPE_TUNER, | 332 | .type = VID_TYPE_TUNER, |
333 | .hardware = 0, | ||
334 | .fops = &gemtek_fops, | 333 | .fops = &gemtek_fops, |
335 | .vidioc_querycap = vidioc_querycap, | 334 | .vidioc_querycap = vidioc_querycap, |
336 | .vidioc_g_tuner = vidioc_g_tuner, | 335 | .vidioc_g_tuner = vidioc_g_tuner, |
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index 9b493b3298cd..82aedfc95d4f 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c | |||
@@ -297,7 +297,6 @@ static struct video_device rtrack2_radio= | |||
297 | .owner = THIS_MODULE, | 297 | .owner = THIS_MODULE, |
298 | .name = "RadioTrack II radio", | 298 | .name = "RadioTrack II radio", |
299 | .type = VID_TYPE_TUNER, | 299 | .type = VID_TYPE_TUNER, |
300 | .hardware = 0, | ||
301 | .fops = &rtrack2_fops, | 300 | .fops = &rtrack2_fops, |
302 | .vidioc_querycap = vidioc_querycap, | 301 | .vidioc_querycap = vidioc_querycap, |
303 | .vidioc_g_tuner = vidioc_g_tuner, | 302 | .vidioc_g_tuner = vidioc_g_tuner, |
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index dc33f19c0e2c..395165367f37 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
@@ -297,7 +297,6 @@ static struct video_device fmi_radio= | |||
297 | .owner = THIS_MODULE, | 297 | .owner = THIS_MODULE, |
298 | .name = "SF16FMx radio", | 298 | .name = "SF16FMx radio", |
299 | .type = VID_TYPE_TUNER, | 299 | .type = VID_TYPE_TUNER, |
300 | .hardware = 0, | ||
301 | .fops = &fmi_fops, | 300 | .fops = &fmi_fops, |
302 | .vidioc_querycap = vidioc_querycap, | 301 | .vidioc_querycap = vidioc_querycap, |
303 | .vidioc_g_tuner = vidioc_g_tuner, | 302 | .vidioc_g_tuner = vidioc_g_tuner, |
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index e6c125def5cb..c432c44bd634 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
@@ -442,7 +442,6 @@ static struct video_device fmr2_radio= | |||
442 | .owner = THIS_MODULE, | 442 | .owner = THIS_MODULE, |
443 | .name = "SF16FMR2 radio", | 443 | .name = "SF16FMR2 radio", |
444 | . type = VID_TYPE_TUNER, | 444 | . type = VID_TYPE_TUNER, |
445 | .hardware = 0, | ||
446 | .fops = &fmr2_fops, | 445 | .fops = &fmr2_fops, |
447 | .vidioc_querycap = vidioc_querycap, | 446 | .vidioc_querycap = vidioc_querycap, |
448 | .vidioc_g_tuner = vidioc_g_tuner, | 447 | .vidioc_g_tuner = vidioc_g_tuner, |
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index e43acfd7e533..7e1911c3d54e 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c | |||
@@ -369,7 +369,6 @@ static struct video_device terratec_radio= | |||
369 | .owner = THIS_MODULE, | 369 | .owner = THIS_MODULE, |
370 | .name = "TerraTec ActiveRadio", | 370 | .name = "TerraTec ActiveRadio", |
371 | .type = VID_TYPE_TUNER, | 371 | .type = VID_TYPE_TUNER, |
372 | .hardware = 0, | ||
373 | .fops = &terratec_fops, | 372 | .fops = &terratec_fops, |
374 | .vidioc_querycap = vidioc_querycap, | 373 | .vidioc_querycap = vidioc_querycap, |
375 | .vidioc_g_tuner = vidioc_g_tuner, | 374 | .vidioc_g_tuner = vidioc_g_tuner, |
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index c27c629d99df..c11981fed827 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c | |||
@@ -349,7 +349,6 @@ static struct video_device trust_radio= | |||
349 | .owner = THIS_MODULE, | 349 | .owner = THIS_MODULE, |
350 | .name = "Trust FM Radio", | 350 | .name = "Trust FM Radio", |
351 | .type = VID_TYPE_TUNER, | 351 | .type = VID_TYPE_TUNER, |
352 | .hardware = 0, | ||
353 | .fops = &trust_fops, | 352 | .fops = &trust_fops, |
354 | .vidioc_querycap = vidioc_querycap, | 353 | .vidioc_querycap = vidioc_querycap, |
355 | .vidioc_g_tuner = vidioc_g_tuner, | 354 | .vidioc_g_tuner = vidioc_g_tuner, |
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 8ff5a23a9f01..1366326474e5 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
@@ -349,7 +349,6 @@ static struct video_device typhoon_radio = | |||
349 | .owner = THIS_MODULE, | 349 | .owner = THIS_MODULE, |
350 | .name = "Typhoon Radio", | 350 | .name = "Typhoon Radio", |
351 | .type = VID_TYPE_TUNER, | 351 | .type = VID_TYPE_TUNER, |
352 | .hardware = 0, | ||
353 | .fops = &typhoon_fops, | 352 | .fops = &typhoon_fops, |
354 | .vidioc_querycap = vidioc_querycap, | 353 | .vidioc_querycap = vidioc_querycap, |
355 | .vidioc_g_tuner = vidioc_g_tuner, | 354 | .vidioc_g_tuner = vidioc_g_tuner, |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 4d45a40016de..9dcbffd0aa15 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -489,6 +489,15 @@ config TUNER_3036 | |||
489 | Say Y here to include support for Philips SAB3036 compatible tuners. | 489 | Say Y here to include support for Philips SAB3036 compatible tuners. |
490 | If in doubt, say N. | 490 | If in doubt, say N. |
491 | 491 | ||
492 | config TUNER_TEA5761 | ||
493 | bool "TEA 5761 radio tuner (EXPERIMENTAL)" | ||
494 | depends on EXPERIMENTAL | ||
495 | depends on I2C | ||
496 | select VIDEO_TUNER | ||
497 | help | ||
498 | Say Y here to include support for Philips TEA5761 radio tuner. | ||
499 | If in doubt, say N. | ||
500 | |||
492 | config VIDEO_VINO | 501 | config VIDEO_VINO |
493 | tristate "SGI Vino Video For Linux (EXPERIMENTAL)" | 502 | tristate "SGI Vino Video For Linux (EXPERIMENTAL)" |
494 | depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 | 503 | depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 9c2de501612f..10b4d4469016 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -7,6 +7,8 @@ zr36067-objs := zoran_procfs.o zoran_device.o \ | |||
7 | tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ | 7 | tuner-objs := tuner-core.o tuner-types.o tuner-simple.o \ |
8 | mt20xx.o tda8290.o tea5767.o tda9887.o | 8 | mt20xx.o tda8290.o tea5767.o tda9887.o |
9 | 9 | ||
10 | tuner-$(CONFIG_TUNER_TEA5761) += tea5761.o | ||
11 | |||
10 | msp3400-objs := msp3400-driver.o msp3400-kthreads.o | 12 | msp3400-objs := msp3400-driver.o msp3400-kthreads.o |
11 | 13 | ||
12 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o | 14 | obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o |
@@ -16,7 +18,7 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y) | |||
16 | endif | 18 | endif |
17 | 19 | ||
18 | obj-$(CONFIG_VIDEO_BT848) += bt8xx/ | 20 | obj-$(CONFIG_VIDEO_BT848) += bt8xx/ |
19 | obj-$(CONFIG_VIDEO_BT848) += ir-kbd-i2c.o | 21 | obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o |
20 | obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o | 22 | obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o |
21 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o | 23 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o |
22 | obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o | 24 | obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o |
@@ -59,7 +61,7 @@ obj-$(CONFIG_VIDEO_CPIA) += cpia.o | |||
59 | obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o | 61 | obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o |
60 | obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o | 62 | obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o |
61 | obj-$(CONFIG_VIDEO_MEYE) += meye.o | 63 | obj-$(CONFIG_VIDEO_MEYE) += meye.o |
62 | obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/ | 64 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ |
63 | obj-$(CONFIG_VIDEO_CX88) += cx88/ | 65 | obj-$(CONFIG_VIDEO_CX88) += cx88/ |
64 | obj-$(CONFIG_VIDEO_IVTV) += ivtv/ | 66 | obj-$(CONFIG_VIDEO_IVTV) += ivtv/ |
65 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ | 67 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ |
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 823cd6cc471e..cbab53fc6243 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c | |||
@@ -38,23 +38,23 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/mm.h> | 39 | #include <linux/mm.h> |
40 | #include <linux/signal.h> | 40 | #include <linux/signal.h> |
41 | #include <linux/types.h> | ||
42 | #include <linux/i2c.h> | ||
41 | #include <asm/io.h> | 43 | #include <asm/io.h> |
42 | #include <asm/pgtable.h> | 44 | #include <asm/pgtable.h> |
43 | #include <asm/page.h> | 45 | #include <asm/page.h> |
44 | #include <linux/types.h> | 46 | #include <asm/uaccess.h> |
45 | 47 | ||
46 | #include <linux/videodev.h> | 48 | #include <linux/videodev.h> |
47 | #include <asm/uaccess.h> | 49 | #include <linux/video_encoder.h> |
48 | 50 | ||
49 | MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver"); | 51 | MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver"); |
50 | MODULE_AUTHOR("Maxim Yevtyushkin"); | 52 | MODULE_AUTHOR("Maxim Yevtyushkin"); |
51 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
52 | 54 | ||
53 | #include <linux/i2c.h> | ||
54 | 55 | ||
55 | #define I2C_NAME(x) (x)->name | 56 | #define I2C_NAME(x) (x)->name |
56 | 57 | ||
57 | #include <linux/video_encoder.h> | ||
58 | 58 | ||
59 | static int debug = 0; | 59 | static int debug = 0; |
60 | module_param(debug, int, 0); | 60 | module_param(debug, int, 0); |
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index 05c7820fe53e..0d0c554bfdf7 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c | |||
@@ -34,23 +34,23 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/mm.h> | 35 | #include <linux/mm.h> |
36 | #include <linux/signal.h> | 36 | #include <linux/signal.h> |
37 | #include <linux/types.h> | ||
38 | #include <linux/i2c.h> | ||
37 | #include <asm/io.h> | 39 | #include <asm/io.h> |
38 | #include <asm/pgtable.h> | 40 | #include <asm/pgtable.h> |
39 | #include <asm/page.h> | 41 | #include <asm/page.h> |
40 | #include <linux/types.h> | 42 | #include <asm/uaccess.h> |
41 | 43 | ||
42 | #include <linux/videodev.h> | 44 | #include <linux/videodev.h> |
43 | #include <asm/uaccess.h> | 45 | #include <linux/video_encoder.h> |
44 | 46 | ||
45 | MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver"); | 47 | MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver"); |
46 | MODULE_AUTHOR("Dave Perks"); | 48 | MODULE_AUTHOR("Dave Perks"); |
47 | MODULE_LICENSE("GPL"); | 49 | MODULE_LICENSE("GPL"); |
48 | 50 | ||
49 | #include <linux/i2c.h> | ||
50 | 51 | ||
51 | #define I2C_NAME(s) (s)->name | 52 | #define I2C_NAME(s) (s)->name |
52 | 53 | ||
53 | #include <linux/video_encoder.h> | ||
54 | 54 | ||
55 | static int debug = 0; | 55 | static int debug = 0; |
56 | module_param(debug, int, 0); | 56 | module_param(debug, int, 0); |
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index 59a43603b5cb..12d1b9248be5 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c | |||
@@ -38,23 +38,24 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/mm.h> | 39 | #include <linux/mm.h> |
40 | #include <linux/signal.h> | 40 | #include <linux/signal.h> |
41 | #include <linux/types.h> | ||
42 | #include <linux/i2c.h> | ||
41 | #include <asm/io.h> | 43 | #include <asm/io.h> |
42 | #include <asm/pgtable.h> | 44 | #include <asm/pgtable.h> |
43 | #include <asm/page.h> | 45 | #include <asm/page.h> |
44 | #include <linux/types.h> | 46 | #include <asm/uaccess.h> |
45 | 47 | ||
46 | #include <linux/videodev.h> | 48 | #include <linux/videodev.h> |
47 | #include <asm/uaccess.h> | 49 | #include <linux/video_decoder.h> |
50 | |||
48 | 51 | ||
49 | MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); | 52 | MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); |
50 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); | 53 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); |
51 | MODULE_LICENSE("GPL"); | 54 | MODULE_LICENSE("GPL"); |
52 | 55 | ||
53 | #include <linux/i2c.h> | ||
54 | 56 | ||
55 | #define I2C_NAME(s) (s)->name | 57 | #define I2C_NAME(s) (s)->name |
56 | 58 | ||
57 | #include <linux/video_decoder.h> | ||
58 | 59 | ||
59 | static int debug = 0; | 60 | static int debug = 0; |
60 | module_param(debug, int, 0); | 61 | module_param(debug, int, 0); |
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index 853b1a3d6a1d..e1028a76c042 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c | |||
@@ -38,23 +38,23 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/mm.h> | 39 | #include <linux/mm.h> |
40 | #include <linux/signal.h> | 40 | #include <linux/signal.h> |
41 | #include <linux/types.h> | ||
42 | #include <linux/i2c.h> | ||
43 | #include <linux/video_encoder.h> | ||
41 | #include <asm/io.h> | 44 | #include <asm/io.h> |
42 | #include <asm/pgtable.h> | 45 | #include <asm/pgtable.h> |
43 | #include <asm/page.h> | 46 | #include <asm/page.h> |
44 | #include <linux/types.h> | 47 | #include <asm/uaccess.h> |
45 | 48 | ||
46 | #include <linux/videodev.h> | 49 | #include <linux/videodev.h> |
47 | #include <asm/uaccess.h> | ||
48 | 50 | ||
49 | MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); | 51 | MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); |
50 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); | 52 | MODULE_AUTHOR("Mike Bernson & Dave Perks"); |
51 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
52 | 54 | ||
53 | #include <linux/i2c.h> | ||
54 | 55 | ||
55 | #define I2C_NAME(s) (s)->name | 56 | #define I2C_NAME(s) (s)->name |
56 | 57 | ||
57 | #include <linux/video_encoder.h> | ||
58 | 58 | ||
59 | static int debug = 0; | 59 | static int debug = 0; |
60 | module_param(debug, int, 0); | 60 | module_param(debug, int, 0); |
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 6b31e50fb951..2aea09c72093 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c | |||
@@ -178,8 +178,8 @@ static struct CARD { | |||
178 | /* this seems to happen as well ... */ | 178 | /* this seems to happen as well ... */ |
179 | { 0xff1211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" }, | 179 | { 0xff1211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" }, |
180 | 180 | ||
181 | { 0x3000121a, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, | 181 | { 0x3000121a, BTTV_BOARD_VOODOOTV_200, "3Dfx VoodooTV 200" }, |
182 | { 0x263710b4, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, | 182 | { 0x263710b4, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM" }, |
183 | { 0x3060121a, BTTV_BOARD_STB2, "3Dfx VoodooTV 100/ STB OEM" }, | 183 | { 0x3060121a, BTTV_BOARD_STB2, "3Dfx VoodooTV 100/ STB OEM" }, |
184 | 184 | ||
185 | { 0x3000144f, BTTV_BOARD_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, | 185 | { 0x3000144f, BTTV_BOARD_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, |
@@ -313,6 +313,7 @@ static struct CARD { | |||
313 | { 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" }, | 313 | { 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" }, |
314 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, | 314 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, |
315 | { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini "}, | 315 | { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini "}, |
316 | { 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" }, | ||
316 | 317 | ||
317 | { 0, -1, NULL } | 318 | { 0, -1, NULL } |
318 | }; | 319 | }; |
@@ -329,7 +330,7 @@ struct tvcard bttv_tvcards[] = { | |||
329 | .tuner = 0, | 330 | .tuner = 0, |
330 | .svhs = 2, | 331 | .svhs = 2, |
331 | .muxsel = { 2, 3, 1, 0 }, | 332 | .muxsel = { 2, 3, 1, 0 }, |
332 | .tuner_type = -1, | 333 | .tuner_type = UNSET, |
333 | .tuner_addr = ADDR_UNSET, | 334 | .tuner_addr = ADDR_UNSET, |
334 | .radio_addr = ADDR_UNSET, | 335 | .radio_addr = ADDR_UNSET, |
335 | }, | 336 | }, |
@@ -344,7 +345,7 @@ struct tvcard bttv_tvcards[] = { | |||
344 | .gpiomux = { 2, 0, 0, 0 }, | 345 | .gpiomux = { 2, 0, 0, 0 }, |
345 | .gpiomute = 10, | 346 | .gpiomute = 10, |
346 | .needs_tvaudio = 1, | 347 | .needs_tvaudio = 1, |
347 | .tuner_type = -1, | 348 | .tuner_type = UNSET, |
348 | .tuner_addr = ADDR_UNSET, | 349 | .tuner_addr = ADDR_UNSET, |
349 | .radio_addr = ADDR_UNSET, | 350 | .radio_addr = ADDR_UNSET, |
350 | }, | 351 | }, |
@@ -359,7 +360,7 @@ struct tvcard bttv_tvcards[] = { | |||
359 | .gpiomux = { 0, 1, 2, 3 }, | 360 | .gpiomux = { 0, 1, 2, 3 }, |
360 | .gpiomute = 4, | 361 | .gpiomute = 4, |
361 | .needs_tvaudio = 1, | 362 | .needs_tvaudio = 1, |
362 | .tuner_type = -1, | 363 | .tuner_type = UNSET, |
363 | .tuner_addr = ADDR_UNSET, | 364 | .tuner_addr = ADDR_UNSET, |
364 | .radio_addr = ADDR_UNSET, | 365 | .radio_addr = ADDR_UNSET, |
365 | }, | 366 | }, |
@@ -387,13 +388,13 @@ struct tvcard bttv_tvcards[] = { | |||
387 | .name = "Intel Create and Share PCI/ Smart Video Recorder III", | 388 | .name = "Intel Create and Share PCI/ Smart Video Recorder III", |
388 | .video_inputs = 4, | 389 | .video_inputs = 4, |
389 | .audio_inputs = 0, | 390 | .audio_inputs = 0, |
390 | .tuner = -1, | 391 | .tuner = UNSET, |
391 | .svhs = 2, | 392 | .svhs = 2, |
392 | .gpiomask = 0, | 393 | .gpiomask = 0, |
393 | .muxsel = { 2, 3, 1, 1 }, | 394 | .muxsel = { 2, 3, 1, 1 }, |
394 | .gpiomux = { 0 }, | 395 | .gpiomux = { 0 }, |
395 | .needs_tvaudio = 0, | 396 | .needs_tvaudio = 0, |
396 | .tuner_type = 4, | 397 | .tuner_type = TUNER_ABSENT, |
397 | .tuner_addr = ADDR_UNSET, | 398 | .tuner_addr = ADDR_UNSET, |
398 | .radio_addr = ADDR_UNSET, | 399 | .radio_addr = ADDR_UNSET, |
399 | }, | 400 | }, |
@@ -408,7 +409,7 @@ struct tvcard bttv_tvcards[] = { | |||
408 | .gpiomux = { 0, 1, 0, 1 }, | 409 | .gpiomux = { 0, 1, 0, 1 }, |
409 | .gpiomute = 3, | 410 | .gpiomute = 3, |
410 | .needs_tvaudio = 1, | 411 | .needs_tvaudio = 1, |
411 | .tuner_type = -1, | 412 | .tuner_type = UNSET, |
412 | .tuner_addr = ADDR_UNSET, | 413 | .tuner_addr = ADDR_UNSET, |
413 | .radio_addr = ADDR_UNSET, | 414 | .radio_addr = ADDR_UNSET, |
414 | }, | 415 | }, |
@@ -423,7 +424,7 @@ struct tvcard bttv_tvcards[] = { | |||
423 | .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, | 424 | .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, |
424 | /* 0x04 for some cards ?? */ | 425 | /* 0x04 for some cards ?? */ |
425 | .needs_tvaudio = 1, | 426 | .needs_tvaudio = 1, |
426 | .tuner_type = -1, | 427 | .tuner_type = UNSET, |
427 | .tuner_addr = ADDR_UNSET, | 428 | .tuner_addr = ADDR_UNSET, |
428 | .radio_addr = ADDR_UNSET, | 429 | .radio_addr = ADDR_UNSET, |
429 | .audio_hook = avermedia_tvphone_audio, | 430 | .audio_hook = avermedia_tvphone_audio, |
@@ -433,13 +434,13 @@ struct tvcard bttv_tvcards[] = { | |||
433 | .name = "MATRIX-Vision MV-Delta", | 434 | .name = "MATRIX-Vision MV-Delta", |
434 | .video_inputs = 5, | 435 | .video_inputs = 5, |
435 | .audio_inputs = 1, | 436 | .audio_inputs = 1, |
436 | .tuner = -1, | 437 | .tuner = UNSET, |
437 | .svhs = 3, | 438 | .svhs = 3, |
438 | .gpiomask = 0, | 439 | .gpiomask = 0, |
439 | .muxsel = { 2, 3, 1, 0, 0 }, | 440 | .muxsel = { 2, 3, 1, 0, 0 }, |
440 | .gpiomux = { 0 }, | 441 | .gpiomux = { 0 }, |
441 | .needs_tvaudio = 1, | 442 | .needs_tvaudio = 1, |
442 | .tuner_type = -1, | 443 | .tuner_type = UNSET, |
443 | .tuner_addr = ADDR_UNSET, | 444 | .tuner_addr = ADDR_UNSET, |
444 | .radio_addr = ADDR_UNSET, | 445 | .radio_addr = ADDR_UNSET, |
445 | }, | 446 | }, |
@@ -457,7 +458,7 @@ struct tvcard bttv_tvcards[] = { | |||
457 | .gpiomute = 0xc00, | 458 | .gpiomute = 0xc00, |
458 | .needs_tvaudio = 1, | 459 | .needs_tvaudio = 1, |
459 | .pll = PLL_28, | 460 | .pll = PLL_28, |
460 | .tuner_type = -1, | 461 | .tuner_type = UNSET, |
461 | .tuner_addr = ADDR_UNSET, | 462 | .tuner_addr = ADDR_UNSET, |
462 | .radio_addr = ADDR_UNSET, | 463 | .radio_addr = ADDR_UNSET, |
463 | }, | 464 | }, |
@@ -488,7 +489,7 @@ struct tvcard bttv_tvcards[] = { | |||
488 | .gpiomute = 4, | 489 | .gpiomute = 4, |
489 | .needs_tvaudio = 1, | 490 | .needs_tvaudio = 1, |
490 | .pll = PLL_28, | 491 | .pll = PLL_28, |
491 | .tuner_type = -1, | 492 | .tuner_type = UNSET, |
492 | .tuner_addr = ADDR_UNSET, | 493 | .tuner_addr = ADDR_UNSET, |
493 | .radio_addr = ADDR_UNSET, | 494 | .radio_addr = ADDR_UNSET, |
494 | }, | 495 | }, |
@@ -503,7 +504,7 @@ struct tvcard bttv_tvcards[] = { | |||
503 | .gpiomux = { 0x20001,0x10001, 0, 0 }, | 504 | .gpiomux = { 0x20001,0x10001, 0, 0 }, |
504 | .gpiomute = 10, | 505 | .gpiomute = 10, |
505 | .needs_tvaudio = 1, | 506 | .needs_tvaudio = 1, |
506 | .tuner_type = -1, | 507 | .tuner_type = UNSET, |
507 | .tuner_addr = ADDR_UNSET, | 508 | .tuner_addr = ADDR_UNSET, |
508 | .radio_addr = ADDR_UNSET, | 509 | .radio_addr = ADDR_UNSET, |
509 | }, | 510 | }, |
@@ -519,7 +520,7 @@ struct tvcard bttv_tvcards[] = { | |||
519 | .muxsel = { 2, 3, 1, 1 }, | 520 | .muxsel = { 2, 3, 1, 1 }, |
520 | .gpiomux = { 13, 14, 11, 7 }, | 521 | .gpiomux = { 13, 14, 11, 7 }, |
521 | .needs_tvaudio = 1, | 522 | .needs_tvaudio = 1, |
522 | .tuner_type = -1, | 523 | .tuner_type = UNSET, |
523 | .tuner_addr = ADDR_UNSET, | 524 | .tuner_addr = ADDR_UNSET, |
524 | .radio_addr = ADDR_UNSET, | 525 | .radio_addr = ADDR_UNSET, |
525 | }, | 526 | }, |
@@ -553,7 +554,7 @@ struct tvcard bttv_tvcards[] = { | |||
553 | .gpiomute = 4, | 554 | .gpiomute = 4, |
554 | .needs_tvaudio = 1, | 555 | .needs_tvaudio = 1, |
555 | .pll = PLL_28, | 556 | .pll = PLL_28, |
556 | .tuner_type = -1, | 557 | .tuner_type = UNSET, |
557 | .tuner_addr = ADDR_UNSET, | 558 | .tuner_addr = ADDR_UNSET, |
558 | .radio_addr = ADDR_UNSET, | 559 | .radio_addr = ADDR_UNSET, |
559 | }, | 560 | }, |
@@ -568,7 +569,7 @@ struct tvcard bttv_tvcards[] = { | |||
568 | .gpiomux = { 0, 0, 1, 0 }, | 569 | .gpiomux = { 0, 0, 1, 0 }, |
569 | .gpiomute = 10, | 570 | .gpiomute = 10, |
570 | .needs_tvaudio = 1, | 571 | .needs_tvaudio = 1, |
571 | .tuner_type = -1, | 572 | .tuner_type = UNSET, |
572 | .tuner_addr = ADDR_UNSET, | 573 | .tuner_addr = ADDR_UNSET, |
573 | .radio_addr = ADDR_UNSET, | 574 | .radio_addr = ADDR_UNSET, |
574 | }, | 575 | }, |
@@ -587,7 +588,7 @@ struct tvcard bttv_tvcards[] = { | |||
587 | .gpiomute = 0x002000, | 588 | .gpiomute = 0x002000, |
588 | .needs_tvaudio = 1, | 589 | .needs_tvaudio = 1, |
589 | .pll = PLL_28, | 590 | .pll = PLL_28, |
590 | .tuner_type = -1, | 591 | .tuner_type = UNSET, |
591 | }, | 592 | }, |
592 | [BTTV_BOARD_WINVIEW_601] = { | 593 | [BTTV_BOARD_WINVIEW_601] = { |
593 | .name = "Leadtek WinView 601", | 594 | .name = "Leadtek WinView 601", |
@@ -600,7 +601,7 @@ struct tvcard bttv_tvcards[] = { | |||
600 | .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, | 601 | .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, |
601 | .gpiomute = 0xcfa007, | 602 | .gpiomute = 0xcfa007, |
602 | .needs_tvaudio = 1, | 603 | .needs_tvaudio = 1, |
603 | .tuner_type = -1, | 604 | .tuner_type = UNSET, |
604 | .tuner_addr = ADDR_UNSET, | 605 | .tuner_addr = ADDR_UNSET, |
605 | .radio_addr = ADDR_UNSET, | 606 | .radio_addr = ADDR_UNSET, |
606 | .audio_hook = winview_audio, | 607 | .audio_hook = winview_audio, |
@@ -616,7 +617,7 @@ struct tvcard bttv_tvcards[] = { | |||
616 | .muxsel = { 2, 3, 1, 1 }, | 617 | .muxsel = { 2, 3, 1, 1 }, |
617 | .gpiomux = { 1, 0, 0, 0 }, | 618 | .gpiomux = { 1, 0, 0, 0 }, |
618 | .needs_tvaudio = 1, | 619 | .needs_tvaudio = 1, |
619 | .tuner_type = -1, | 620 | .tuner_type = UNSET, |
620 | .tuner_addr = ADDR_UNSET, | 621 | .tuner_addr = ADDR_UNSET, |
621 | .radio_addr = ADDR_UNSET, | 622 | .radio_addr = ADDR_UNSET, |
622 | }, | 623 | }, |
@@ -624,13 +625,13 @@ struct tvcard bttv_tvcards[] = { | |||
624 | .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", | 625 | .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", |
625 | .video_inputs = 4, | 626 | .video_inputs = 4, |
626 | .audio_inputs = 1, | 627 | .audio_inputs = 1, |
627 | .tuner = -1, | 628 | .tuner = UNSET, |
628 | .svhs = -1, | 629 | .svhs = UNSET, |
629 | .gpiomask = 0x8dff00, | 630 | .gpiomask = 0x8dff00, |
630 | .muxsel = { 2, 3, 1, 1 }, | 631 | .muxsel = { 2, 3, 1, 1 }, |
631 | .gpiomux = { 0 }, | 632 | .gpiomux = { 0 }, |
632 | .no_msp34xx = 1, | 633 | .no_msp34xx = 1, |
633 | .tuner_type = -1, | 634 | .tuner_type = UNSET, |
634 | .tuner_addr = ADDR_UNSET, | 635 | .tuner_addr = ADDR_UNSET, |
635 | .radio_addr = ADDR_UNSET, | 636 | .radio_addr = ADDR_UNSET, |
636 | }, | 637 | }, |
@@ -643,7 +644,7 @@ struct tvcard bttv_tvcards[] = { | |||
643 | .tuner = 0, | 644 | .tuner = 0, |
644 | .svhs = 2, | 645 | .svhs = 2, |
645 | .muxsel = { 2, 3, 1, 1 }, | 646 | .muxsel = { 2, 3, 1, 1 }, |
646 | .tuner_type = -1, | 647 | .tuner_type = UNSET, |
647 | .tuner_addr = ADDR_UNSET, | 648 | .tuner_addr = ADDR_UNSET, |
648 | .radio_addr = ADDR_UNSET, | 649 | .radio_addr = ADDR_UNSET, |
649 | }, | 650 | }, |
@@ -674,7 +675,7 @@ struct tvcard bttv_tvcards[] = { | |||
674 | .gpiomute = 0xc00, | 675 | .gpiomute = 0xc00, |
675 | .needs_tvaudio = 1, | 676 | .needs_tvaudio = 1, |
676 | .pll = PLL_28, | 677 | .pll = PLL_28, |
677 | .tuner_type = -1, | 678 | .tuner_type = UNSET, |
678 | .tuner_addr = ADDR_UNSET, | 679 | .tuner_addr = ADDR_UNSET, |
679 | .radio_addr = ADDR_UNSET, | 680 | .radio_addr = ADDR_UNSET, |
680 | }, | 681 | }, |
@@ -683,7 +684,7 @@ struct tvcard bttv_tvcards[] = { | |||
683 | .video_inputs = 3, | 684 | .video_inputs = 3, |
684 | .audio_inputs = 1, | 685 | .audio_inputs = 1, |
685 | .tuner = 0, | 686 | .tuner = 0, |
686 | .svhs = -1, | 687 | .svhs = UNSET, |
687 | .gpiomask = 7, | 688 | .gpiomask = 7, |
688 | .muxsel = { 2, 3, -1 }, | 689 | .muxsel = { 2, 3, -1 }, |
689 | .digital_mode = DIGITAL_MODE_CAMERA, | 690 | .digital_mode = DIGITAL_MODE_CAMERA, |
@@ -708,7 +709,7 @@ struct tvcard bttv_tvcards[] = { | |||
708 | .gpiomute = 0xc00, | 709 | .gpiomute = 0xc00, |
709 | .needs_tvaudio = 1, | 710 | .needs_tvaudio = 1, |
710 | .pll = PLL_28, | 711 | .pll = PLL_28, |
711 | .tuner_type = -1, | 712 | .tuner_type = UNSET, |
712 | .tuner_addr = ADDR_UNSET, | 713 | .tuner_addr = ADDR_UNSET, |
713 | .radio_addr = ADDR_UNSET, | 714 | .radio_addr = ADDR_UNSET, |
714 | .has_remote = 1, | 715 | .has_remote = 1, |
@@ -740,7 +741,7 @@ struct tvcard bttv_tvcards[] = { | |||
740 | .gpiomux = { 0, 1, 2, 3 }, | 741 | .gpiomux = { 0, 1, 2, 3 }, |
741 | .gpiomute = 4, | 742 | .gpiomute = 4, |
742 | .needs_tvaudio = 1, | 743 | .needs_tvaudio = 1, |
743 | .tuner_type = -1, | 744 | .tuner_type = UNSET, |
744 | .tuner_addr = ADDR_UNSET, | 745 | .tuner_addr = ADDR_UNSET, |
745 | .radio_addr = ADDR_UNSET, | 746 | .radio_addr = ADDR_UNSET, |
746 | }, | 747 | }, |
@@ -813,13 +814,13 @@ struct tvcard bttv_tvcards[] = { | |||
813 | .name = "Imagenation PXC200", | 814 | .name = "Imagenation PXC200", |
814 | .video_inputs = 5, | 815 | .video_inputs = 5, |
815 | .audio_inputs = 1, | 816 | .audio_inputs = 1, |
816 | .tuner = -1, | 817 | .tuner = UNSET, |
817 | .svhs = 1, /* was: 4 */ | 818 | .svhs = 1, /* was: 4 */ |
818 | .gpiomask = 0, | 819 | .gpiomask = 0, |
819 | .muxsel = { 2, 3, 1, 0, 0}, | 820 | .muxsel = { 2, 3, 1, 0, 0}, |
820 | .gpiomux = { 0 }, | 821 | .gpiomux = { 0 }, |
821 | .needs_tvaudio = 1, | 822 | .needs_tvaudio = 1, |
822 | .tuner_type = -1, | 823 | .tuner_type = UNSET, |
823 | .tuner_addr = ADDR_UNSET, | 824 | .tuner_addr = ADDR_UNSET, |
824 | .radio_addr = ADDR_UNSET, | 825 | .radio_addr = ADDR_UNSET, |
825 | .muxsel_hook = PXC200_muxsel, | 826 | .muxsel_hook = PXC200_muxsel, |
@@ -836,7 +837,7 @@ struct tvcard bttv_tvcards[] = { | |||
836 | .gpiomux = { 0, 0x0800, 0x1000, 0x1000 }, | 837 | .gpiomux = { 0, 0x0800, 0x1000, 0x1000 }, |
837 | .gpiomute = 0x1800, | 838 | .gpiomute = 0x1800, |
838 | .pll = PLL_28, | 839 | .pll = PLL_28, |
839 | .tuner_type = -1, | 840 | .tuner_type = UNSET, |
840 | .tuner_addr = ADDR_UNSET, | 841 | .tuner_addr = ADDR_UNSET, |
841 | .radio_addr = ADDR_UNSET, | 842 | .radio_addr = ADDR_UNSET, |
842 | }, | 843 | }, |
@@ -860,13 +861,13 @@ struct tvcard bttv_tvcards[] = { | |||
860 | .name = "Intel Create and Share PCI/ Smart Video Recorder III", | 861 | .name = "Intel Create and Share PCI/ Smart Video Recorder III", |
861 | .video_inputs = 4, | 862 | .video_inputs = 4, |
862 | .audio_inputs = 0, | 863 | .audio_inputs = 0, |
863 | .tuner = -1, | 864 | .tuner = UNSET, |
864 | .svhs = 2, | 865 | .svhs = 2, |
865 | .gpiomask = 0, | 866 | .gpiomask = 0, |
866 | .muxsel = { 2, 3, 1, 1 }, | 867 | .muxsel = { 2, 3, 1, 1 }, |
867 | .gpiomux = { 0 }, | 868 | .gpiomux = { 0 }, |
868 | .needs_tvaudio = 0, | 869 | .needs_tvaudio = 0, |
869 | .tuner_type = 4, | 870 | .tuner_type = TUNER_ABSENT, |
870 | .tuner_addr = ADDR_UNSET, | 871 | .tuner_addr = ADDR_UNSET, |
871 | .radio_addr = ADDR_UNSET, | 872 | .radio_addr = ADDR_UNSET, |
872 | }, | 873 | }, |
@@ -911,7 +912,7 @@ struct tvcard bttv_tvcards[] = { | |||
911 | .needs_tvaudio = 0, | 912 | .needs_tvaudio = 0, |
912 | .pll = PLL_28, | 913 | .pll = PLL_28, |
913 | .has_radio = 1, | 914 | .has_radio = 1, |
914 | .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */ | 915 | .tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */ |
915 | .tuner_addr = ADDR_UNSET, | 916 | .tuner_addr = ADDR_UNSET, |
916 | .radio_addr = ADDR_UNSET, | 917 | .radio_addr = ADDR_UNSET, |
917 | .audio_hook = winfast2000_audio, | 918 | .audio_hook = winfast2000_audio, |
@@ -928,7 +929,7 @@ struct tvcard bttv_tvcards[] = { | |||
928 | .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, | 929 | .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, |
929 | .gpiomute = 0x1800, | 930 | .gpiomute = 0x1800, |
930 | .pll = PLL_28, | 931 | .pll = PLL_28, |
931 | .tuner_type = -1, | 932 | .tuner_type = UNSET, |
932 | .tuner_addr = ADDR_UNSET, | 933 | .tuner_addr = ADDR_UNSET, |
933 | .radio_addr = ADDR_UNSET, | 934 | .radio_addr = ADDR_UNSET, |
934 | }, | 935 | }, |
@@ -945,7 +946,7 @@ struct tvcard bttv_tvcards[] = { | |||
945 | .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, | 946 | .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, |
946 | .gpiomute = 0x1800, | 947 | .gpiomute = 0x1800, |
947 | .pll = PLL_28, | 948 | .pll = PLL_28, |
948 | .tuner_type = -1, | 949 | .tuner_type = UNSET, |
949 | .tuner_addr = ADDR_UNSET, | 950 | .tuner_addr = ADDR_UNSET, |
950 | .radio_addr = ADDR_UNSET, | 951 | .radio_addr = ADDR_UNSET, |
951 | .has_radio = 1, | 952 | .has_radio = 1, |
@@ -962,7 +963,7 @@ struct tvcard bttv_tvcards[] = { | |||
962 | .gpiomute = 0x29, | 963 | .gpiomute = 0x29, |
963 | .no_msp34xx = 1, | 964 | .no_msp34xx = 1, |
964 | .pll = PLL_28, | 965 | .pll = PLL_28, |
965 | .tuner_type = -1, | 966 | .tuner_type = UNSET, |
966 | .tuner_addr = ADDR_UNSET, | 967 | .tuner_addr = ADDR_UNSET, |
967 | .radio_addr = ADDR_UNSET, | 968 | .radio_addr = ADDR_UNSET, |
968 | }, | 969 | }, |
@@ -978,7 +979,7 @@ struct tvcard bttv_tvcards[] = { | |||
978 | .gpiomute = 0x551c00, | 979 | .gpiomute = 0x551c00, |
979 | .needs_tvaudio = 1, | 980 | .needs_tvaudio = 1, |
980 | .pll = PLL_28, | 981 | .pll = PLL_28, |
981 | .tuner_type = 1, | 982 | .tuner_type = TUNER_PHILIPS_PAL_I, |
982 | .tuner_addr = ADDR_UNSET, | 983 | .tuner_addr = ADDR_UNSET, |
983 | .radio_addr = ADDR_UNSET, | 984 | .radio_addr = ADDR_UNSET, |
984 | .has_remote = 1, | 985 | .has_remote = 1, |
@@ -995,7 +996,7 @@ struct tvcard bttv_tvcards[] = { | |||
995 | .gpiomute = 1, | 996 | .gpiomute = 1, |
996 | .needs_tvaudio = 0, | 997 | .needs_tvaudio = 0, |
997 | .pll = PLL_28, | 998 | .pll = PLL_28, |
998 | .tuner_type = -1, | 999 | .tuner_type = UNSET, |
999 | .tuner_addr = ADDR_UNSET, | 1000 | .tuner_addr = ADDR_UNSET, |
1000 | .radio_addr = ADDR_UNSET, | 1001 | .radio_addr = ADDR_UNSET, |
1001 | }, | 1002 | }, |
@@ -1030,7 +1031,7 @@ struct tvcard bttv_tvcards[] = { | |||
1030 | .gpiomux = { 13, 4, 11, 7 }, | 1031 | .gpiomux = { 13, 4, 11, 7 }, |
1031 | .needs_tvaudio = 1, | 1032 | .needs_tvaudio = 1, |
1032 | .pll = PLL_28, | 1033 | .pll = PLL_28, |
1033 | .tuner_type = -1, | 1034 | .tuner_type = UNSET, |
1034 | .tuner_addr = ADDR_UNSET, | 1035 | .tuner_addr = ADDR_UNSET, |
1035 | .radio_addr = ADDR_UNSET, | 1036 | .radio_addr = ADDR_UNSET, |
1036 | .has_radio = 1, | 1037 | .has_radio = 1, |
@@ -1048,7 +1049,7 @@ struct tvcard bttv_tvcards[] = { | |||
1048 | .needs_tvaudio = 1, | 1049 | .needs_tvaudio = 1, |
1049 | .no_msp34xx = 1, | 1050 | .no_msp34xx = 1, |
1050 | .pll = PLL_28, | 1051 | .pll = PLL_28, |
1051 | .tuner_type = 1, | 1052 | .tuner_type = TUNER_PHILIPS_PAL_I, |
1052 | .tuner_addr = ADDR_UNSET, | 1053 | .tuner_addr = ADDR_UNSET, |
1053 | .radio_addr = ADDR_UNSET, | 1054 | .radio_addr = ADDR_UNSET, |
1054 | }, | 1055 | }, |
@@ -1063,7 +1064,7 @@ struct tvcard bttv_tvcards[] = { | |||
1063 | .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 }, | 1064 | .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 }, |
1064 | .gpiomute = 0xff3ffc, | 1065 | .gpiomute = 0xff3ffc, |
1065 | .no_msp34xx = 1, | 1066 | .no_msp34xx = 1, |
1066 | .tuner_type = -1, | 1067 | .tuner_type = UNSET, |
1067 | .tuner_addr = ADDR_UNSET, | 1068 | .tuner_addr = ADDR_UNSET, |
1068 | .radio_addr = ADDR_UNSET, | 1069 | .radio_addr = ADDR_UNSET, |
1069 | }, | 1070 | }, |
@@ -1074,14 +1075,14 @@ struct tvcard bttv_tvcards[] = { | |||
1074 | .video_inputs = 2, | 1075 | .video_inputs = 2, |
1075 | .audio_inputs = 1, | 1076 | .audio_inputs = 1, |
1076 | .tuner = 0, | 1077 | .tuner = 0, |
1077 | .svhs = -1, | 1078 | .svhs = UNSET, |
1078 | .gpiomask = 3, | 1079 | .gpiomask = 3, |
1079 | .muxsel = { 2, 3, 1, 1 }, | 1080 | .muxsel = { 2, 3, 1, 1 }, |
1080 | .gpiomux = { 1, 1, 0, 2 }, | 1081 | .gpiomux = { 1, 1, 0, 2 }, |
1081 | .gpiomute = 3, | 1082 | .gpiomute = 3, |
1082 | .no_msp34xx = 1, | 1083 | .no_msp34xx = 1, |
1083 | .pll = PLL_NONE, | 1084 | .pll = PLL_NONE, |
1084 | .tuner_type = -1, | 1085 | .tuner_type = UNSET, |
1085 | .tuner_addr = ADDR_UNSET, | 1086 | .tuner_addr = ADDR_UNSET, |
1086 | .radio_addr = ADDR_UNSET, | 1087 | .radio_addr = ADDR_UNSET, |
1087 | }, | 1088 | }, |
@@ -1089,14 +1090,14 @@ struct tvcard bttv_tvcards[] = { | |||
1089 | .name = "MATRIX-Vision MV-Delta 2", | 1090 | .name = "MATRIX-Vision MV-Delta 2", |
1090 | .video_inputs = 5, | 1091 | .video_inputs = 5, |
1091 | .audio_inputs = 1, | 1092 | .audio_inputs = 1, |
1092 | .tuner = -1, | 1093 | .tuner = UNSET, |
1093 | .svhs = 3, | 1094 | .svhs = 3, |
1094 | .gpiomask = 0, | 1095 | .gpiomask = 0, |
1095 | .muxsel = { 2, 3, 1, 0, 0 }, | 1096 | .muxsel = { 2, 3, 1, 0, 0 }, |
1096 | .gpiomux = { 0 }, | 1097 | .gpiomux = { 0 }, |
1097 | .no_msp34xx = 1, | 1098 | .no_msp34xx = 1, |
1098 | .pll = PLL_28, | 1099 | .pll = PLL_28, |
1099 | .tuner_type = -1, | 1100 | .tuner_type = UNSET, |
1100 | .tuner_addr = ADDR_UNSET, | 1101 | .tuner_addr = ADDR_UNSET, |
1101 | .radio_addr = ADDR_UNSET, | 1102 | .radio_addr = ADDR_UNSET, |
1102 | }, | 1103 | }, |
@@ -1112,7 +1113,7 @@ struct tvcard bttv_tvcards[] = { | |||
1112 | .gpiomute = 0xbcb03f, | 1113 | .gpiomute = 0xbcb03f, |
1113 | .no_msp34xx = 1, | 1114 | .no_msp34xx = 1, |
1114 | .pll = PLL_28, | 1115 | .pll = PLL_28, |
1115 | .tuner_type = 21, | 1116 | .tuner_type = TUNER_TEMIC_4039FR5_NTSC, |
1116 | .tuner_addr = ADDR_UNSET, | 1117 | .tuner_addr = ADDR_UNSET, |
1117 | .radio_addr = ADDR_UNSET, | 1118 | .radio_addr = ADDR_UNSET, |
1118 | }, | 1119 | }, |
@@ -1129,7 +1130,7 @@ struct tvcard bttv_tvcards[] = { | |||
1129 | .needs_tvaudio = 1, | 1130 | .needs_tvaudio = 1, |
1130 | .no_msp34xx = 1, | 1131 | .no_msp34xx = 1, |
1131 | .pll = PLL_35, | 1132 | .pll = PLL_35, |
1132 | .tuner_type = 1, | 1133 | .tuner_type = TUNER_PHILIPS_PAL_I, |
1133 | .tuner_addr = ADDR_UNSET, | 1134 | .tuner_addr = ADDR_UNSET, |
1134 | .radio_addr = ADDR_UNSET, | 1135 | .radio_addr = ADDR_UNSET, |
1135 | .has_radio = 1, | 1136 | .has_radio = 1, |
@@ -1148,7 +1149,7 @@ struct tvcard bttv_tvcards[] = { | |||
1148 | .gpiomute = 1, | 1149 | .gpiomute = 1, |
1149 | .needs_tvaudio = 1, | 1150 | .needs_tvaudio = 1, |
1150 | .pll = PLL_28, | 1151 | .pll = PLL_28, |
1151 | .tuner_type = -1, | 1152 | .tuner_type = UNSET, |
1152 | .tuner_addr = ADDR_UNSET, | 1153 | .tuner_addr = ADDR_UNSET, |
1153 | .radio_addr = ADDR_UNSET, | 1154 | .radio_addr = ADDR_UNSET, |
1154 | }, | 1155 | }, |
@@ -1206,7 +1207,7 @@ struct tvcard bttv_tvcards[] = { | |||
1206 | .gpiomux = { 0, 1, 2, 3 }, | 1207 | .gpiomux = { 0, 1, 2, 3 }, |
1207 | .gpiomute = 4, | 1208 | .gpiomute = 4, |
1208 | .pll = PLL_28, | 1209 | .pll = PLL_28, |
1209 | .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */, | 1210 | .tuner_type = UNSET /* TUNER_ALPS_TMDH2_NTSC */, |
1210 | .tuner_addr = ADDR_UNSET, | 1211 | .tuner_addr = ADDR_UNSET, |
1211 | .radio_addr = ADDR_UNSET, | 1212 | .radio_addr = ADDR_UNSET, |
1212 | }, | 1213 | }, |
@@ -1234,7 +1235,7 @@ struct tvcard bttv_tvcards[] = { | |||
1234 | 1= FM stereo Radio from Tuner */ | 1235 | 1= FM stereo Radio from Tuner */ |
1235 | .needs_tvaudio = 0, | 1236 | .needs_tvaudio = 0, |
1236 | .pll = PLL_28, | 1237 | .pll = PLL_28, |
1237 | .tuner_type = -1, | 1238 | .tuner_type = UNSET, |
1238 | .tuner_addr = ADDR_UNSET, | 1239 | .tuner_addr = ADDR_UNSET, |
1239 | .radio_addr = ADDR_UNSET, | 1240 | .radio_addr = ADDR_UNSET, |
1240 | }, | 1241 | }, |
@@ -1277,7 +1278,7 @@ struct tvcard bttv_tvcards[] = { | |||
1277 | 0x0080: Tuner A2 SAP (second audio program = Zweikanalton) | 1278 | 0x0080: Tuner A2 SAP (second audio program = Zweikanalton) |
1278 | 0x0880: Tuner A2 stereo */ | 1279 | 0x0880: Tuner A2 stereo */ |
1279 | .pll = PLL_28, | 1280 | .pll = PLL_28, |
1280 | .tuner_type = -1, | 1281 | .tuner_type = UNSET, |
1281 | .tuner_addr = ADDR_UNSET, | 1282 | .tuner_addr = ADDR_UNSET, |
1282 | .radio_addr = ADDR_UNSET, | 1283 | .radio_addr = ADDR_UNSET, |
1283 | }, | 1284 | }, |
@@ -1313,7 +1314,7 @@ struct tvcard bttv_tvcards[] = { | |||
1313 | .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, | 1314 | .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, |
1314 | .gpiomute = 0x1800, | 1315 | .gpiomute = 0x1800, |
1315 | .pll = PLL_28, | 1316 | .pll = PLL_28, |
1316 | .tuner_type = 5, | 1317 | .tuner_type = TUNER_PHILIPS_PAL, |
1317 | .tuner_addr = ADDR_UNSET, | 1318 | .tuner_addr = ADDR_UNSET, |
1318 | .radio_addr = ADDR_UNSET, | 1319 | .radio_addr = ADDR_UNSET, |
1319 | }, | 1320 | }, |
@@ -1324,7 +1325,7 @@ struct tvcard bttv_tvcards[] = { | |||
1324 | .name = "GrandTec 'Grand Video Capture' (Bt848)", | 1325 | .name = "GrandTec 'Grand Video Capture' (Bt848)", |
1325 | .video_inputs = 2, | 1326 | .video_inputs = 2, |
1326 | .audio_inputs = 0, | 1327 | .audio_inputs = 0, |
1327 | .tuner = -1, | 1328 | .tuner = UNSET, |
1328 | .svhs = 1, | 1329 | .svhs = 1, |
1329 | .gpiomask = 0, | 1330 | .gpiomask = 0, |
1330 | .muxsel = { 3, 1 }, | 1331 | .muxsel = { 3, 1 }, |
@@ -1332,7 +1333,7 @@ struct tvcard bttv_tvcards[] = { | |||
1332 | .needs_tvaudio = 0, | 1333 | .needs_tvaudio = 0, |
1333 | .no_msp34xx = 1, | 1334 | .no_msp34xx = 1, |
1334 | .pll = PLL_35, | 1335 | .pll = PLL_35, |
1335 | .tuner_type = -1, | 1336 | .tuner_type = UNSET, |
1336 | .tuner_addr = ADDR_UNSET, | 1337 | .tuner_addr = ADDR_UNSET, |
1337 | .radio_addr = ADDR_UNSET, | 1338 | .radio_addr = ADDR_UNSET, |
1338 | }, | 1339 | }, |
@@ -1365,7 +1366,7 @@ struct tvcard bttv_tvcards[] = { | |||
1365 | .gpiomux = { 2, 0, 0, 0 }, | 1366 | .gpiomux = { 2, 0, 0, 0 }, |
1366 | .gpiomute = 1, | 1367 | .gpiomute = 1, |
1367 | .pll = PLL_28, | 1368 | .pll = PLL_28, |
1368 | .tuner_type = 0, | 1369 | .tuner_type = TUNER_TEMIC_PAL, |
1369 | .tuner_addr = ADDR_UNSET, | 1370 | .tuner_addr = ADDR_UNSET, |
1370 | .radio_addr = ADDR_UNSET, | 1371 | .radio_addr = ADDR_UNSET, |
1371 | }, | 1372 | }, |
@@ -1377,7 +1378,7 @@ struct tvcard bttv_tvcards[] = { | |||
1377 | .video_inputs = 2, | 1378 | .video_inputs = 2, |
1378 | .audio_inputs = 2, | 1379 | .audio_inputs = 2, |
1379 | .tuner = 0, | 1380 | .tuner = 0, |
1380 | .svhs = -1, | 1381 | .svhs = UNSET, |
1381 | .gpiomask = 11, | 1382 | .gpiomask = 11, |
1382 | .muxsel = { 2, 3, 1, 1 }, | 1383 | .muxsel = { 2, 3, 1, 1 }, |
1383 | .gpiomux = { 2, 0, 0, 1 }, | 1384 | .gpiomux = { 2, 0, 0, 1 }, |
@@ -1392,7 +1393,7 @@ struct tvcard bttv_tvcards[] = { | |||
1392 | .name = "AG Electronics GMV1", | 1393 | .name = "AG Electronics GMV1", |
1393 | .video_inputs = 2, | 1394 | .video_inputs = 2, |
1394 | .audio_inputs = 0, | 1395 | .audio_inputs = 0, |
1395 | .tuner = -1, | 1396 | .tuner = UNSET, |
1396 | .svhs = 1, | 1397 | .svhs = 1, |
1397 | .gpiomask = 0xF, | 1398 | .gpiomask = 0xF, |
1398 | .muxsel = { 2, 2 }, | 1399 | .muxsel = { 2, 2 }, |
@@ -1400,7 +1401,7 @@ struct tvcard bttv_tvcards[] = { | |||
1400 | .no_msp34xx = 1, | 1401 | .no_msp34xx = 1, |
1401 | .needs_tvaudio = 0, | 1402 | .needs_tvaudio = 0, |
1402 | .pll = PLL_28, | 1403 | .pll = PLL_28, |
1403 | .tuner_type = -1, | 1404 | .tuner_type = UNSET, |
1404 | .tuner_addr = ADDR_UNSET, | 1405 | .tuner_addr = ADDR_UNSET, |
1405 | .radio_addr = ADDR_UNSET, | 1406 | .radio_addr = ADDR_UNSET, |
1406 | }, | 1407 | }, |
@@ -1447,7 +1448,7 @@ struct tvcard bttv_tvcards[] = { | |||
1447 | .video_inputs = 2, | 1448 | .video_inputs = 2, |
1448 | .audio_inputs = 1, | 1449 | .audio_inputs = 1, |
1449 | .tuner = 0, | 1450 | .tuner = 0, |
1450 | .svhs = -1, | 1451 | .svhs = UNSET, |
1451 | .gpiomask = 1, | 1452 | .gpiomask = 1, |
1452 | .muxsel = { 2, 3, 0, 1 }, | 1453 | .muxsel = { 2, 3, 0, 1 }, |
1453 | .gpiomux = { 0, 0, 1, 0 }, | 1454 | .gpiomux = { 0, 0, 1, 0 }, |
@@ -1476,7 +1477,7 @@ struct tvcard bttv_tvcards[] = { | |||
1476 | .no_tda9875 = 1, | 1477 | .no_tda9875 = 1, |
1477 | .needs_tvaudio = 1, | 1478 | .needs_tvaudio = 1, |
1478 | .pll = PLL_28, | 1479 | .pll = PLL_28, |
1479 | .tuner_type = 5, | 1480 | .tuner_type = TUNER_PHILIPS_PAL, |
1480 | .tuner_addr = ADDR_UNSET, | 1481 | .tuner_addr = ADDR_UNSET, |
1481 | .radio_addr = ADDR_UNSET, | 1482 | .radio_addr = ADDR_UNSET, |
1482 | }, | 1483 | }, |
@@ -1517,13 +1518,35 @@ struct tvcard bttv_tvcards[] = { | |||
1517 | 1518 | ||
1518 | /* ---- card 0x44 ---------------------------------- */ | 1519 | /* ---- card 0x44 ---------------------------------- */ |
1519 | [BTTV_BOARD_VOODOOTV_FM] = { | 1520 | [BTTV_BOARD_VOODOOTV_FM] = { |
1520 | .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)", | 1521 | .name = "3Dfx VoodooTV FM (Euro)", |
1522 | /* try "insmod msp3400 simple=0" if you have | ||
1523 | * sound problems with this card. */ | ||
1524 | .video_inputs = 4, | ||
1525 | .audio_inputs = 1, | ||
1526 | .tuner = 0, | ||
1527 | .svhs = UNSET, | ||
1528 | .gpiomask = 0x4f8a00, | ||
1529 | /* 0x100000: 1=MSP enabled (0=disable again) | ||
1530 | * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ | ||
1531 | .gpiomux = {0x947fff, 0x987fff,0x947fff,0x947fff }, | ||
1532 | .gpiomute = 0x947fff, | ||
1533 | /* tvtuner, radio, external,internal, mute, stereo | ||
1534 | * tuner, Composit, SVid, Composit-on-Svid-adapter */ | ||
1535 | .muxsel = { 2, 3 ,0 ,1 }, | ||
1536 | .tuner_type = TUNER_MT2032, | ||
1537 | .tuner_addr = ADDR_UNSET, | ||
1538 | .radio_addr = ADDR_UNSET, | ||
1539 | .pll = PLL_28, | ||
1540 | .has_radio = 1, | ||
1541 | }, | ||
1542 | [BTTV_BOARD_VOODOOTV_200] = { | ||
1543 | .name = "VoodooTV 200 (USA)", | ||
1521 | /* try "insmod msp3400 simple=0" if you have | 1544 | /* try "insmod msp3400 simple=0" if you have |
1522 | * sound problems with this card. */ | 1545 | * sound problems with this card. */ |
1523 | .video_inputs = 4, | 1546 | .video_inputs = 4, |
1524 | .audio_inputs = 1, | 1547 | .audio_inputs = 1, |
1525 | .tuner = 0, | 1548 | .tuner = 0, |
1526 | .svhs = -1, | 1549 | .svhs = UNSET, |
1527 | .gpiomask = 0x4f8a00, | 1550 | .gpiomask = 0x4f8a00, |
1528 | /* 0x100000: 1=MSP enabled (0=disable again) | 1551 | /* 0x100000: 1=MSP enabled (0=disable again) |
1529 | * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ | 1552 | * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ |
@@ -1543,8 +1566,8 @@ struct tvcard bttv_tvcards[] = { | |||
1543 | .name = "Active Imaging AIMMS", | 1566 | .name = "Active Imaging AIMMS", |
1544 | .video_inputs = 1, | 1567 | .video_inputs = 1, |
1545 | .audio_inputs = 0, | 1568 | .audio_inputs = 0, |
1546 | .tuner = -1, | 1569 | .tuner = UNSET, |
1547 | .tuner_type = -1, | 1570 | .tuner_type = UNSET, |
1548 | .tuner_addr = ADDR_UNSET, | 1571 | .tuner_addr = ADDR_UNSET, |
1549 | .radio_addr = ADDR_UNSET, | 1572 | .radio_addr = ADDR_UNSET, |
1550 | .pll = PLL_28, | 1573 | .pll = PLL_28, |
@@ -1564,7 +1587,7 @@ struct tvcard bttv_tvcards[] = { | |||
1564 | .gpiomute = 13, | 1587 | .gpiomute = 13, |
1565 | .needs_tvaudio = 1, | 1588 | .needs_tvaudio = 1, |
1566 | .pll = PLL_28, | 1589 | .pll = PLL_28, |
1567 | .tuner_type = 25, | 1590 | .tuner_type = TUNER_LG_PAL_I_FM, |
1568 | .tuner_addr = ADDR_UNSET, | 1591 | .tuner_addr = ADDR_UNSET, |
1569 | .radio_addr = ADDR_UNSET, | 1592 | .radio_addr = ADDR_UNSET, |
1570 | .has_remote = 1, | 1593 | .has_remote = 1, |
@@ -1580,7 +1603,7 @@ struct tvcard bttv_tvcards[] = { | |||
1580 | .name = "Lifeview FlyVideo 98EZ (capture only) LR51", | 1603 | .name = "Lifeview FlyVideo 98EZ (capture only) LR51", |
1581 | .video_inputs = 4, | 1604 | .video_inputs = 4, |
1582 | .audio_inputs = 0, | 1605 | .audio_inputs = 0, |
1583 | .tuner = -1, | 1606 | .tuner = UNSET, |
1584 | .svhs = 2, | 1607 | .svhs = 2, |
1585 | .muxsel = { 2, 3, 1, 1 }, /* AV1, AV2, SVHS, CVid adapter on SVHS */ | 1608 | .muxsel = { 2, 3, 1, 1 }, /* AV1, AV2, SVHS, CVid adapter on SVHS */ |
1586 | .pll = PLL_28, | 1609 | .pll = PLL_28, |
@@ -1606,7 +1629,7 @@ struct tvcard bttv_tvcards[] = { | |||
1606 | .no_msp34xx = 1, | 1629 | .no_msp34xx = 1, |
1607 | .no_tda9875 = 1, | 1630 | .no_tda9875 = 1, |
1608 | .pll = PLL_28, | 1631 | .pll = PLL_28, |
1609 | .tuner_type = 5, | 1632 | .tuner_type = TUNER_PHILIPS_PAL, |
1610 | .tuner_addr = ADDR_UNSET, | 1633 | .tuner_addr = ADDR_UNSET, |
1611 | .radio_addr = ADDR_UNSET, | 1634 | .radio_addr = ADDR_UNSET, |
1612 | .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */ | 1635 | .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */ |
@@ -1626,13 +1649,13 @@ struct tvcard bttv_tvcards[] = { | |||
1626 | .name = "Sensoray 311", | 1649 | .name = "Sensoray 311", |
1627 | .video_inputs = 5, | 1650 | .video_inputs = 5, |
1628 | .audio_inputs = 0, | 1651 | .audio_inputs = 0, |
1629 | .tuner = -1, | 1652 | .tuner = UNSET, |
1630 | .svhs = 4, | 1653 | .svhs = 4, |
1631 | .gpiomask = 0, | 1654 | .gpiomask = 0, |
1632 | .muxsel = { 2, 3, 1, 0, 0 }, | 1655 | .muxsel = { 2, 3, 1, 0, 0 }, |
1633 | .gpiomux = { 0 }, | 1656 | .gpiomux = { 0 }, |
1634 | .needs_tvaudio = 0, | 1657 | .needs_tvaudio = 0, |
1635 | .tuner_type = -1, | 1658 | .tuner_type = UNSET, |
1636 | .tuner_addr = ADDR_UNSET, | 1659 | .tuner_addr = ADDR_UNSET, |
1637 | .radio_addr = ADDR_UNSET, | 1660 | .radio_addr = ADDR_UNSET, |
1638 | }, | 1661 | }, |
@@ -1641,15 +1664,15 @@ struct tvcard bttv_tvcards[] = { | |||
1641 | .name = "RemoteVision MX (RV605)", | 1664 | .name = "RemoteVision MX (RV605)", |
1642 | .video_inputs = 16, | 1665 | .video_inputs = 16, |
1643 | .audio_inputs = 0, | 1666 | .audio_inputs = 0, |
1644 | .tuner = -1, | 1667 | .tuner = UNSET, |
1645 | .svhs = -1, | 1668 | .svhs = UNSET, |
1646 | .gpiomask = 0x00, | 1669 | .gpiomask = 0x00, |
1647 | .gpiomask2 = 0x07ff, | 1670 | .gpiomask2 = 0x07ff, |
1648 | .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, | 1671 | .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, |
1649 | 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, | 1672 | 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, |
1650 | .no_msp34xx = 1, | 1673 | .no_msp34xx = 1, |
1651 | .no_tda9875 = 1, | 1674 | .no_tda9875 = 1, |
1652 | .tuner_type = -1, | 1675 | .tuner_type = UNSET, |
1653 | .tuner_addr = ADDR_UNSET, | 1676 | .tuner_addr = ADDR_UNSET, |
1654 | .radio_addr = ADDR_UNSET, | 1677 | .radio_addr = ADDR_UNSET, |
1655 | .muxsel_hook = rv605_muxsel, | 1678 | .muxsel_hook = rv605_muxsel, |
@@ -1693,15 +1716,15 @@ struct tvcard bttv_tvcards[] = { | |||
1693 | .name = "GrandTec Multi Capture Card (Bt878)", | 1716 | .name = "GrandTec Multi Capture Card (Bt878)", |
1694 | .video_inputs = 4, | 1717 | .video_inputs = 4, |
1695 | .audio_inputs = 0, | 1718 | .audio_inputs = 0, |
1696 | .tuner = -1, | 1719 | .tuner = UNSET, |
1697 | .svhs = -1, | 1720 | .svhs = UNSET, |
1698 | .gpiomask = 0, | 1721 | .gpiomask = 0, |
1699 | .muxsel = { 2, 3, 1, 0 }, | 1722 | .muxsel = { 2, 3, 1, 0 }, |
1700 | .gpiomux = { 0 }, | 1723 | .gpiomux = { 0 }, |
1701 | .needs_tvaudio = 0, | 1724 | .needs_tvaudio = 0, |
1702 | .no_msp34xx = 1, | 1725 | .no_msp34xx = 1, |
1703 | .pll = PLL_28, | 1726 | .pll = PLL_28, |
1704 | .tuner_type = -1, | 1727 | .tuner_type = UNSET, |
1705 | .tuner_addr = ADDR_UNSET, | 1728 | .tuner_addr = ADDR_UNSET, |
1706 | .radio_addr = ADDR_UNSET, | 1729 | .radio_addr = ADDR_UNSET, |
1707 | }, | 1730 | }, |
@@ -1724,7 +1747,7 @@ struct tvcard bttv_tvcards[] = { | |||
1724 | .needs_tvaudio = 0, | 1747 | .needs_tvaudio = 0, |
1725 | .no_msp34xx = 1, | 1748 | .no_msp34xx = 1, |
1726 | .pll = PLL_28, | 1749 | .pll = PLL_28, |
1727 | .tuner_type = 5, | 1750 | .tuner_type = TUNER_PHILIPS_PAL, |
1728 | .tuner_addr = ADDR_UNSET, | 1751 | .tuner_addr = ADDR_UNSET, |
1729 | .radio_addr = ADDR_UNSET, | 1752 | .radio_addr = ADDR_UNSET, |
1730 | /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and | 1753 | /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and |
@@ -1744,10 +1767,10 @@ struct tvcard bttv_tvcards[] = { | |||
1744 | /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */ | 1767 | /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */ |
1745 | .name = "DSP Design TCVIDEO", | 1768 | .name = "DSP Design TCVIDEO", |
1746 | .video_inputs = 4, | 1769 | .video_inputs = 4, |
1747 | .svhs = -1, | 1770 | .svhs = UNSET, |
1748 | .muxsel = { 2, 3, 1, 0 }, | 1771 | .muxsel = { 2, 3, 1, 0 }, |
1749 | .pll = PLL_28, | 1772 | .pll = PLL_28, |
1750 | .tuner_type = -1, | 1773 | .tuner_type = UNSET, |
1751 | .tuner_addr = ADDR_UNSET, | 1774 | .tuner_addr = ADDR_UNSET, |
1752 | .radio_addr = ADDR_UNSET, | 1775 | .radio_addr = ADDR_UNSET, |
1753 | }, | 1776 | }, |
@@ -1762,7 +1785,7 @@ struct tvcard bttv_tvcards[] = { | |||
1762 | .muxsel = { 2, 0, 1, 1 }, | 1785 | .muxsel = { 2, 0, 1, 1 }, |
1763 | .needs_tvaudio = 1, | 1786 | .needs_tvaudio = 1, |
1764 | .pll = PLL_28, | 1787 | .pll = PLL_28, |
1765 | .tuner_type = -1, | 1788 | .tuner_type = UNSET, |
1766 | .tuner_addr = ADDR_UNSET, | 1789 | .tuner_addr = ADDR_UNSET, |
1767 | .radio_addr = ADDR_UNSET, | 1790 | .radio_addr = ADDR_UNSET, |
1768 | 1791 | ||
@@ -1791,11 +1814,11 @@ struct tvcard bttv_tvcards[] = { | |||
1791 | .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ | 1814 | .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ |
1792 | .video_inputs = 4, /* id-inputs-clock */ | 1815 | .video_inputs = 4, /* id-inputs-clock */ |
1793 | .audio_inputs = 0, | 1816 | .audio_inputs = 0, |
1794 | .tuner = -1, | 1817 | .tuner = UNSET, |
1795 | .svhs = 3, | 1818 | .svhs = 3, |
1796 | .muxsel = { 3, 2, 0, 1 }, | 1819 | .muxsel = { 3, 2, 0, 1 }, |
1797 | .pll = PLL_28, | 1820 | .pll = PLL_28, |
1798 | .tuner_type = -1, | 1821 | .tuner_type = UNSET, |
1799 | .tuner_addr = ADDR_UNSET, | 1822 | .tuner_addr = ADDR_UNSET, |
1800 | .radio_addr = ADDR_UNSET, | 1823 | .radio_addr = ADDR_UNSET, |
1801 | .no_msp34xx = 1, | 1824 | .no_msp34xx = 1, |
@@ -1806,11 +1829,11 @@ struct tvcard bttv_tvcards[] = { | |||
1806 | .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ | 1829 | .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ |
1807 | .video_inputs = 3, | 1830 | .video_inputs = 3, |
1808 | .audio_inputs = 0, | 1831 | .audio_inputs = 0, |
1809 | .tuner = -1, | 1832 | .tuner = UNSET, |
1810 | .svhs = 2, | 1833 | .svhs = 2, |
1811 | .muxsel = { 2, 3, 1 }, | 1834 | .muxsel = { 2, 3, 1 }, |
1812 | .pll = PLL_28, | 1835 | .pll = PLL_28, |
1813 | .tuner_type = -1, | 1836 | .tuner_type = UNSET, |
1814 | .tuner_addr = ADDR_UNSET, | 1837 | .tuner_addr = ADDR_UNSET, |
1815 | .radio_addr = ADDR_UNSET, | 1838 | .radio_addr = ADDR_UNSET, |
1816 | .no_msp34xx = 1, | 1839 | .no_msp34xx = 1, |
@@ -1823,11 +1846,11 @@ struct tvcard bttv_tvcards[] = { | |||
1823 | .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ | 1846 | .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ |
1824 | .video_inputs = 2, | 1847 | .video_inputs = 2, |
1825 | .audio_inputs = 0, | 1848 | .audio_inputs = 0, |
1826 | .tuner = -1, | 1849 | .tuner = UNSET, |
1827 | .svhs = 1, | 1850 | .svhs = 1, |
1828 | .muxsel = { 3, 1 }, | 1851 | .muxsel = { 3, 1 }, |
1829 | .pll = PLL_28, | 1852 | .pll = PLL_28, |
1830 | .tuner_type = -1, | 1853 | .tuner_type = UNSET, |
1831 | .tuner_addr = ADDR_UNSET, | 1854 | .tuner_addr = ADDR_UNSET, |
1832 | .radio_addr = ADDR_UNSET, | 1855 | .radio_addr = ADDR_UNSET, |
1833 | .no_msp34xx = 1, | 1856 | .no_msp34xx = 1, |
@@ -1838,11 +1861,11 @@ struct tvcard bttv_tvcards[] = { | |||
1838 | .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ | 1861 | .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ |
1839 | .video_inputs = 1, | 1862 | .video_inputs = 1, |
1840 | .audio_inputs = 0, | 1863 | .audio_inputs = 0, |
1841 | .tuner = -1, | 1864 | .tuner = UNSET, |
1842 | .svhs = -1, | 1865 | .svhs = UNSET, |
1843 | .muxsel = { 0 }, | 1866 | .muxsel = { 0 }, |
1844 | .pll = PLL_28, | 1867 | .pll = PLL_28, |
1845 | .tuner_type = -1, | 1868 | .tuner_type = UNSET, |
1846 | .tuner_addr = ADDR_UNSET, | 1869 | .tuner_addr = ADDR_UNSET, |
1847 | .radio_addr = ADDR_UNSET, | 1870 | .radio_addr = ADDR_UNSET, |
1848 | .no_msp34xx = 1, | 1871 | .no_msp34xx = 1, |
@@ -1853,11 +1876,11 @@ struct tvcard bttv_tvcards[] = { | |||
1853 | .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ | 1876 | .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ |
1854 | .video_inputs = 2, | 1877 | .video_inputs = 2, |
1855 | .audio_inputs = 0, | 1878 | .audio_inputs = 0, |
1856 | .tuner = -1, | 1879 | .tuner = UNSET, |
1857 | .svhs = 1, | 1880 | .svhs = 1, |
1858 | .muxsel = { 0, 1 }, | 1881 | .muxsel = { 0, 1 }, |
1859 | .pll = PLL_28, | 1882 | .pll = PLL_28, |
1860 | .tuner_type = -1, | 1883 | .tuner_type = UNSET, |
1861 | .tuner_addr = ADDR_UNSET, | 1884 | .tuner_addr = ADDR_UNSET, |
1862 | .radio_addr = ADDR_UNSET, | 1885 | .radio_addr = ADDR_UNSET, |
1863 | .no_msp34xx = 1, | 1886 | .no_msp34xx = 1, |
@@ -1868,8 +1891,8 @@ struct tvcard bttv_tvcards[] = { | |||
1868 | .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ | 1891 | .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ |
1869 | .video_inputs = 1, | 1892 | .video_inputs = 1, |
1870 | .audio_inputs = 1, | 1893 | .audio_inputs = 1, |
1871 | .tuner = -1, | 1894 | .tuner = UNSET, |
1872 | .svhs = -1, | 1895 | .svhs = UNSET, |
1873 | .muxsel = { 0 }, | 1896 | .muxsel = { 0 }, |
1874 | .pll = PLL_28, | 1897 | .pll = PLL_28, |
1875 | .tuner_type = UNSET, | 1898 | .tuner_type = UNSET, |
@@ -1885,7 +1908,7 @@ struct tvcard bttv_tvcards[] = { | |||
1885 | .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ | 1908 | .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ |
1886 | .video_inputs = 2, | 1909 | .video_inputs = 2, |
1887 | .audio_inputs = 1, | 1910 | .audio_inputs = 1, |
1888 | .tuner = -1, | 1911 | .tuner = UNSET, |
1889 | .svhs = 1, | 1912 | .svhs = 1, |
1890 | .muxsel = { 0, 1 }, | 1913 | .muxsel = { 0, 1 }, |
1891 | .pll = PLL_28, | 1914 | .pll = PLL_28, |
@@ -1900,7 +1923,7 @@ struct tvcard bttv_tvcards[] = { | |||
1900 | .name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */ | 1923 | .name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */ |
1901 | .video_inputs = 2, | 1924 | .video_inputs = 2, |
1902 | .audio_inputs = 1, | 1925 | .audio_inputs = 1, |
1903 | .tuner = -1, | 1926 | .tuner = UNSET, |
1904 | .svhs = 1, | 1927 | .svhs = 1, |
1905 | .muxsel = { 2, 3 }, | 1928 | .muxsel = { 2, 3 }, |
1906 | .pll = PLL_28, | 1929 | .pll = PLL_28, |
@@ -1915,11 +1938,11 @@ struct tvcard bttv_tvcards[] = { | |||
1915 | .name = "Osprey 500", /* 500 */ | 1938 | .name = "Osprey 500", /* 500 */ |
1916 | .video_inputs = 2, | 1939 | .video_inputs = 2, |
1917 | .audio_inputs = 1, | 1940 | .audio_inputs = 1, |
1918 | .tuner = -1, | 1941 | .tuner = UNSET, |
1919 | .svhs = 1, | 1942 | .svhs = 1, |
1920 | .muxsel = { 2, 3 }, | 1943 | .muxsel = { 2, 3 }, |
1921 | .pll = PLL_28, | 1944 | .pll = PLL_28, |
1922 | .tuner_type = -1, | 1945 | .tuner_type = UNSET, |
1923 | .tuner_addr = ADDR_UNSET, | 1946 | .tuner_addr = ADDR_UNSET, |
1924 | .radio_addr = ADDR_UNSET, | 1947 | .radio_addr = ADDR_UNSET, |
1925 | .no_msp34xx = 1, | 1948 | .no_msp34xx = 1, |
@@ -1930,9 +1953,9 @@ struct tvcard bttv_tvcards[] = { | |||
1930 | .name = "Osprey 540", /* 540 */ | 1953 | .name = "Osprey 540", /* 540 */ |
1931 | .video_inputs = 4, | 1954 | .video_inputs = 4, |
1932 | .audio_inputs = 1, | 1955 | .audio_inputs = 1, |
1933 | .tuner = -1, | 1956 | .tuner = UNSET, |
1934 | .pll = PLL_28, | 1957 | .pll = PLL_28, |
1935 | .tuner_type = -1, | 1958 | .tuner_type = UNSET, |
1936 | .tuner_addr = ADDR_UNSET, | 1959 | .tuner_addr = ADDR_UNSET, |
1937 | .radio_addr = ADDR_UNSET, | 1960 | .radio_addr = ADDR_UNSET, |
1938 | .no_msp34xx = 1, | 1961 | .no_msp34xx = 1, |
@@ -1945,7 +1968,7 @@ struct tvcard bttv_tvcards[] = { | |||
1945 | .name = "Osprey 2000", /* 2000 */ | 1968 | .name = "Osprey 2000", /* 2000 */ |
1946 | .video_inputs = 2, | 1969 | .video_inputs = 2, |
1947 | .audio_inputs = 1, | 1970 | .audio_inputs = 1, |
1948 | .tuner = -1, | 1971 | .tuner = UNSET, |
1949 | .svhs = 1, | 1972 | .svhs = 1, |
1950 | .muxsel = { 2, 3 }, | 1973 | .muxsel = { 2, 3 }, |
1951 | .pll = PLL_28, | 1974 | .pll = PLL_28, |
@@ -1961,11 +1984,11 @@ struct tvcard bttv_tvcards[] = { | |||
1961 | .name = "IDS Eagle", | 1984 | .name = "IDS Eagle", |
1962 | .video_inputs = 4, | 1985 | .video_inputs = 4, |
1963 | .audio_inputs = 0, | 1986 | .audio_inputs = 0, |
1964 | .tuner = -1, | 1987 | .tuner = UNSET, |
1965 | .tuner_type = -1, | 1988 | .tuner_type = UNSET, |
1966 | .tuner_addr = ADDR_UNSET, | 1989 | .tuner_addr = ADDR_UNSET, |
1967 | .radio_addr = ADDR_UNSET, | 1990 | .radio_addr = ADDR_UNSET, |
1968 | .svhs = -1, | 1991 | .svhs = UNSET, |
1969 | .gpiomask = 0, | 1992 | .gpiomask = 0, |
1970 | .muxsel = { 0, 1, 2, 3 }, | 1993 | .muxsel = { 0, 1, 2, 3 }, |
1971 | .muxsel_hook = eagle_muxsel, | 1994 | .muxsel_hook = eagle_muxsel, |
@@ -1978,8 +2001,8 @@ struct tvcard bttv_tvcards[] = { | |||
1978 | .video_inputs = 2, | 2001 | .video_inputs = 2, |
1979 | .audio_inputs = 0, | 2002 | .audio_inputs = 0, |
1980 | .svhs = 1, | 2003 | .svhs = 1, |
1981 | .tuner = -1, | 2004 | .tuner = UNSET, |
1982 | .tuner_type = -1, | 2005 | .tuner_type = UNSET, |
1983 | .tuner_addr = ADDR_UNSET, | 2006 | .tuner_addr = ADDR_UNSET, |
1984 | .radio_addr = ADDR_UNSET, | 2007 | .radio_addr = ADDR_UNSET, |
1985 | .no_msp34xx = 1, | 2008 | .no_msp34xx = 1, |
@@ -2020,13 +2043,13 @@ struct tvcard bttv_tvcards[] = { | |||
2020 | .video_inputs = 3, | 2043 | .video_inputs = 3, |
2021 | .audio_inputs = 1, | 2044 | .audio_inputs = 1, |
2022 | .tuner = 0, | 2045 | .tuner = 0, |
2023 | .svhs = -1, | 2046 | .svhs = UNSET, |
2024 | .gpiomask = 7, | 2047 | .gpiomask = 7, |
2025 | .muxsel = { 2, 3, 1, 1}, | 2048 | .muxsel = { 2, 3, 1, 1}, |
2026 | .gpiomux = { 0, 1, 2, 3}, | 2049 | .gpiomux = { 0, 1, 2, 3}, |
2027 | .gpiomute = 4, | 2050 | .gpiomute = 4, |
2028 | .needs_tvaudio = 1, | 2051 | .needs_tvaudio = 1, |
2029 | .tuner_type = 5, | 2052 | .tuner_type = TUNER_PHILIPS_PAL, |
2030 | .tuner_addr = ADDR_UNSET, | 2053 | .tuner_addr = ADDR_UNSET, |
2031 | .radio_addr = ADDR_UNSET, | 2054 | .radio_addr = ADDR_UNSET, |
2032 | .pll = PLL_28, | 2055 | .pll = PLL_28, |
@@ -2035,7 +2058,7 @@ struct tvcard bttv_tvcards[] = { | |||
2035 | .name = "Euresys Picolo", | 2058 | .name = "Euresys Picolo", |
2036 | .video_inputs = 3, | 2059 | .video_inputs = 3, |
2037 | .audio_inputs = 0, | 2060 | .audio_inputs = 0, |
2038 | .tuner = -1, | 2061 | .tuner = UNSET, |
2039 | .svhs = 2, | 2062 | .svhs = 2, |
2040 | .gpiomask = 0, | 2063 | .gpiomask = 0, |
2041 | .no_msp34xx = 1, | 2064 | .no_msp34xx = 1, |
@@ -2052,8 +2075,8 @@ struct tvcard bttv_tvcards[] = { | |||
2052 | .name = "ProVideo PV150", /* 0x4f */ | 2075 | .name = "ProVideo PV150", /* 0x4f */ |
2053 | .video_inputs = 2, | 2076 | .video_inputs = 2, |
2054 | .audio_inputs = 0, | 2077 | .audio_inputs = 0, |
2055 | .tuner = -1, | 2078 | .tuner = UNSET, |
2056 | .svhs = -1, | 2079 | .svhs = UNSET, |
2057 | .gpiomask = 0, | 2080 | .gpiomask = 0, |
2058 | .muxsel = { 2, 3 }, | 2081 | .muxsel = { 2, 3 }, |
2059 | .gpiomux = { 0 }, | 2082 | .gpiomux = { 0 }, |
@@ -2080,7 +2103,7 @@ struct tvcard bttv_tvcards[] = { | |||
2080 | .needs_tvaudio = 0, | 2103 | .needs_tvaudio = 0, |
2081 | .no_msp34xx = 1, | 2104 | .no_msp34xx = 1, |
2082 | .pll = PLL_28, | 2105 | .pll = PLL_28, |
2083 | .tuner_type = 2, | 2106 | .tuner_type = TUNER_PHILIPS_NTSC, |
2084 | .tuner_addr = ADDR_UNSET, | 2107 | .tuner_addr = ADDR_UNSET, |
2085 | .radio_addr = ADDR_UNSET, | 2108 | .radio_addr = ADDR_UNSET, |
2086 | .audio_hook = adtvk503_audio, | 2109 | .audio_hook = adtvk503_audio, |
@@ -2098,7 +2121,7 @@ struct tvcard bttv_tvcards[] = { | |||
2098 | .needs_tvaudio = 1, | 2121 | .needs_tvaudio = 1, |
2099 | .no_msp34xx = 1, | 2122 | .no_msp34xx = 1, |
2100 | .pll = PLL_28, | 2123 | .pll = PLL_28, |
2101 | .tuner_type = 5, | 2124 | .tuner_type = TUNER_PHILIPS_PAL, |
2102 | .tuner_addr = ADDR_UNSET, | 2125 | .tuner_addr = ADDR_UNSET, |
2103 | .radio_addr = ADDR_UNSET, | 2126 | .radio_addr = ADDR_UNSET, |
2104 | /* Notes: | 2127 | /* Notes: |
@@ -2121,7 +2144,7 @@ struct tvcard bttv_tvcards[] = { | |||
2121 | .gpiomask = 0, | 2144 | .gpiomask = 0, |
2122 | .no_tda9875 = 1, | 2145 | .no_tda9875 = 1, |
2123 | .no_tda7432 = 1, | 2146 | .no_tda7432 = 1, |
2124 | .tuner_type = 1, | 2147 | .tuner_type = TUNER_PHILIPS_PAL_I, |
2125 | .tuner_addr = ADDR_UNSET, | 2148 | .tuner_addr = ADDR_UNSET, |
2126 | .radio_addr = ADDR_UNSET, | 2149 | .radio_addr = ADDR_UNSET, |
2127 | .has_radio = 1, | 2150 | .has_radio = 1, |
@@ -2138,11 +2161,11 @@ struct tvcard bttv_tvcards[] = { | |||
2138 | .name = "IVC-200", | 2161 | .name = "IVC-200", |
2139 | .video_inputs = 1, | 2162 | .video_inputs = 1, |
2140 | .audio_inputs = 0, | 2163 | .audio_inputs = 0, |
2141 | .tuner = -1, | 2164 | .tuner = UNSET, |
2142 | .tuner_type = -1, | 2165 | .tuner_type = UNSET, |
2143 | .tuner_addr = ADDR_UNSET, | 2166 | .tuner_addr = ADDR_UNSET, |
2144 | .radio_addr = ADDR_UNSET, | 2167 | .radio_addr = ADDR_UNSET, |
2145 | .svhs = -1, | 2168 | .svhs = UNSET, |
2146 | .gpiomask = 0xdf, | 2169 | .gpiomask = 0xdf, |
2147 | .muxsel = { 2 }, | 2170 | .muxsel = { 2 }, |
2148 | .pll = PLL_28, | 2171 | .pll = PLL_28, |
@@ -2151,9 +2174,9 @@ struct tvcard bttv_tvcards[] = { | |||
2151 | .name = "Grand X-Guard / Trust 814PCI", | 2174 | .name = "Grand X-Guard / Trust 814PCI", |
2152 | .video_inputs = 16, | 2175 | .video_inputs = 16, |
2153 | .audio_inputs = 0, | 2176 | .audio_inputs = 0, |
2154 | .tuner = -1, | 2177 | .tuner = UNSET, |
2155 | .svhs = -1, | 2178 | .svhs = UNSET, |
2156 | .tuner_type = 4, | 2179 | .tuner_type = TUNER_ABSENT, |
2157 | .tuner_addr = ADDR_UNSET, | 2180 | .tuner_addr = ADDR_UNSET, |
2158 | .radio_addr = ADDR_UNSET, | 2181 | .radio_addr = ADDR_UNSET, |
2159 | .gpiomask2 = 0xff, | 2182 | .gpiomask2 = 0xff, |
@@ -2169,14 +2192,14 @@ struct tvcard bttv_tvcards[] = { | |||
2169 | [BTTV_BOARD_NEBULA_DIGITV] = { | 2192 | [BTTV_BOARD_NEBULA_DIGITV] = { |
2170 | .name = "Nebula Electronics DigiTV", | 2193 | .name = "Nebula Electronics DigiTV", |
2171 | .video_inputs = 1, | 2194 | .video_inputs = 1, |
2172 | .tuner = -1, | 2195 | .tuner = UNSET, |
2173 | .svhs = -1, | 2196 | .svhs = UNSET, |
2174 | .muxsel = { 2, 3, 1, 0 }, | 2197 | .muxsel = { 2, 3, 1, 0 }, |
2175 | .no_msp34xx = 1, | 2198 | .no_msp34xx = 1, |
2176 | .no_tda9875 = 1, | 2199 | .no_tda9875 = 1, |
2177 | .no_tda7432 = 1, | 2200 | .no_tda7432 = 1, |
2178 | .pll = PLL_28, | 2201 | .pll = PLL_28, |
2179 | .tuner_type = -1, | 2202 | .tuner_type = UNSET, |
2180 | .tuner_addr = ADDR_UNSET, | 2203 | .tuner_addr = ADDR_UNSET, |
2181 | .radio_addr = ADDR_UNSET, | 2204 | .radio_addr = ADDR_UNSET, |
2182 | .has_dvb = 1, | 2205 | .has_dvb = 1, |
@@ -2189,15 +2212,15 @@ struct tvcard bttv_tvcards[] = { | |||
2189 | .name = "ProVideo PV143", | 2212 | .name = "ProVideo PV143", |
2190 | .video_inputs = 4, | 2213 | .video_inputs = 4, |
2191 | .audio_inputs = 0, | 2214 | .audio_inputs = 0, |
2192 | .tuner = -1, | 2215 | .tuner = UNSET, |
2193 | .svhs = -1, | 2216 | .svhs = UNSET, |
2194 | .gpiomask = 0, | 2217 | .gpiomask = 0, |
2195 | .muxsel = { 2, 3, 1, 0 }, | 2218 | .muxsel = { 2, 3, 1, 0 }, |
2196 | .gpiomux = { 0 }, | 2219 | .gpiomux = { 0 }, |
2197 | .needs_tvaudio = 0, | 2220 | .needs_tvaudio = 0, |
2198 | .no_msp34xx = 1, | 2221 | .no_msp34xx = 1, |
2199 | .pll = PLL_28, | 2222 | .pll = PLL_28, |
2200 | .tuner_type = -1, | 2223 | .tuner_type = UNSET, |
2201 | .tuner_addr = ADDR_UNSET, | 2224 | .tuner_addr = ADDR_UNSET, |
2202 | .radio_addr = ADDR_UNSET, | 2225 | .radio_addr = ADDR_UNSET, |
2203 | }, | 2226 | }, |
@@ -2206,14 +2229,14 @@ struct tvcard bttv_tvcards[] = { | |||
2206 | .name = "PHYTEC VD-009-X1 MiniDIN (bt878)", | 2229 | .name = "PHYTEC VD-009-X1 MiniDIN (bt878)", |
2207 | .video_inputs = 4, | 2230 | .video_inputs = 4, |
2208 | .audio_inputs = 0, | 2231 | .audio_inputs = 0, |
2209 | .tuner = -1, /* card has no tuner */ | 2232 | .tuner = UNSET, /* card has no tuner */ |
2210 | .svhs = 3, | 2233 | .svhs = 3, |
2211 | .gpiomask = 0x00, | 2234 | .gpiomask = 0x00, |
2212 | .muxsel = { 2, 3, 1, 0 }, | 2235 | .muxsel = { 2, 3, 1, 0 }, |
2213 | .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ | 2236 | .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ |
2214 | .needs_tvaudio = 1, | 2237 | .needs_tvaudio = 1, |
2215 | .pll = PLL_28, | 2238 | .pll = PLL_28, |
2216 | .tuner_type = -1, | 2239 | .tuner_type = UNSET, |
2217 | .tuner_addr = ADDR_UNSET, | 2240 | .tuner_addr = ADDR_UNSET, |
2218 | .radio_addr = ADDR_UNSET, | 2241 | .radio_addr = ADDR_UNSET, |
2219 | }, | 2242 | }, |
@@ -2221,14 +2244,14 @@ struct tvcard bttv_tvcards[] = { | |||
2221 | .name = "PHYTEC VD-009-X1 Combi (bt878)", | 2244 | .name = "PHYTEC VD-009-X1 Combi (bt878)", |
2222 | .video_inputs = 4, | 2245 | .video_inputs = 4, |
2223 | .audio_inputs = 0, | 2246 | .audio_inputs = 0, |
2224 | .tuner = -1, /* card has no tuner */ | 2247 | .tuner = UNSET, /* card has no tuner */ |
2225 | .svhs = 3, | 2248 | .svhs = 3, |
2226 | .gpiomask = 0x00, | 2249 | .gpiomask = 0x00, |
2227 | .muxsel = { 2, 3, 1, 1 }, | 2250 | .muxsel = { 2, 3, 1, 1 }, |
2228 | .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ | 2251 | .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ |
2229 | .needs_tvaudio = 1, | 2252 | .needs_tvaudio = 1, |
2230 | .pll = PLL_28, | 2253 | .pll = PLL_28, |
2231 | .tuner_type = -1, | 2254 | .tuner_type = UNSET, |
2232 | .tuner_addr = ADDR_UNSET, | 2255 | .tuner_addr = ADDR_UNSET, |
2233 | .radio_addr = ADDR_UNSET, | 2256 | .radio_addr = ADDR_UNSET, |
2234 | }, | 2257 | }, |
@@ -2238,7 +2261,7 @@ struct tvcard bttv_tvcards[] = { | |||
2238 | .name = "PHYTEC VD-009 MiniDIN (bt878)", | 2261 | .name = "PHYTEC VD-009 MiniDIN (bt878)", |
2239 | .video_inputs = 10, | 2262 | .video_inputs = 10, |
2240 | .audio_inputs = 0, | 2263 | .audio_inputs = 0, |
2241 | .tuner = -1, /* card has no tuner */ | 2264 | .tuner = UNSET, /* card has no tuner */ |
2242 | .svhs = 9, | 2265 | .svhs = 9, |
2243 | .gpiomask = 0x00, | 2266 | .gpiomask = 0x00, |
2244 | .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio | 2267 | .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio |
@@ -2248,7 +2271,7 @@ struct tvcard bttv_tvcards[] = { | |||
2248 | .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ | 2271 | .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ |
2249 | .needs_tvaudio = 1, | 2272 | .needs_tvaudio = 1, |
2250 | .pll = PLL_28, | 2273 | .pll = PLL_28, |
2251 | .tuner_type = -1, | 2274 | .tuner_type = UNSET, |
2252 | .tuner_addr = ADDR_UNSET, | 2275 | .tuner_addr = ADDR_UNSET, |
2253 | .radio_addr = ADDR_UNSET, | 2276 | .radio_addr = ADDR_UNSET, |
2254 | }, | 2277 | }, |
@@ -2256,7 +2279,7 @@ struct tvcard bttv_tvcards[] = { | |||
2256 | .name = "PHYTEC VD-009 Combi (bt878)", | 2279 | .name = "PHYTEC VD-009 Combi (bt878)", |
2257 | .video_inputs = 10, | 2280 | .video_inputs = 10, |
2258 | .audio_inputs = 0, | 2281 | .audio_inputs = 0, |
2259 | .tuner = -1, /* card has no tuner */ | 2282 | .tuner = UNSET, /* card has no tuner */ |
2260 | .svhs = 9, | 2283 | .svhs = 9, |
2261 | .gpiomask = 0x00, | 2284 | .gpiomask = 0x00, |
2262 | .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio | 2285 | .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio |
@@ -2266,7 +2289,7 @@ struct tvcard bttv_tvcards[] = { | |||
2266 | .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ | 2289 | .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ |
2267 | .needs_tvaudio = 1, | 2290 | .needs_tvaudio = 1, |
2268 | .pll = PLL_28, | 2291 | .pll = PLL_28, |
2269 | .tuner_type = -1, | 2292 | .tuner_type = UNSET, |
2270 | .tuner_addr = ADDR_UNSET, | 2293 | .tuner_addr = ADDR_UNSET, |
2271 | .radio_addr = ADDR_UNSET, | 2294 | .radio_addr = ADDR_UNSET, |
2272 | }, | 2295 | }, |
@@ -2274,11 +2297,11 @@ struct tvcard bttv_tvcards[] = { | |||
2274 | .name = "IVC-100", | 2297 | .name = "IVC-100", |
2275 | .video_inputs = 4, | 2298 | .video_inputs = 4, |
2276 | .audio_inputs = 0, | 2299 | .audio_inputs = 0, |
2277 | .tuner = -1, | 2300 | .tuner = UNSET, |
2278 | .tuner_type = -1, | 2301 | .tuner_type = UNSET, |
2279 | .tuner_addr = ADDR_UNSET, | 2302 | .tuner_addr = ADDR_UNSET, |
2280 | .radio_addr = ADDR_UNSET, | 2303 | .radio_addr = ADDR_UNSET, |
2281 | .svhs = -1, | 2304 | .svhs = UNSET, |
2282 | .gpiomask = 0xdf, | 2305 | .gpiomask = 0xdf, |
2283 | .muxsel = { 2, 3, 1, 0 }, | 2306 | .muxsel = { 2, 3, 1, 0 }, |
2284 | .pll = PLL_28, | 2307 | .pll = PLL_28, |
@@ -2288,11 +2311,11 @@ struct tvcard bttv_tvcards[] = { | |||
2288 | .name = "IVC-120G", | 2311 | .name = "IVC-120G", |
2289 | .video_inputs = 16, | 2312 | .video_inputs = 16, |
2290 | .audio_inputs = 0, /* card has no audio */ | 2313 | .audio_inputs = 0, /* card has no audio */ |
2291 | .tuner = -1, /* card has no tuner */ | 2314 | .tuner = UNSET, /* card has no tuner */ |
2292 | .tuner_type = -1, | 2315 | .tuner_type = UNSET, |
2293 | .tuner_addr = ADDR_UNSET, | 2316 | .tuner_addr = ADDR_UNSET, |
2294 | .radio_addr = ADDR_UNSET, | 2317 | .radio_addr = ADDR_UNSET, |
2295 | .svhs = -1, /* card has no svhs */ | 2318 | .svhs = UNSET, /* card has no svhs */ |
2296 | .needs_tvaudio = 0, | 2319 | .needs_tvaudio = 0, |
2297 | .no_msp34xx = 1, | 2320 | .no_msp34xx = 1, |
2298 | .no_tda9875 = 1, | 2321 | .no_tda9875 = 1, |
@@ -2333,7 +2356,7 @@ struct tvcard bttv_tvcards[] = { | |||
2333 | .video_inputs = 3, | 2356 | .video_inputs = 3, |
2334 | .audio_inputs = 0, | 2357 | .audio_inputs = 0, |
2335 | .svhs = 1, | 2358 | .svhs = 1, |
2336 | .tuner = -1, | 2359 | .tuner = UNSET, |
2337 | .muxsel = { 3, 1, 1, 3 }, /* Vid In, SVid In, Vid over SVid in connector */ | 2360 | .muxsel = { 3, 1, 1, 3 }, /* Vid In, SVid In, Vid over SVid in connector */ |
2338 | .no_msp34xx = 1, | 2361 | .no_msp34xx = 1, |
2339 | .no_tda9875 = 1, | 2362 | .no_tda9875 = 1, |
@@ -2364,9 +2387,9 @@ struct tvcard bttv_tvcards[] = { | |||
2364 | .name = "SIMUS GVC1100", | 2387 | .name = "SIMUS GVC1100", |
2365 | .video_inputs = 4, | 2388 | .video_inputs = 4, |
2366 | .audio_inputs = 0, | 2389 | .audio_inputs = 0, |
2367 | .tuner = -1, | 2390 | .tuner = UNSET, |
2368 | .svhs = -1, | 2391 | .svhs = UNSET, |
2369 | .tuner_type = -1, | 2392 | .tuner_type = UNSET, |
2370 | .tuner_addr = ADDR_UNSET, | 2393 | .tuner_addr = ADDR_UNSET, |
2371 | .radio_addr = ADDR_UNSET, | 2394 | .radio_addr = ADDR_UNSET, |
2372 | .pll = PLL_28, | 2395 | .pll = PLL_28, |
@@ -2395,14 +2418,14 @@ struct tvcard bttv_tvcards[] = { | |||
2395 | .name = "LMLBT4", | 2418 | .name = "LMLBT4", |
2396 | .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ | 2419 | .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ |
2397 | .audio_inputs = 0, | 2420 | .audio_inputs = 0, |
2398 | .tuner = -1, | 2421 | .tuner = UNSET, |
2399 | .svhs = -1, | 2422 | .svhs = UNSET, |
2400 | .muxsel = { 2, 3, 1, 0 }, | 2423 | .muxsel = { 2, 3, 1, 0 }, |
2401 | .no_msp34xx = 1, | 2424 | .no_msp34xx = 1, |
2402 | .no_tda9875 = 1, | 2425 | .no_tda9875 = 1, |
2403 | .no_tda7432 = 1, | 2426 | .no_tda7432 = 1, |
2404 | .needs_tvaudio = 0, | 2427 | .needs_tvaudio = 0, |
2405 | .tuner_type = -1, | 2428 | .tuner_type = UNSET, |
2406 | .tuner_addr = ADDR_UNSET, | 2429 | .tuner_addr = ADDR_UNSET, |
2407 | .radio_addr = ADDR_UNSET, | 2430 | .radio_addr = ADDR_UNSET, |
2408 | }, | 2431 | }, |
@@ -2452,8 +2475,8 @@ struct tvcard bttv_tvcards[] = { | |||
2452 | .name = "Euresys Picolo Tetra", | 2475 | .name = "Euresys Picolo Tetra", |
2453 | .video_inputs = 4, | 2476 | .video_inputs = 4, |
2454 | .audio_inputs = 0, | 2477 | .audio_inputs = 0, |
2455 | .tuner = -1, | 2478 | .tuner = UNSET, |
2456 | .svhs = -1, | 2479 | .svhs = UNSET, |
2457 | .gpiomask = 0, | 2480 | .gpiomask = 0, |
2458 | .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ | 2481 | .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ |
2459 | .no_msp34xx = 1, | 2482 | .no_msp34xx = 1, |
@@ -2464,7 +2487,7 @@ struct tvcard bttv_tvcards[] = { | |||
2464 | .pll = PLL_28, | 2487 | .pll = PLL_28, |
2465 | .needs_tvaudio = 0, | 2488 | .needs_tvaudio = 0, |
2466 | .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ | 2489 | .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ |
2467 | .tuner_type = -1, | 2490 | .tuner_type = UNSET, |
2468 | .tuner_addr = ADDR_UNSET, | 2491 | .tuner_addr = ADDR_UNSET, |
2469 | .radio_addr = ADDR_UNSET, | 2492 | .radio_addr = ADDR_UNSET, |
2470 | }, | 2493 | }, |
@@ -2490,7 +2513,7 @@ struct tvcard bttv_tvcards[] = { | |||
2490 | .name = "AVerMedia AVerTV DVB-T 771", | 2513 | .name = "AVerMedia AVerTV DVB-T 771", |
2491 | .video_inputs = 2, | 2514 | .video_inputs = 2, |
2492 | .svhs = 1, | 2515 | .svhs = 1, |
2493 | .tuner = -1, | 2516 | .tuner = UNSET, |
2494 | .tuner_type = TUNER_ABSENT, | 2517 | .tuner_type = TUNER_ABSENT, |
2495 | .tuner_addr = ADDR_UNSET, | 2518 | .tuner_addr = ADDR_UNSET, |
2496 | .radio_addr = ADDR_UNSET, | 2519 | .radio_addr = ADDR_UNSET, |
@@ -2509,14 +2532,14 @@ struct tvcard bttv_tvcards[] = { | |||
2509 | /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */ | 2532 | /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */ |
2510 | .name = "AverMedia AverTV DVB-T 761", | 2533 | .name = "AverMedia AverTV DVB-T 761", |
2511 | .video_inputs = 2, | 2534 | .video_inputs = 2, |
2512 | .tuner = -1, | 2535 | .tuner = UNSET, |
2513 | .svhs = 1, | 2536 | .svhs = 1, |
2514 | .muxsel = { 3, 1, 2, 0 }, /* Comp0, S-Video, ?, ? */ | 2537 | .muxsel = { 3, 1, 2, 0 }, /* Comp0, S-Video, ?, ? */ |
2515 | .no_msp34xx = 1, | 2538 | .no_msp34xx = 1, |
2516 | .no_tda9875 = 1, | 2539 | .no_tda9875 = 1, |
2517 | .no_tda7432 = 1, | 2540 | .no_tda7432 = 1, |
2518 | .pll = PLL_28, | 2541 | .pll = PLL_28, |
2519 | .tuner_type = -1, | 2542 | .tuner_type = UNSET, |
2520 | .tuner_addr = ADDR_UNSET, | 2543 | .tuner_addr = ADDR_UNSET, |
2521 | .radio_addr = ADDR_UNSET, | 2544 | .radio_addr = ADDR_UNSET, |
2522 | .has_dvb = 1, | 2545 | .has_dvb = 1, |
@@ -2528,8 +2551,8 @@ struct tvcard bttv_tvcards[] = { | |||
2528 | .name = "MATRIX Vision Sigma-SQ", | 2551 | .name = "MATRIX Vision Sigma-SQ", |
2529 | .video_inputs = 16, | 2552 | .video_inputs = 16, |
2530 | .audio_inputs = 0, | 2553 | .audio_inputs = 0, |
2531 | .tuner = -1, | 2554 | .tuner = UNSET, |
2532 | .svhs = -1, | 2555 | .svhs = UNSET, |
2533 | .gpiomask = 0x0, | 2556 | .gpiomask = 0x0, |
2534 | .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, | 2557 | .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, |
2535 | 3, 3, 3, 3, 3, 3, 3, 3 }, | 2558 | 3, 3, 3, 3, 3, 3, 3, 3 }, |
@@ -2537,7 +2560,7 @@ struct tvcard bttv_tvcards[] = { | |||
2537 | .gpiomux = { 0 }, | 2560 | .gpiomux = { 0 }, |
2538 | .no_msp34xx = 1, | 2561 | .no_msp34xx = 1, |
2539 | .pll = PLL_28, | 2562 | .pll = PLL_28, |
2540 | .tuner_type = -1, | 2563 | .tuner_type = UNSET, |
2541 | .tuner_addr = ADDR_UNSET, | 2564 | .tuner_addr = ADDR_UNSET, |
2542 | .radio_addr = ADDR_UNSET, | 2565 | .radio_addr = ADDR_UNSET, |
2543 | }, | 2566 | }, |
@@ -2546,15 +2569,15 @@ struct tvcard bttv_tvcards[] = { | |||
2546 | .name = "MATRIX Vision Sigma-SLC", | 2569 | .name = "MATRIX Vision Sigma-SLC", |
2547 | .video_inputs = 4, | 2570 | .video_inputs = 4, |
2548 | .audio_inputs = 0, | 2571 | .audio_inputs = 0, |
2549 | .tuner = -1, | 2572 | .tuner = UNSET, |
2550 | .svhs = -1, | 2573 | .svhs = UNSET, |
2551 | .gpiomask = 0x0, | 2574 | .gpiomask = 0x0, |
2552 | .muxsel = { 2, 2, 2, 2 }, | 2575 | .muxsel = { 2, 2, 2, 2 }, |
2553 | .muxsel_hook = sigmaSLC_muxsel, | 2576 | .muxsel_hook = sigmaSLC_muxsel, |
2554 | .gpiomux = { 0 }, | 2577 | .gpiomux = { 0 }, |
2555 | .no_msp34xx = 1, | 2578 | .no_msp34xx = 1, |
2556 | .pll = PLL_28, | 2579 | .pll = PLL_28, |
2557 | .tuner_type = -1, | 2580 | .tuner_type = UNSET, |
2558 | .tuner_addr = ADDR_UNSET, | 2581 | .tuner_addr = ADDR_UNSET, |
2559 | .radio_addr = ADDR_UNSET, | 2582 | .radio_addr = ADDR_UNSET, |
2560 | }, | 2583 | }, |
@@ -2566,7 +2589,7 @@ struct tvcard bttv_tvcards[] = { | |||
2566 | .video_inputs = 2, | 2589 | .video_inputs = 2, |
2567 | .audio_inputs = 1, | 2590 | .audio_inputs = 1, |
2568 | .tuner = 0, | 2591 | .tuner = 0, |
2569 | .svhs = -1, | 2592 | .svhs = UNSET, |
2570 | .gpiomask = 0xFF, | 2593 | .gpiomask = 0xFF, |
2571 | .muxsel = { 2, 3, 1, 1 }, | 2594 | .muxsel = { 2, 3, 1, 1 }, |
2572 | .gpiomux = { 2, 0, 0, 0 }, | 2595 | .gpiomux = { 2, 0, 0, 0 }, |
@@ -2584,14 +2607,14 @@ struct tvcard bttv_tvcards[] = { | |||
2584 | [BTTV_BOARD_DVICO_DVBT_LITE] = { | 2607 | [BTTV_BOARD_DVICO_DVBT_LITE] = { |
2585 | /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */ | 2608 | /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */ |
2586 | .name = "DViCO FusionHDTV DVB-T Lite", | 2609 | .name = "DViCO FusionHDTV DVB-T Lite", |
2587 | .tuner = -1, | 2610 | .tuner = UNSET, |
2588 | .no_msp34xx = 1, | 2611 | .no_msp34xx = 1, |
2589 | .no_tda9875 = 1, | 2612 | .no_tda9875 = 1, |
2590 | .no_tda7432 = 1, | 2613 | .no_tda7432 = 1, |
2591 | .pll = PLL_28, | 2614 | .pll = PLL_28, |
2592 | .no_video = 1, | 2615 | .no_video = 1, |
2593 | .has_dvb = 1, | 2616 | .has_dvb = 1, |
2594 | .tuner_type = -1, | 2617 | .tuner_type = UNSET, |
2595 | .tuner_addr = ADDR_UNSET, | 2618 | .tuner_addr = ADDR_UNSET, |
2596 | .radio_addr = ADDR_UNSET, | 2619 | .radio_addr = ADDR_UNSET, |
2597 | }, | 2620 | }, |
@@ -2634,14 +2657,14 @@ struct tvcard bttv_tvcards[] = { | |||
2634 | .name = "Tibet Systems 'Progress DVR' CS16", | 2657 | .name = "Tibet Systems 'Progress DVR' CS16", |
2635 | .video_inputs = 16, | 2658 | .video_inputs = 16, |
2636 | .audio_inputs = 0, | 2659 | .audio_inputs = 0, |
2637 | .tuner = -1, | 2660 | .tuner = UNSET, |
2638 | .svhs = -1, | 2661 | .svhs = UNSET, |
2639 | .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, | 2662 | .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, |
2640 | .pll = PLL_28, | 2663 | .pll = PLL_28, |
2641 | .no_msp34xx = 1, | 2664 | .no_msp34xx = 1, |
2642 | .no_tda9875 = 1, | 2665 | .no_tda9875 = 1, |
2643 | .no_tda7432 = 1, | 2666 | .no_tda7432 = 1, |
2644 | .tuner_type = -1, | 2667 | .tuner_type = UNSET, |
2645 | .tuner_addr = ADDR_UNSET, | 2668 | .tuner_addr = ADDR_UNSET, |
2646 | .radio_addr = ADDR_UNSET, | 2669 | .radio_addr = ADDR_UNSET, |
2647 | .muxsel_hook = tibetCS16_muxsel, | 2670 | .muxsel_hook = tibetCS16_muxsel, |
@@ -2661,11 +2684,11 @@ struct tvcard bttv_tvcards[] = { | |||
2661 | .name = "Kodicom 4400R (master)", | 2684 | .name = "Kodicom 4400R (master)", |
2662 | .video_inputs = 16, | 2685 | .video_inputs = 16, |
2663 | .audio_inputs = 0, | 2686 | .audio_inputs = 0, |
2664 | .tuner = -1, | 2687 | .tuner = UNSET, |
2665 | .tuner_type = -1, | 2688 | .tuner_type = UNSET, |
2666 | .tuner_addr = ADDR_UNSET, | 2689 | .tuner_addr = ADDR_UNSET, |
2667 | .radio_addr = ADDR_UNSET, | 2690 | .radio_addr = ADDR_UNSET, |
2668 | .svhs = -1, | 2691 | .svhs = UNSET, |
2669 | /* GPIO bits 0-9 used for analog switch: | 2692 | /* GPIO bits 0-9 used for analog switch: |
2670 | * 00 - 03: camera selector | 2693 | * 00 - 03: camera selector |
2671 | * 04 - 06: channel (controller) selector | 2694 | * 04 - 06: channel (controller) selector |
@@ -2693,11 +2716,11 @@ struct tvcard bttv_tvcards[] = { | |||
2693 | .name = "Kodicom 4400R (slave)", | 2716 | .name = "Kodicom 4400R (slave)", |
2694 | .video_inputs = 16, | 2717 | .video_inputs = 16, |
2695 | .audio_inputs = 0, | 2718 | .audio_inputs = 0, |
2696 | .tuner = -1, | 2719 | .tuner = UNSET, |
2697 | .tuner_type = -1, | 2720 | .tuner_type = UNSET, |
2698 | .tuner_addr = ADDR_UNSET, | 2721 | .tuner_addr = ADDR_UNSET, |
2699 | .radio_addr = ADDR_UNSET, | 2722 | .radio_addr = ADDR_UNSET, |
2700 | .svhs = -1, | 2723 | .svhs = UNSET, |
2701 | .gpiomask = 0x010000, | 2724 | .gpiomask = 0x010000, |
2702 | .no_gpioirq = 1, | 2725 | .no_gpioirq = 1, |
2703 | .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, | 2726 | .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, |
@@ -2717,7 +2740,7 @@ struct tvcard bttv_tvcards[] = { | |||
2717 | .tuner = 0, | 2740 | .tuner = 0, |
2718 | .svhs = 2, | 2741 | .svhs = 2, |
2719 | .muxsel = { 2, 3, 1, 0 }, | 2742 | .muxsel = { 2, 3, 1, 0 }, |
2720 | .tuner_type = -1, | 2743 | .tuner_type = UNSET, |
2721 | .tuner_addr = ADDR_UNSET, | 2744 | .tuner_addr = ADDR_UNSET, |
2722 | .radio_addr = ADDR_UNSET, | 2745 | .radio_addr = ADDR_UNSET, |
2723 | .pll = PLL_28, | 2746 | .pll = PLL_28, |
@@ -2824,7 +2847,7 @@ struct tvcard bttv_tvcards[] = { | |||
2824 | .name = "Osprey 440", | 2847 | .name = "Osprey 440", |
2825 | .video_inputs = 1, | 2848 | .video_inputs = 1, |
2826 | .audio_inputs = 1, | 2849 | .audio_inputs = 1, |
2827 | .tuner = -1, | 2850 | .tuner = UNSET, |
2828 | .svhs = 1, | 2851 | .svhs = 1, |
2829 | .muxsel = { 2 }, | 2852 | .muxsel = { 2 }, |
2830 | .pll = PLL_28, | 2853 | .pll = PLL_28, |
@@ -2848,7 +2871,7 @@ struct tvcard bttv_tvcards[] = { | |||
2848 | .gpiomute = 1, | 2871 | .gpiomute = 1, |
2849 | .needs_tvaudio = 1, | 2872 | .needs_tvaudio = 1, |
2850 | .pll = PLL_28, | 2873 | .pll = PLL_28, |
2851 | .tuner_type = 2, | 2874 | .tuner_type = TUNER_PHILIPS_NTSC, |
2852 | .tuner_addr = ADDR_UNSET, | 2875 | .tuner_addr = ADDR_UNSET, |
2853 | .radio_addr = ADDR_UNSET, | 2876 | .radio_addr = ADDR_UNSET, |
2854 | }, | 2877 | }, |
@@ -2875,14 +2898,14 @@ struct tvcard bttv_tvcards[] = { | |||
2875 | .name = "Hauppauge ImpactVCB (bt878)", | 2898 | .name = "Hauppauge ImpactVCB (bt878)", |
2876 | .video_inputs = 4, | 2899 | .video_inputs = 4, |
2877 | .audio_inputs = 0, | 2900 | .audio_inputs = 0, |
2878 | .tuner = -1, | 2901 | .tuner = UNSET, |
2879 | .svhs = -1, | 2902 | .svhs = UNSET, |
2880 | .gpiomask = 0x0f, /* old: 7 */ | 2903 | .gpiomask = 0x0f, /* old: 7 */ |
2881 | .muxsel = { 0, 1, 3, 2 }, /* Composite 0-3 */ | 2904 | .muxsel = { 0, 1, 3, 2 }, /* Composite 0-3 */ |
2882 | .no_msp34xx = 1, | 2905 | .no_msp34xx = 1, |
2883 | .no_tda9875 = 1, | 2906 | .no_tda9875 = 1, |
2884 | .no_tda7432 = 1, | 2907 | .no_tda7432 = 1, |
2885 | .tuner_type = -1, | 2908 | .tuner_type = UNSET, |
2886 | .tuner_addr = ADDR_UNSET, | 2909 | .tuner_addr = ADDR_UNSET, |
2887 | .radio_addr = ADDR_UNSET, | 2910 | .radio_addr = ADDR_UNSET, |
2888 | }, | 2911 | }, |
@@ -2914,10 +2937,10 @@ struct tvcard bttv_tvcards[] = { | |||
2914 | .name = "SSAI Security Video Interface", | 2937 | .name = "SSAI Security Video Interface", |
2915 | .video_inputs = 4, | 2938 | .video_inputs = 4, |
2916 | .audio_inputs = 0, | 2939 | .audio_inputs = 0, |
2917 | .tuner = -1, | 2940 | .tuner = UNSET, |
2918 | .svhs = -1, | 2941 | .svhs = UNSET, |
2919 | .muxsel = { 0, 1, 2, 3 }, | 2942 | .muxsel = { 0, 1, 2, 3 }, |
2920 | .tuner_type = -1, | 2943 | .tuner_type = UNSET, |
2921 | .tuner_addr = ADDR_UNSET, | 2944 | .tuner_addr = ADDR_UNSET, |
2922 | .radio_addr = ADDR_UNSET, | 2945 | .radio_addr = ADDR_UNSET, |
2923 | }, | 2946 | }, |
@@ -2925,13 +2948,31 @@ struct tvcard bttv_tvcards[] = { | |||
2925 | .name = "SSAI Ultrasound Video Interface", | 2948 | .name = "SSAI Ultrasound Video Interface", |
2926 | .video_inputs = 2, | 2949 | .video_inputs = 2, |
2927 | .audio_inputs = 0, | 2950 | .audio_inputs = 0, |
2928 | .tuner = -1, | 2951 | .tuner = UNSET, |
2929 | .svhs = 1, | 2952 | .svhs = 1, |
2930 | .muxsel = { 2, 0, 1, 3 }, | 2953 | .muxsel = { 2, 0, 1, 3 }, |
2931 | .tuner_type = -1, | 2954 | .tuner_type = UNSET, |
2932 | .tuner_addr = ADDR_UNSET, | 2955 | .tuner_addr = ADDR_UNSET, |
2933 | .radio_addr = ADDR_UNSET, | 2956 | .radio_addr = ADDR_UNSET, |
2934 | }, | 2957 | }, |
2958 | /* ---- card 0x94---------------------------------- */ | ||
2959 | [BTTV_BOARD_DVICO_FUSIONHDTV_2] = { | ||
2960 | .name = "DViCO FusionHDTV 2", | ||
2961 | .tuner = 0, | ||
2962 | .tuner_type = TUNER_PHILIPS_ATSC, /* FCV1236D */ | ||
2963 | .tuner_addr = ADDR_UNSET, | ||
2964 | .radio_addr = ADDR_UNSET, | ||
2965 | .video_inputs = 3, | ||
2966 | .audio_inputs = 1, | ||
2967 | .svhs = 2, | ||
2968 | .muxsel = { 2, 3, 1 }, | ||
2969 | .gpiomask = 0x00e00007, | ||
2970 | .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, | ||
2971 | .gpiomute = 0x00c00007, | ||
2972 | .no_msp34xx = 1, | ||
2973 | .no_tda9875 = 1, | ||
2974 | .no_tda7432 = 1, | ||
2975 | }, | ||
2935 | }; | 2976 | }; |
2936 | 2977 | ||
2937 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); | 2978 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); |
@@ -3040,7 +3081,7 @@ static void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256]) | |||
3040 | static void flyvideo_gpio(struct bttv *btv) | 3081 | static void flyvideo_gpio(struct bttv *btv) |
3041 | { | 3082 | { |
3042 | int gpio,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821; | 3083 | int gpio,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821; |
3043 | int tuner=-1,ttype; | 3084 | int tuner=UNSET,ttype; |
3044 | 3085 | ||
3045 | gpio_inout(0xffffff, 0); | 3086 | gpio_inout(0xffffff, 0); |
3046 | udelay(8); /* without this we would see the 0x1800 mask */ | 3087 | udelay(8); /* without this we would see the 0x1800 mask */ |
@@ -3085,7 +3126,7 @@ static void flyvideo_gpio(struct bttv *btv) | |||
3085 | * gpio & 0x001000 output bit for audio routing */ | 3126 | * gpio & 0x001000 output bit for audio routing */ |
3086 | 3127 | ||
3087 | if(is_capture_only) | 3128 | if(is_capture_only) |
3088 | tuner=4; /* No tuner present */ | 3129 | tuner = TUNER_ABSENT; /* No tuner present */ |
3089 | 3130 | ||
3090 | printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n", | 3131 | printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n", |
3091 | btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio); | 3132 | btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio); |
@@ -3093,7 +3134,7 @@ static void flyvideo_gpio(struct bttv *btv) | |||
3093 | btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ", | 3134 | btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ", |
3094 | is_capture_only?"yes":"no "); | 3135 | is_capture_only?"yes":"no "); |
3095 | 3136 | ||
3096 | if(tuner!= -1) /* only set if known tuner autodetected, else let insmod option through */ | 3137 | if (tuner != UNSET) /* only set if known tuner autodetected, else let insmod option through */ |
3097 | btv->tuner_type = tuner; | 3138 | btv->tuner_type = tuner; |
3098 | btv->has_radio = has_radio; | 3139 | btv->has_radio = has_radio; |
3099 | 3140 | ||
@@ -3302,6 +3343,7 @@ void __devinit bttv_init_card1(struct bttv *btv) | |||
3302 | case BTTV_BOARD_HAUPPAUGE878: | 3343 | case BTTV_BOARD_HAUPPAUGE878: |
3303 | boot_msp34xx(btv,5); | 3344 | boot_msp34xx(btv,5); |
3304 | break; | 3345 | break; |
3346 | case BTTV_BOARD_VOODOOTV_200: | ||
3305 | case BTTV_BOARD_VOODOOTV_FM: | 3347 | case BTTV_BOARD_VOODOOTV_FM: |
3306 | boot_msp34xx(btv,20); | 3348 | boot_msp34xx(btv,20); |
3307 | break; | 3349 | break; |
@@ -3328,10 +3370,9 @@ void __devinit bttv_init_card1(struct bttv *btv) | |||
3328 | /* initialization part two -- after registering i2c bus */ | 3370 | /* initialization part two -- after registering i2c bus */ |
3329 | void __devinit bttv_init_card2(struct bttv *btv) | 3371 | void __devinit bttv_init_card2(struct bttv *btv) |
3330 | { | 3372 | { |
3331 | int tda9887; | ||
3332 | int addr=ADDR_UNSET; | 3373 | int addr=ADDR_UNSET; |
3333 | 3374 | ||
3334 | btv->tuner_type = -1; | 3375 | btv->tuner_type = UNSET; |
3335 | 3376 | ||
3336 | if (BTTV_BOARD_UNKNOWN == btv->c.type) { | 3377 | if (BTTV_BOARD_UNKNOWN == btv->c.type) { |
3337 | bttv_readee(btv,eeprom_data,0xa0); | 3378 | bttv_readee(btv,eeprom_data,0xa0); |
@@ -3479,7 +3520,15 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3479 | btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; | 3520 | btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; |
3480 | if (UNSET != tuner[btv->c.nr]) | 3521 | if (UNSET != tuner[btv->c.nr]) |
3481 | btv->tuner_type = tuner[btv->c.nr]; | 3522 | btv->tuner_type = tuner[btv->c.nr]; |
3482 | printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type); | 3523 | |
3524 | if (btv->tuner_type == TUNER_ABSENT || | ||
3525 | bttv_tvcards[btv->c.type].tuner == UNSET) | ||
3526 | printk(KERN_INFO "bttv%d: tuner absent\n", btv->c.nr); | ||
3527 | else if(btv->tuner_type == UNSET) | ||
3528 | printk(KERN_WARNING "bttv%d: tuner type unset\n", btv->c.nr); | ||
3529 | else | ||
3530 | printk(KERN_INFO "bttv%d: tuner type=%d\n", btv->c.nr, | ||
3531 | btv->tuner_type); | ||
3483 | 3532 | ||
3484 | if (btv->tuner_type != UNSET) { | 3533 | if (btv->tuner_type != UNSET) { |
3485 | struct tuner_setup tun_setup; | 3534 | struct tuner_setup tun_setup; |
@@ -3521,6 +3570,9 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3521 | if (!autoload) | 3570 | if (!autoload) |
3522 | return; | 3571 | return; |
3523 | 3572 | ||
3573 | if (bttv_tvcards[btv->c.type].tuner == UNSET) | ||
3574 | return; /* no tuner or related drivers to load */ | ||
3575 | |||
3524 | /* try to detect audio/fader chips */ | 3576 | /* try to detect audio/fader chips */ |
3525 | if (!bttv_tvcards[btv->c.type].no_msp34xx && | 3577 | if (!bttv_tvcards[btv->c.type].no_msp34xx && |
3526 | bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx") >=0) | 3578 | bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx") >=0) |
@@ -3541,17 +3593,7 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3541 | if (bttv_tvcards[btv->c.type].needs_tvaudio) | 3593 | if (bttv_tvcards[btv->c.type].needs_tvaudio) |
3542 | request_module("tvaudio"); | 3594 | request_module("tvaudio"); |
3543 | 3595 | ||
3544 | /* tuner modules */ | 3596 | if (btv->tuner_type != UNSET && btv->tuner_type != TUNER_ABSENT) |
3545 | tda9887 = 0; | ||
3546 | if (btv->tda9887_conf) | ||
3547 | tda9887 = 1; | ||
3548 | if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && | ||
3549 | bttv_I2CRead(btv, I2C_ADDR_TDA9887, "TDA9887") >=0) | ||
3550 | tda9887 = 1; | ||
3551 | /* Hybrid DVB card, DOES have a tda9887 */ | ||
3552 | if (btv->c.type == BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE) | ||
3553 | tda9887 = 1; | ||
3554 | if (btv->tuner_type != UNSET) | ||
3555 | request_module("tuner"); | 3597 | request_module("tuner"); |
3556 | } | 3598 | } |
3557 | 3599 | ||
@@ -3865,11 +3907,15 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm) | |||
3865 | if(norm==VIDEO_MODE_NTSC) { | 3907 | if(norm==VIDEO_MODE_NTSC) { |
3866 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff; | 3908 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff; |
3867 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x957fff; | 3909 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x957fff; |
3910 | bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff; | ||
3911 | bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x957fff; | ||
3868 | dprintk("bttv_tda9880_setnorm to NTSC\n"); | 3912 | dprintk("bttv_tda9880_setnorm to NTSC\n"); |
3869 | } | 3913 | } |
3870 | else { | 3914 | else { |
3871 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff; | 3915 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff; |
3872 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x947fff; | 3916 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x947fff; |
3917 | bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff; | ||
3918 | bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x947fff; | ||
3873 | dprintk("bttv_tda9880_setnorm to PAL\n"); | 3919 | dprintk("bttv_tda9880_setnorm to PAL\n"); |
3874 | } | 3920 | } |
3875 | /* set GPIO according */ | 3921 | /* set GPIO according */ |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index b1fedb0f6431..cb555f2c40f9 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -1218,7 +1218,14 @@ audio_mux(struct bttv *btv, int input, int mute) | |||
1218 | break; | 1218 | break; |
1219 | case TVAUDIO_INPUT_TUNER: | 1219 | case TVAUDIO_INPUT_TUNER: |
1220 | default: | 1220 | default: |
1221 | route.input = MSP_INPUT_DEFAULT; | 1221 | /* This is the only card that uses TUNER2, and afaik, |
1222 | is the only difference between the VOODOOTV_FM | ||
1223 | and VOODOOTV_200 */ | ||
1224 | if (btv->c.type == BTTV_BOARD_VOODOOTV_200) | ||
1225 | route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER2, \ | ||
1226 | MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER); | ||
1227 | else | ||
1228 | route.input = MSP_INPUT_DEFAULT; | ||
1222 | break; | 1229 | break; |
1223 | } | 1230 | } |
1224 | route.output = MSP_OUTPUT_DEFAULT; | 1231 | route.output = MSP_OUTPUT_DEFAULT; |
@@ -1253,7 +1260,7 @@ i2c_vidiocschan(struct bttv *btv) | |||
1253 | v4l2_std_id std = bttv_tvnorms[btv->tvnorm].v4l2_id; | 1260 | v4l2_std_id std = bttv_tvnorms[btv->tvnorm].v4l2_id; |
1254 | 1261 | ||
1255 | bttv_call_i2c_clients(btv, VIDIOC_S_STD, &std); | 1262 | bttv_call_i2c_clients(btv, VIDIOC_S_STD, &std); |
1256 | if (btv->c.type == BTTV_BOARD_VOODOOTV_FM) | 1263 | if (btv->c.type == BTTV_BOARD_VOODOOTV_FM || btv->c.type == BTTV_BOARD_VOODOOTV_200) |
1257 | bttv_tda9880_setnorm(btv,btv->tvnorm); | 1264 | bttv_tda9880_setnorm(btv,btv->tvnorm); |
1258 | } | 1265 | } |
1259 | 1266 | ||
@@ -1323,6 +1330,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm) | |||
1323 | 1330 | ||
1324 | switch (btv->c.type) { | 1331 | switch (btv->c.type) { |
1325 | case BTTV_BOARD_VOODOOTV_FM: | 1332 | case BTTV_BOARD_VOODOOTV_FM: |
1333 | case BTTV_BOARD_VOODOOTV_200: | ||
1326 | bttv_tda9880_setnorm(btv,norm); | 1334 | bttv_tda9880_setnorm(btv,norm); |
1327 | break; | 1335 | break; |
1328 | } | 1336 | } |
@@ -2251,6 +2259,24 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
2251 | printk(KERN_INFO "bttv%d: ================== END STATUS CARD #%d ==================\n", btv->c.nr, btv->c.nr); | 2259 | printk(KERN_INFO "bttv%d: ================== END STATUS CARD #%d ==================\n", btv->c.nr, btv->c.nr); |
2252 | return 0; | 2260 | return 0; |
2253 | } | 2261 | } |
2262 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
2263 | case VIDIOC_DBG_G_REGISTER: | ||
2264 | case VIDIOC_DBG_S_REGISTER: | ||
2265 | { | ||
2266 | struct v4l2_register *reg = arg; | ||
2267 | if (!capable(CAP_SYS_ADMIN)) | ||
2268 | return -EPERM; | ||
2269 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | ||
2270 | return -EINVAL; | ||
2271 | /* bt848 has a 12-bit register space */ | ||
2272 | reg->reg &= 0xfff; | ||
2273 | if (cmd == VIDIOC_DBG_G_REGISTER) | ||
2274 | reg->val = btread(reg->reg); | ||
2275 | else | ||
2276 | btwrite(reg->val, reg->reg); | ||
2277 | return 0; | ||
2278 | } | ||
2279 | #endif | ||
2254 | 2280 | ||
2255 | default: | 2281 | default: |
2256 | return -ENOIOCTLCMD; | 2282 | return -ENOIOCTLCMD; |
@@ -3561,6 +3587,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
3561 | case VIDIOC_G_FREQUENCY: | 3587 | case VIDIOC_G_FREQUENCY: |
3562 | case VIDIOC_S_FREQUENCY: | 3588 | case VIDIOC_S_FREQUENCY: |
3563 | case VIDIOC_LOG_STATUS: | 3589 | case VIDIOC_LOG_STATUS: |
3590 | case VIDIOC_DBG_G_REGISTER: | ||
3591 | case VIDIOC_DBG_S_REGISTER: | ||
3564 | return bttv_common_ioctls(btv,cmd,arg); | 3592 | return bttv_common_ioctls(btv,cmd,arg); |
3565 | 3593 | ||
3566 | default: | 3594 | default: |
@@ -3943,6 +3971,8 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
3943 | case VIDIOCGAUDIO: | 3971 | case VIDIOCGAUDIO: |
3944 | case VIDIOCSAUDIO: | 3972 | case VIDIOCSAUDIO: |
3945 | case VIDIOC_LOG_STATUS: | 3973 | case VIDIOC_LOG_STATUS: |
3974 | case VIDIOC_DBG_G_REGISTER: | ||
3975 | case VIDIOC_DBG_S_REGISTER: | ||
3946 | return bttv_common_ioctls(btv,cmd,arg); | 3976 | return bttv_common_ioctls(btv,cmd,arg); |
3947 | 3977 | ||
3948 | default: | 3978 | default: |
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c index 6f74c8042bc3..94a13d0ee614 100644 --- a/drivers/media/video/bt8xx/bttv-input.c +++ b/drivers/media/video/bt8xx/bttv-input.c | |||
@@ -313,7 +313,7 @@ int bttv_input_init(struct bttv *btv) | |||
313 | input_dev->id.vendor = btv->c.pci->vendor; | 313 | input_dev->id.vendor = btv->c.pci->vendor; |
314 | input_dev->id.product = btv->c.pci->device; | 314 | input_dev->id.product = btv->c.pci->device; |
315 | } | 315 | } |
316 | input_dev->cdev.dev = &btv->c.pci->dev; | 316 | input_dev->dev.parent = &btv->c.pci->dev; |
317 | 317 | ||
318 | btv->remote = ir; | 318 | btv->remote = ir; |
319 | bttv_ir_start(btv, ir); | 319 | bttv_ir_start(btv, ir); |
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index f821ba69db99..dcc847dc2486 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h | |||
@@ -170,6 +170,8 @@ | |||
170 | #define BTTV_BOARD_MACHTV_MAGICTV 0x90 | 170 | #define BTTV_BOARD_MACHTV_MAGICTV 0x90 |
171 | #define BTTV_BOARD_SSAI_SECURITY 0x91 | 171 | #define BTTV_BOARD_SSAI_SECURITY 0x91 |
172 | #define BTTV_BOARD_SSAI_ULTRASOUND 0x92 | 172 | #define BTTV_BOARD_SSAI_ULTRASOUND 0x92 |
173 | #define BTTV_BOARD_VOODOOTV_200 0x93 | ||
174 | #define BTTV_BOARD_DVICO_FUSIONHDTV_2 0x94 | ||
173 | 175 | ||
174 | /* more card-specific defines */ | 176 | /* more card-specific defines */ |
175 | #define PT2254_L_CHANNEL 0x10 | 177 | #define PT2254_L_CHANNEL 0x10 |
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index 8f44f02029be..bd85f6d0fbe3 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h | |||
@@ -33,12 +33,12 @@ | |||
33 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
34 | #include <linux/i2c-algo-bit.h> | 34 | #include <linux/i2c-algo-bit.h> |
35 | #include <linux/videodev.h> | 35 | #include <linux/videodev.h> |
36 | #include <media/v4l2-common.h> | ||
37 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
38 | #include <linux/input.h> | 37 | #include <linux/input.h> |
39 | #include <linux/mutex.h> | 38 | #include <linux/mutex.h> |
40 | #include <asm/scatterlist.h> | 39 | #include <asm/scatterlist.h> |
41 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | #include <media/v4l2-common.h> | ||
42 | 42 | ||
43 | #include <linux/device.h> | 43 | #include <linux/device.h> |
44 | #include <media/video-buf.h> | 44 | #include <media/video-buf.h> |
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c index fd771c7a2fe2..55aab8d38880 100644 --- a/drivers/media/video/cpia2/cpia2_core.c +++ b/drivers/media/video/cpia2/cpia2_core.c | |||
@@ -663,15 +663,13 @@ int cpia2_reset_camera(struct camera_data *cam) | |||
663 | cpia2_send_command(cam, &cmd); | 663 | cpia2_send_command(cam, &cmd); |
664 | } | 664 | } |
665 | 665 | ||
666 | current->state = TASK_INTERRUPTIBLE; | 666 | schedule_timeout_interruptible(msecs_to_jiffies(100)); |
667 | schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ | ||
668 | 667 | ||
669 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) | 668 | if (cam->params.pnp_id.device_type == DEVICE_STV_672) |
670 | retval = apply_vp_patch(cam); | 669 | retval = apply_vp_patch(cam); |
671 | 670 | ||
672 | /* wait for vp to go to sleep */ | 671 | /* wait for vp to go to sleep */ |
673 | current->state = TASK_INTERRUPTIBLE; | 672 | schedule_timeout_interruptible(msecs_to_jiffies(100)); |
674 | schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ | ||
675 | 673 | ||
676 | /*** | 674 | /*** |
677 | * If this is a 676, apply VP5 fixes before we start streaming | 675 | * If this is a 676, apply VP5 fixes before we start streaming |
@@ -720,8 +718,7 @@ int cpia2_reset_camera(struct camera_data *cam) | |||
720 | set_default_user_mode(cam); | 718 | set_default_user_mode(cam); |
721 | 719 | ||
722 | /* Give VP time to wake up */ | 720 | /* Give VP time to wake up */ |
723 | current->state = TASK_INTERRUPTIBLE; | 721 | schedule_timeout_interruptible(msecs_to_jiffies(100)); |
724 | schedule_timeout(100 * HZ / 1000); /* wait for 100 msecs */ | ||
725 | 722 | ||
726 | set_all_properties(cam); | 723 | set_all_properties(cam); |
727 | 724 | ||
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 1bda7ad9de11..92778cd1d735 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c | |||
@@ -105,7 +105,7 @@ static struct control_menu_info framerate_controls[] = | |||
105 | { CPIA2_VP_FRAMERATE_25, "25 fps" }, | 105 | { CPIA2_VP_FRAMERATE_25, "25 fps" }, |
106 | { CPIA2_VP_FRAMERATE_30, "30 fps" }, | 106 | { CPIA2_VP_FRAMERATE_30, "30 fps" }, |
107 | }; | 107 | }; |
108 | #define NUM_FRAMERATE_CONTROLS (sizeof(framerate_controls)/sizeof(framerate_controls[0])) | 108 | #define NUM_FRAMERATE_CONTROLS (ARRAY_SIZE(framerate_controls)) |
109 | 109 | ||
110 | static struct control_menu_info flicker_controls[] = | 110 | static struct control_menu_info flicker_controls[] = |
111 | { | 111 | { |
@@ -113,7 +113,7 @@ static struct control_menu_info flicker_controls[] = | |||
113 | { FLICKER_50, "50 Hz" }, | 113 | { FLICKER_50, "50 Hz" }, |
114 | { FLICKER_60, "60 Hz" }, | 114 | { FLICKER_60, "60 Hz" }, |
115 | }; | 115 | }; |
116 | #define NUM_FLICKER_CONTROLS (sizeof(flicker_controls)/sizeof(flicker_controls[0])) | 116 | #define NUM_FLICKER_CONTROLS (ARRAY_SIZE(flicker_controls)) |
117 | 117 | ||
118 | static struct control_menu_info lights_controls[] = | 118 | static struct control_menu_info lights_controls[] = |
119 | { | 119 | { |
@@ -122,7 +122,7 @@ static struct control_menu_info lights_controls[] = | |||
122 | { 128, "Bottom" }, | 122 | { 128, "Bottom" }, |
123 | { 192, "Both" }, | 123 | { 192, "Both" }, |
124 | }; | 124 | }; |
125 | #define NUM_LIGHTS_CONTROLS (sizeof(lights_controls)/sizeof(lights_controls[0])) | 125 | #define NUM_LIGHTS_CONTROLS (ARRAY_SIZE(lights_controls)) |
126 | #define GPIO_LIGHTS_MASK 192 | 126 | #define GPIO_LIGHTS_MASK 192 |
127 | 127 | ||
128 | static struct v4l2_queryctrl controls[] = { | 128 | static struct v4l2_queryctrl controls[] = { |
@@ -235,7 +235,7 @@ static struct v4l2_queryctrl controls[] = { | |||
235 | .default_value = 0, | 235 | .default_value = 0, |
236 | }, | 236 | }, |
237 | }; | 237 | }; |
238 | #define NUM_CONTROLS (sizeof(controls)/sizeof(controls[0])) | 238 | #define NUM_CONTROLS (ARRAY_SIZE(controls)) |
239 | 239 | ||
240 | 240 | ||
241 | /****************************************************************************** | 241 | /****************************************************************************** |
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 0f9d96963618..f750a543c961 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
@@ -47,7 +47,7 @@ config VIDEO_CX88_DVB | |||
47 | tristate "DVB/ATSC Support for cx2388x based TV cards" | 47 | tristate "DVB/ATSC Support for cx2388x based TV cards" |
48 | depends on VIDEO_CX88 && DVB_CORE | 48 | depends on VIDEO_CX88 && DVB_CORE |
49 | select VIDEO_BUF_DVB | 49 | select VIDEO_BUF_DVB |
50 | select DVB_PLL | 50 | select DVB_PLL if !DVB_FE_CUSTOMISE |
51 | select DVB_MT352 if !DVB_FE_CUSTOMISE | 51 | select DVB_MT352 if !DVB_FE_CUSTOMISE |
52 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | 52 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE |
53 | select DVB_OR51132 if !DVB_FE_CUSTOMISE | 53 | select DVB_OR51132 if !DVB_FE_CUSTOMISE |
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index a80b1cb1abe8..f2fcdb92ecce 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -56,8 +56,7 @@ MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); | |||
56 | 56 | ||
57 | /* ------------------------------------------------------------------ */ | 57 | /* ------------------------------------------------------------------ */ |
58 | 58 | ||
59 | #define OLD_BLACKBIRD_FIRM_IMAGE_SIZE 262144 | 59 | #define BLACKBIRD_FIRM_IMAGE_SIZE 376836 |
60 | #define BLACKBIRD_FIRM_IMAGE_SIZE 376836 | ||
61 | 60 | ||
62 | /* defines below are from ivtv-driver.h */ | 61 | /* defines below are from ivtv-driver.h */ |
63 | 62 | ||
@@ -405,7 +404,7 @@ static int blackbird_find_mailbox(struct cx8802_dev *dev) | |||
405 | u32 value; | 404 | u32 value; |
406 | int i; | 405 | int i; |
407 | 406 | ||
408 | for (i = 0; i < dev->fw_size; i++) { | 407 | for (i = 0; i < BLACKBIRD_FIRM_IMAGE_SIZE; i++) { |
409 | memory_read(dev->core, i, &value); | 408 | memory_read(dev->core, i, &value); |
410 | if (value == signature[signaturecnt]) | 409 | if (value == signature[signaturecnt]) |
411 | signaturecnt++; | 410 | signaturecnt++; |
@@ -453,15 +452,12 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) | |||
453 | return -1; | 452 | return -1; |
454 | } | 453 | } |
455 | 454 | ||
456 | if ((firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) && | 455 | if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) { |
457 | (firmware->size != OLD_BLACKBIRD_FIRM_IMAGE_SIZE)) { | 456 | dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n", |
458 | dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d or %d)\n", | 457 | firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE); |
459 | firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE, | ||
460 | OLD_BLACKBIRD_FIRM_IMAGE_SIZE); | ||
461 | release_firmware(firmware); | 458 | release_firmware(firmware); |
462 | return -1; | 459 | return -1; |
463 | } | 460 | } |
464 | dev->fw_size = firmware->size; | ||
465 | 461 | ||
466 | if (0 != memcmp(firmware->data, magic, 8)) { | 462 | if (0 != memcmp(firmware->data, magic, 8)) { |
467 | dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n"); | 463 | dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n"); |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index e61102dc8ad7..6a136ddbccf8 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -1335,6 +1335,26 @@ struct cx88_board cx88_boards[] = { | |||
1335 | /* fixme: Add radio support */ | 1335 | /* fixme: Add radio support */ |
1336 | .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, | 1336 | .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, |
1337 | }, | 1337 | }, |
1338 | [CX88_BOARD_ADSTECH_PTV_390] = { | ||
1339 | .name = "ADS Tech Instant Video PCI", | ||
1340 | .tuner_type = TUNER_ABSENT, | ||
1341 | .radio_type = UNSET, | ||
1342 | .tuner_addr = ADDR_UNSET, | ||
1343 | .radio_addr = ADDR_UNSET, | ||
1344 | .input = {{ | ||
1345 | .type = CX88_VMUX_DEBUG, | ||
1346 | .vmux = 3, | ||
1347 | .gpio0 = 0x04ff, | ||
1348 | },{ | ||
1349 | .type = CX88_VMUX_COMPOSITE1, | ||
1350 | .vmux = 1, | ||
1351 | .gpio0 = 0x07fa, | ||
1352 | },{ | ||
1353 | .type = CX88_VMUX_SVIDEO, | ||
1354 | .vmux = 2, | ||
1355 | .gpio0 = 0x07fa, | ||
1356 | }}, | ||
1357 | }, | ||
1338 | }; | 1358 | }; |
1339 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); | 1359 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); |
1340 | 1360 | ||
@@ -1641,6 +1661,10 @@ struct cx88_subid cx88_subids[] = { | |||
1641 | .subvendor = 0x1421, | 1661 | .subvendor = 0x1421, |
1642 | .subdevice = 0x0341, /* ADS Tech InstantTV DVB-S */ | 1662 | .subdevice = 0x0341, /* ADS Tech InstantTV DVB-S */ |
1643 | .card = CX88_BOARD_KWORLD_DVBS_100, | 1663 | .card = CX88_BOARD_KWORLD_DVBS_100, |
1664 | },{ | ||
1665 | .subvendor = 0x1421, | ||
1666 | .subdevice = 0x0390, | ||
1667 | .card = CX88_BOARD_ADSTECH_PTV_390, | ||
1644 | }, | 1668 | }, |
1645 | }; | 1669 | }; |
1646 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); | 1670 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index dbfe4dc9cf8c..1773b40467dc 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -35,9 +35,7 @@ | |||
35 | 35 | ||
36 | #include "mt352.h" | 36 | #include "mt352.h" |
37 | #include "mt352_priv.h" | 37 | #include "mt352_priv.h" |
38 | #if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE) | 38 | #include "cx88-vp3054-i2c.h" |
39 | # include "cx88-vp3054-i2c.h" | ||
40 | #endif | ||
41 | #include "zl10353.h" | 39 | #include "zl10353.h" |
42 | #include "cx22702.h" | 40 | #include "cx22702.h" |
43 | #include "or51132.h" | 41 | #include "or51132.h" |
@@ -199,7 +197,7 @@ static struct mt352_config dvico_fusionhdtv_dual = { | |||
199 | .demod_init = dvico_dual_demod_init, | 197 | .demod_init = dvico_dual_demod_init, |
200 | }; | 198 | }; |
201 | 199 | ||
202 | #if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE) | 200 | #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) |
203 | static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) | 201 | static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) |
204 | { | 202 | { |
205 | static u8 clock_config [] = { 0x89, 0x38, 0x38 }; | 203 | static u8 clock_config [] = { 0x89, 0x38, 0x38 }; |
@@ -223,64 +221,6 @@ static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) | |||
223 | return 0; | 221 | return 0; |
224 | } | 222 | } |
225 | 223 | ||
226 | static int philips_fmd1216_pll_init(struct dvb_frontend *fe) | ||
227 | { | ||
228 | struct cx8802_dev *dev= fe->dvb->priv; | ||
229 | |||
230 | /* this message is to set up ATC and ALC */ | ||
231 | static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; | ||
232 | struct i2c_msg msg = | ||
233 | { .addr = dev->core->pll_addr, .flags = 0, | ||
234 | .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; | ||
235 | int err; | ||
236 | |||
237 | if (fe->ops.i2c_gate_ctrl) | ||
238 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
239 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | ||
240 | if (err < 0) | ||
241 | return err; | ||
242 | else | ||
243 | return -EREMOTEIO; | ||
244 | } | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int dntv_live_dvbt_pro_tuner_set_params(struct dvb_frontend* fe, | ||
250 | struct dvb_frontend_parameters* params) | ||
251 | { | ||
252 | struct cx8802_dev *dev= fe->dvb->priv; | ||
253 | u8 buf[4]; | ||
254 | struct i2c_msg msg = | ||
255 | { .addr = dev->core->pll_addr, .flags = 0, | ||
256 | .buf = buf, .len = 4 }; | ||
257 | int err; | ||
258 | |||
259 | /* Switch PLL to DVB mode */ | ||
260 | err = philips_fmd1216_pll_init(fe); | ||
261 | if (err) | ||
262 | return err; | ||
263 | |||
264 | /* Tune PLL */ | ||
265 | dvb_pll_configure(dev->core->pll_desc, buf, | ||
266 | params->frequency, | ||
267 | params->u.ofdm.bandwidth); | ||
268 | if (fe->ops.i2c_gate_ctrl) | ||
269 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
270 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | ||
271 | |||
272 | printk(KERN_WARNING "cx88-dvb: %s error " | ||
273 | "(addr %02x <- %02x, err = %i)\n", | ||
274 | __FUNCTION__, dev->core->pll_addr, buf[0], err); | ||
275 | if (err < 0) | ||
276 | return err; | ||
277 | else | ||
278 | return -EREMOTEIO; | ||
279 | } | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static struct mt352_config dntv_live_dvbt_pro_config = { | 224 | static struct mt352_config dntv_live_dvbt_pro_config = { |
285 | .demod_address = 0x0f, | 225 | .demod_address = 0x0f, |
286 | .no_tuner = 1, | 226 | .no_tuner = 1, |
@@ -370,18 +310,8 @@ static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured) | |||
370 | return 0; | 310 | return 0; |
371 | } | 311 | } |
372 | 312 | ||
373 | static int nxt200x_set_pll_input(u8* buf, int input) | ||
374 | { | ||
375 | if (input) | ||
376 | buf[3] |= 0x08; | ||
377 | else | ||
378 | buf[3] &= ~0x08; | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | static struct nxt200x_config ati_hdtvwonder = { | 313 | static struct nxt200x_config ati_hdtvwonder = { |
383 | .demod_address = 0x0a, | 314 | .demod_address = 0x0a, |
384 | .set_pll_input = nxt200x_set_pll_input, | ||
385 | .set_ts_params = nxt200x_set_ts_param, | 315 | .set_ts_params = nxt200x_set_ts_param, |
386 | }; | 316 | }; |
387 | 317 | ||
@@ -456,7 +386,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
456 | if (dev->dvb.frontend != NULL) { | 386 | if (dev->dvb.frontend != NULL) { |
457 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 387 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
458 | &dev->core->i2c_adap, | 388 | &dev->core->i2c_adap, |
459 | &dvb_pll_thomson_dtt759x); | 389 | DVB_PLL_THOMSON_DTT759X); |
460 | } | 390 | } |
461 | break; | 391 | break; |
462 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: | 392 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: |
@@ -469,7 +399,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
469 | if (dev->dvb.frontend != NULL) { | 399 | if (dev->dvb.frontend != NULL) { |
470 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, | 400 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, |
471 | &dev->core->i2c_adap, | 401 | &dev->core->i2c_adap, |
472 | &dvb_pll_thomson_dtt7579); | 402 | DVB_PLL_THOMSON_DTT7579); |
473 | } | 403 | } |
474 | break; | 404 | break; |
475 | case CX88_BOARD_WINFAST_DTV2000H: | 405 | case CX88_BOARD_WINFAST_DTV2000H: |
@@ -482,7 +412,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
482 | &dev->core->i2c_adap); | 412 | &dev->core->i2c_adap); |
483 | if (dev->dvb.frontend != NULL) { | 413 | if (dev->dvb.frontend != NULL) { |
484 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 414 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
485 | &dev->core->i2c_adap, &dvb_pll_fmd1216me); | 415 | &dev->core->i2c_adap, DVB_PLL_FMD1216ME); |
486 | } | 416 | } |
487 | break; | 417 | break; |
488 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: | 418 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: |
@@ -491,7 +421,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
491 | &dev->core->i2c_adap); | 421 | &dev->core->i2c_adap); |
492 | if (dev->dvb.frontend != NULL) { | 422 | if (dev->dvb.frontend != NULL) { |
493 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, | 423 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, |
494 | NULL, &dvb_pll_thomson_dtt7579); | 424 | NULL, DVB_PLL_THOMSON_DTT7579); |
495 | break; | 425 | break; |
496 | } | 426 | } |
497 | /* ZL10353 replaces MT352 on later cards */ | 427 | /* ZL10353 replaces MT352 on later cards */ |
@@ -500,7 +430,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
500 | &dev->core->i2c_adap); | 430 | &dev->core->i2c_adap); |
501 | if (dev->dvb.frontend != NULL) { | 431 | if (dev->dvb.frontend != NULL) { |
502 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, | 432 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, |
503 | NULL, &dvb_pll_thomson_dtt7579); | 433 | NULL, DVB_PLL_THOMSON_DTT7579); |
504 | } | 434 | } |
505 | break; | 435 | break; |
506 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: | 436 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: |
@@ -511,7 +441,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
511 | &dev->core->i2c_adap); | 441 | &dev->core->i2c_adap); |
512 | if (dev->dvb.frontend != NULL) { | 442 | if (dev->dvb.frontend != NULL) { |
513 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 443 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
514 | NULL, &dvb_pll_thomson_dtt7579); | 444 | NULL, DVB_PLL_THOMSON_DTT7579); |
515 | break; | 445 | break; |
516 | } | 446 | } |
517 | /* ZL10353 replaces MT352 on later cards */ | 447 | /* ZL10353 replaces MT352 on later cards */ |
@@ -520,7 +450,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
520 | &dev->core->i2c_adap); | 450 | &dev->core->i2c_adap); |
521 | if (dev->dvb.frontend != NULL) { | 451 | if (dev->dvb.frontend != NULL) { |
522 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 452 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
523 | NULL, &dvb_pll_thomson_dtt7579); | 453 | NULL, DVB_PLL_THOMSON_DTT7579); |
524 | } | 454 | } |
525 | break; | 455 | break; |
526 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: | 456 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: |
@@ -529,7 +459,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
529 | &dev->core->i2c_adap); | 459 | &dev->core->i2c_adap); |
530 | if (dev->dvb.frontend != NULL) { | 460 | if (dev->dvb.frontend != NULL) { |
531 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 461 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
532 | NULL, &dvb_pll_lg_z201); | 462 | NULL, DVB_PLL_LG_Z201); |
533 | } | 463 | } |
534 | break; | 464 | break; |
535 | case CX88_BOARD_KWORLD_DVB_T: | 465 | case CX88_BOARD_KWORLD_DVB_T: |
@@ -540,17 +470,16 @@ static int dvb_register(struct cx8802_dev *dev) | |||
540 | &dev->core->i2c_adap); | 470 | &dev->core->i2c_adap); |
541 | if (dev->dvb.frontend != NULL) { | 471 | if (dev->dvb.frontend != NULL) { |
542 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 472 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
543 | NULL, &dvb_pll_unknown_1); | 473 | NULL, DVB_PLL_UNKNOWN_1); |
544 | } | 474 | } |
545 | break; | 475 | break; |
546 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: | 476 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: |
547 | #if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE) | 477 | #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) |
548 | dev->core->pll_addr = 0x61; | ||
549 | dev->core->pll_desc = &dvb_pll_fmd1216me; | ||
550 | dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, | 478 | dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, |
551 | &((struct vp3054_i2c_state *)dev->card_priv)->adap); | 479 | &((struct vp3054_i2c_state *)dev->card_priv)->adap); |
552 | if (dev->dvb.frontend != NULL) { | 480 | if (dev->dvb.frontend != NULL) { |
553 | dev->dvb.frontend->ops.tuner_ops.set_params = dntv_live_dvbt_pro_tuner_set_params; | 481 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
482 | &dev->core->i2c_adap, DVB_PLL_FMD1216ME); | ||
554 | } | 483 | } |
555 | #else | 484 | #else |
556 | printk("%s: built without vp3054 support\n", dev->core->name); | 485 | printk("%s: built without vp3054 support\n", dev->core->name); |
@@ -563,7 +492,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
563 | if (dev->dvb.frontend != NULL) { | 492 | if (dev->dvb.frontend != NULL) { |
564 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 493 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
565 | &dev->core->i2c_adap, | 494 | &dev->core->i2c_adap, |
566 | &dvb_pll_thomson_fe6600); | 495 | DVB_PLL_THOMSON_FE6600); |
567 | } | 496 | } |
568 | break; | 497 | break; |
569 | case CX88_BOARD_PCHDTV_HD3000: | 498 | case CX88_BOARD_PCHDTV_HD3000: |
@@ -572,7 +501,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
572 | if (dev->dvb.frontend != NULL) { | 501 | if (dev->dvb.frontend != NULL) { |
573 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 502 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
574 | &dev->core->i2c_adap, | 503 | &dev->core->i2c_adap, |
575 | &dvb_pll_thomson_dtt761x); | 504 | DVB_PLL_THOMSON_DTT761X); |
576 | } | 505 | } |
577 | break; | 506 | break; |
578 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: | 507 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: |
@@ -594,7 +523,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
594 | if (dev->dvb.frontend != NULL) { | 523 | if (dev->dvb.frontend != NULL) { |
595 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 524 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
596 | &dev->core->i2c_adap, | 525 | &dev->core->i2c_adap, |
597 | &dvb_pll_microtune_4042); | 526 | DVB_PLL_MICROTUNE_4042); |
598 | } | 527 | } |
599 | } | 528 | } |
600 | break; | 529 | break; |
@@ -614,7 +543,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
614 | if (dev->dvb.frontend != NULL) { | 543 | if (dev->dvb.frontend != NULL) { |
615 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 544 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
616 | &dev->core->i2c_adap, | 545 | &dev->core->i2c_adap, |
617 | &dvb_pll_thomson_dtt761x); | 546 | DVB_PLL_THOMSON_DTT761X); |
618 | } | 547 | } |
619 | } | 548 | } |
620 | break; | 549 | break; |
@@ -634,7 +563,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
634 | if (dev->dvb.frontend != NULL) { | 563 | if (dev->dvb.frontend != NULL) { |
635 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 564 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
636 | &dev->core->i2c_adap, | 565 | &dev->core->i2c_adap, |
637 | &dvb_pll_lg_tdvs_h06xf); | 566 | DVB_PLL_LG_TDVS_H06XF); |
638 | } | 567 | } |
639 | } | 568 | } |
640 | break; | 569 | break; |
@@ -654,7 +583,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
654 | if (dev->dvb.frontend != NULL) { | 583 | if (dev->dvb.frontend != NULL) { |
655 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 584 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
656 | &dev->core->i2c_adap, | 585 | &dev->core->i2c_adap, |
657 | &dvb_pll_lg_tdvs_h06xf); | 586 | DVB_PLL_LG_TDVS_H06XF); |
658 | } | 587 | } |
659 | } | 588 | } |
660 | break; | 589 | break; |
@@ -664,7 +593,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
664 | &dev->core->i2c_adap); | 593 | &dev->core->i2c_adap); |
665 | if (dev->dvb.frontend != NULL) { | 594 | if (dev->dvb.frontend != NULL) { |
666 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 595 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
667 | NULL, &dvb_pll_tuv1236d); | 596 | NULL, DVB_PLL_TUV1236D); |
668 | } | 597 | } |
669 | break; | 598 | break; |
670 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | 599 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: |
@@ -705,10 +634,6 @@ static int dvb_register(struct cx8802_dev *dev) | |||
705 | return -1; | 634 | return -1; |
706 | } | 635 | } |
707 | 636 | ||
708 | if (dev->core->pll_desc) { | ||
709 | dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min; | ||
710 | dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max; | ||
711 | } | ||
712 | /* Ensure all frontends negotiate bus access */ | 637 | /* Ensure all frontends negotiate bus access */ |
713 | dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; | 638 | dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; |
714 | 639 | ||
@@ -778,11 +703,10 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) | |||
778 | if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB)) | 703 | if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB)) |
779 | goto fail_core; | 704 | goto fail_core; |
780 | 705 | ||
781 | #if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE) | 706 | /* If vp3054 isn't enabled, a stub will just return 0 */ |
782 | err = vp3054_i2c_probe(dev); | 707 | err = vp3054_i2c_probe(dev); |
783 | if (0 != err) | 708 | if (0 != err) |
784 | goto fail_core; | 709 | goto fail_core; |
785 | #endif | ||
786 | 710 | ||
787 | /* dvb stuff */ | 711 | /* dvb stuff */ |
788 | printk("%s/2: cx2388x based dvb card\n", core->name); | 712 | printk("%s/2: cx2388x based dvb card\n", core->name); |
@@ -807,9 +731,7 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv) | |||
807 | /* dvb */ | 731 | /* dvb */ |
808 | videobuf_dvb_unregister(&dev->dvb); | 732 | videobuf_dvb_unregister(&dev->dvb); |
809 | 733 | ||
810 | #if defined(CONFIG_VIDEO_CX88_VP3054) || defined(CONFIG_VIDEO_CX88_VP3054_MODULE) | ||
811 | vp3054_i2c_remove(dev); | 734 | vp3054_i2c_remove(dev); |
812 | #endif | ||
813 | 735 | ||
814 | return 0; | 736 | return 0; |
815 | } | 737 | } |
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 7919a1f9da06..78bbcfab9670 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -160,7 +160,7 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) | |||
160 | i2c_clients_command(&core->i2c_adap, cmd, arg); | 160 | i2c_clients_command(&core->i2c_adap, cmd, arg); |
161 | } | 161 | } |
162 | 162 | ||
163 | static struct i2c_algo_bit_data cx8800_i2c_algo_template = { | 163 | static const struct i2c_algo_bit_data cx8800_i2c_algo_template = { |
164 | .setsda = cx8800_bit_setsda, | 164 | .setsda = cx8800_bit_setsda, |
165 | .setscl = cx8800_bit_setscl, | 165 | .setscl = cx8800_bit_setscl, |
166 | .getsda = cx8800_bit_getsda, | 166 | .getsda = cx8800_bit_getsda, |
@@ -171,18 +171,6 @@ static struct i2c_algo_bit_data cx8800_i2c_algo_template = { | |||
171 | 171 | ||
172 | /* ----------------------------------------------------------------------- */ | 172 | /* ----------------------------------------------------------------------- */ |
173 | 173 | ||
174 | static struct i2c_adapter cx8800_i2c_adap_template = { | ||
175 | .name = "cx2388x", | ||
176 | .owner = THIS_MODULE, | ||
177 | .id = I2C_HW_B_CX2388x, | ||
178 | .client_register = attach_inform, | ||
179 | .client_unregister = detach_inform, | ||
180 | }; | ||
181 | |||
182 | static struct i2c_client cx8800_i2c_client_template = { | ||
183 | .name = "cx88xx internal", | ||
184 | }; | ||
185 | |||
186 | static char *i2c_devs[128] = { | 174 | static char *i2c_devs[128] = { |
187 | [ 0x1c >> 1 ] = "lgdt330x", | 175 | [ 0x1c >> 1 ] = "lgdt330x", |
188 | [ 0x86 >> 1 ] = "tda9887/cx22702", | 176 | [ 0x86 >> 1 ] = "tda9887/cx22702", |
@@ -212,14 +200,9 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) | |||
212 | /* Prevents usage of invalid delay values */ | 200 | /* Prevents usage of invalid delay values */ |
213 | if (i2c_udelay<5) | 201 | if (i2c_udelay<5) |
214 | i2c_udelay=5; | 202 | i2c_udelay=5; |
215 | cx8800_i2c_algo_template.udelay=i2c_udelay; | ||
216 | 203 | ||
217 | memcpy(&core->i2c_adap, &cx8800_i2c_adap_template, | ||
218 | sizeof(core->i2c_adap)); | ||
219 | memcpy(&core->i2c_algo, &cx8800_i2c_algo_template, | 204 | memcpy(&core->i2c_algo, &cx8800_i2c_algo_template, |
220 | sizeof(core->i2c_algo)); | 205 | sizeof(core->i2c_algo)); |
221 | memcpy(&core->i2c_client, &cx8800_i2c_client_template, | ||
222 | sizeof(core->i2c_client)); | ||
223 | 206 | ||
224 | if (core->tuner_type != TUNER_ABSENT) | 207 | if (core->tuner_type != TUNER_ABSENT) |
225 | core->i2c_adap.class |= I2C_CLASS_TV_ANALOG; | 208 | core->i2c_adap.class |= I2C_CLASS_TV_ANALOG; |
@@ -228,10 +211,16 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) | |||
228 | 211 | ||
229 | core->i2c_adap.dev.parent = &pci->dev; | 212 | core->i2c_adap.dev.parent = &pci->dev; |
230 | strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); | 213 | strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); |
214 | core->i2c_adap.owner = THIS_MODULE; | ||
215 | core->i2c_adap.id = I2C_HW_B_CX2388x; | ||
216 | core->i2c_adap.client_register = attach_inform; | ||
217 | core->i2c_adap.client_unregister = detach_inform; | ||
218 | core->i2c_algo.udelay = i2c_udelay; | ||
231 | core->i2c_algo.data = core; | 219 | core->i2c_algo.data = core; |
232 | i2c_set_adapdata(&core->i2c_adap,core); | 220 | i2c_set_adapdata(&core->i2c_adap,core); |
233 | core->i2c_adap.algo_data = &core->i2c_algo; | 221 | core->i2c_adap.algo_data = &core->i2c_algo; |
234 | core->i2c_client.adapter = &core->i2c_adap; | 222 | core->i2c_client.adapter = &core->i2c_adap; |
223 | strlcpy(core->i2c_client.name, "cx88xx internal", I2C_NAME_SIZE); | ||
235 | 224 | ||
236 | cx8800_bit_setscl(core,1); | 225 | cx8800_bit_setscl(core,1); |
237 | cx8800_bit_setsda(core,1); | 226 | cx8800_bit_setsda(core,1); |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 8136673fe9e8..f5d4a565346e 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -74,7 +74,8 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) | |||
74 | 74 | ||
75 | /* read gpio value */ | 75 | /* read gpio value */ |
76 | gpio = cx_read(ir->gpio_addr); | 76 | gpio = cx_read(ir->gpio_addr); |
77 | if (core->board == CX88_BOARD_NPGTECH_REALTV_TOP10FM) { | 77 | switch (core->board) { |
78 | case CX88_BOARD_NPGTECH_REALTV_TOP10FM: | ||
78 | /* This board apparently uses a combination of 2 GPIO | 79 | /* This board apparently uses a combination of 2 GPIO |
79 | to represent the keys. Additionally, the second GPIO | 80 | to represent the keys. Additionally, the second GPIO |
80 | can be used for parity. | 81 | can be used for parity. |
@@ -90,9 +91,14 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) | |||
90 | auxgpio = cx_read(MO_GP1_IO); | 91 | auxgpio = cx_read(MO_GP1_IO); |
91 | /* Take out the parity part */ | 92 | /* Take out the parity part */ |
92 | gpio=(gpio & 0x7fd) + (auxgpio & 0xef); | 93 | gpio=(gpio & 0x7fd) + (auxgpio & 0xef); |
93 | } else | 94 | break; |
95 | case CX88_BOARD_WINFAST_DTV1000: | ||
96 | gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900); | ||
94 | auxgpio = gpio; | 97 | auxgpio = gpio; |
95 | 98 | break; | |
99 | default: | ||
100 | auxgpio = gpio; | ||
101 | } | ||
96 | if (ir->polling) { | 102 | if (ir->polling) { |
97 | if (ir->last_gpio == auxgpio) | 103 | if (ir->last_gpio == auxgpio) |
98 | return; | 104 | return; |
@@ -148,20 +154,16 @@ static void ir_timer(unsigned long data) | |||
148 | static void cx88_ir_work(struct work_struct *work) | 154 | static void cx88_ir_work(struct work_struct *work) |
149 | { | 155 | { |
150 | struct cx88_IR *ir = container_of(work, struct cx88_IR, work); | 156 | struct cx88_IR *ir = container_of(work, struct cx88_IR, work); |
151 | unsigned long timeout; | ||
152 | 157 | ||
153 | cx88_ir_handle_key(ir); | 158 | cx88_ir_handle_key(ir); |
154 | timeout = jiffies + (ir->polling * HZ / 1000); | 159 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); |
155 | mod_timer(&ir->timer, timeout); | ||
156 | } | 160 | } |
157 | 161 | ||
158 | static void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) | 162 | static void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) |
159 | { | 163 | { |
160 | if (ir->polling) { | 164 | if (ir->polling) { |
165 | setup_timer(&ir->timer, ir_timer, (unsigned long)ir); | ||
161 | INIT_WORK(&ir->work, cx88_ir_work); | 166 | INIT_WORK(&ir->work, cx88_ir_work); |
162 | init_timer(&ir->timer); | ||
163 | ir->timer.function = ir_timer; | ||
164 | ir->timer.data = (unsigned long)ir; | ||
165 | schedule_work(&ir->work); | 167 | schedule_work(&ir->work); |
166 | } | 168 | } |
167 | if (ir->sampling) { | 169 | if (ir->sampling) { |
@@ -222,7 +224,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
222 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | 224 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: |
223 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | 225 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: |
224 | case CX88_BOARD_HAUPPAUGE_HVR1100: | 226 | case CX88_BOARD_HAUPPAUGE_HVR1100: |
225 | case CX88_BOARD_HAUPPAUGE_HVR1300: | ||
226 | case CX88_BOARD_HAUPPAUGE_HVR3000: | 227 | case CX88_BOARD_HAUPPAUGE_HVR3000: |
227 | ir_codes = ir_codes_hauppauge_new; | 228 | ir_codes = ir_codes_hauppauge_new; |
228 | ir_type = IR_TYPE_RC5; | 229 | ir_type = IR_TYPE_RC5; |
@@ -236,6 +237,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
236 | ir->polling = 50; /* ms */ | 237 | ir->polling = 50; /* ms */ |
237 | break; | 238 | break; |
238 | case CX88_BOARD_WINFAST2000XP_EXPERT: | 239 | case CX88_BOARD_WINFAST2000XP_EXPERT: |
240 | case CX88_BOARD_WINFAST_DTV1000: | ||
239 | ir_codes = ir_codes_winfast; | 241 | ir_codes = ir_codes_winfast; |
240 | ir->gpio_addr = MO_GP0_IO; | 242 | ir->gpio_addr = MO_GP0_IO; |
241 | ir->mask_keycode = 0x8f8; | 243 | ir->mask_keycode = 0x8f8; |
@@ -328,7 +330,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
328 | input_dev->id.vendor = pci->vendor; | 330 | input_dev->id.vendor = pci->vendor; |
329 | input_dev->id.product = pci->device; | 331 | input_dev->id.product = pci->device; |
330 | } | 332 | } |
331 | input_dev->cdev.dev = &pci->dev; | 333 | input_dev->dev.parent = &pci->dev; |
332 | /* record handles to ourself */ | 334 | /* record handles to ourself */ |
333 | ir->core = core; | 335 | ir->core = core; |
334 | core->ir = ir; | 336 | core->ir = ir; |
@@ -442,7 +444,6 @@ void cx88_ir_irq(struct cx88_core *core) | |||
442 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | 444 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: |
443 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: | 445 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: |
444 | case CX88_BOARD_HAUPPAUGE_HVR1100: | 446 | case CX88_BOARD_HAUPPAUGE_HVR1100: |
445 | case CX88_BOARD_HAUPPAUGE_HVR1300: | ||
446 | case CX88_BOARD_HAUPPAUGE_HVR3000: | 447 | case CX88_BOARD_HAUPPAUGE_HVR3000: |
447 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); | 448 | ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); |
448 | ir_dprintk("biphase decoded: %x\n", ircode); | 449 | ir_dprintk("biphase decoded: %x\n", ircode); |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 543b05ebc0e7..317a2a3f9cc1 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -336,7 +336,7 @@ static void cx8802_timeout(unsigned long data) | |||
336 | { | 336 | { |
337 | struct cx8802_dev *dev = (struct cx8802_dev*)data; | 337 | struct cx8802_dev *dev = (struct cx8802_dev*)data; |
338 | 338 | ||
339 | dprintk(0, "%s\n",__FUNCTION__); | 339 | dprintk(1, "%s\n",__FUNCTION__); |
340 | 340 | ||
341 | if (debug) | 341 | if (debug) |
342 | cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); | 342 | cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); |
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c index 82bc3a28aa22..cd0877636a32 100644 --- a/drivers/media/video/cx88/cx88-vp3054-i2c.c +++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c | |||
@@ -94,7 +94,7 @@ static int vp3054_bit_getsda(void *data) | |||
94 | 94 | ||
95 | /* ----------------------------------------------------------------------- */ | 95 | /* ----------------------------------------------------------------------- */ |
96 | 96 | ||
97 | static struct i2c_algo_bit_data vp3054_i2c_algo_template = { | 97 | static const struct i2c_algo_bit_data vp3054_i2c_algo_template = { |
98 | .setsda = vp3054_bit_setsda, | 98 | .setsda = vp3054_bit_setsda, |
99 | .setscl = vp3054_bit_setscl, | 99 | .setscl = vp3054_bit_setscl, |
100 | .getsda = vp3054_bit_getsda, | 100 | .getsda = vp3054_bit_getsda, |
@@ -105,12 +105,6 @@ static struct i2c_algo_bit_data vp3054_i2c_algo_template = { | |||
105 | 105 | ||
106 | /* ----------------------------------------------------------------------- */ | 106 | /* ----------------------------------------------------------------------- */ |
107 | 107 | ||
108 | static struct i2c_adapter vp3054_i2c_adap_template = { | ||
109 | .name = "cx2388x", | ||
110 | .owner = THIS_MODULE, | ||
111 | .id = I2C_HW_B_CX2388x, | ||
112 | }; | ||
113 | |||
114 | int vp3054_i2c_probe(struct cx8802_dev *dev) | 108 | int vp3054_i2c_probe(struct cx8802_dev *dev) |
115 | { | 109 | { |
116 | struct cx88_core *core = dev->core; | 110 | struct cx88_core *core = dev->core; |
@@ -125,8 +119,6 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) | |||
125 | return -ENOMEM; | 119 | return -ENOMEM; |
126 | vp3054_i2c = dev->card_priv; | 120 | vp3054_i2c = dev->card_priv; |
127 | 121 | ||
128 | memcpy(&vp3054_i2c->adap, &vp3054_i2c_adap_template, | ||
129 | sizeof(vp3054_i2c->adap)); | ||
130 | memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template, | 122 | memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template, |
131 | sizeof(vp3054_i2c->algo)); | 123 | sizeof(vp3054_i2c->algo)); |
132 | 124 | ||
@@ -135,6 +127,8 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) | |||
135 | vp3054_i2c->adap.dev.parent = &dev->pci->dev; | 127 | vp3054_i2c->adap.dev.parent = &dev->pci->dev; |
136 | strlcpy(vp3054_i2c->adap.name, core->name, | 128 | strlcpy(vp3054_i2c->adap.name, core->name, |
137 | sizeof(vp3054_i2c->adap.name)); | 129 | sizeof(vp3054_i2c->adap.name)); |
130 | vp3054_i2c->adap.owner = THIS_MODULE; | ||
131 | vp3054_i2c->adap.id = I2C_HW_B_CX2388x; | ||
138 | vp3054_i2c->algo.data = dev; | 132 | vp3054_i2c->algo.data = dev; |
139 | i2c_set_adapdata(&vp3054_i2c->adap, dev); | 133 | i2c_set_adapdata(&vp3054_i2c->adap, dev); |
140 | vp3054_i2c->adap.algo_data = &vp3054_i2c->algo; | 134 | vp3054_i2c->adap.algo_data = &vp3054_i2c->algo; |
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.h b/drivers/media/video/cx88/cx88-vp3054-i2c.h index 637a7d232238..be99c931dc3e 100644 --- a/drivers/media/video/cx88/cx88-vp3054-i2c.h +++ b/drivers/media/video/cx88/cx88-vp3054-i2c.h | |||
@@ -30,5 +30,12 @@ struct vp3054_i2c_state { | |||
30 | }; | 30 | }; |
31 | 31 | ||
32 | /* ----------------------------------------------------------------------- */ | 32 | /* ----------------------------------------------------------------------- */ |
33 | #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) | ||
33 | int vp3054_i2c_probe(struct cx8802_dev *dev); | 34 | int vp3054_i2c_probe(struct cx8802_dev *dev); |
34 | void vp3054_i2c_remove(struct cx8802_dev *dev); | 35 | void vp3054_i2c_remove(struct cx8802_dev *dev); |
36 | #else | ||
37 | static inline int vp3054_i2c_probe(struct cx8802_dev *dev) | ||
38 | { return 0; } | ||
39 | static inline void vp3054_i2c_remove(struct cx8802_dev *dev) | ||
40 | { } | ||
41 | #endif | ||
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 738d4f20c580..c4f656ec46b0 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -209,6 +209,7 @@ extern struct sram_channel cx88_sram_channels[]; | |||
209 | #define CX88_BOARD_NORWOOD_MICRO 54 | 209 | #define CX88_BOARD_NORWOOD_MICRO 54 |
210 | #define CX88_BOARD_TE_DTV_250_OEM_SWANN 55 | 210 | #define CX88_BOARD_TE_DTV_250_OEM_SWANN 55 |
211 | #define CX88_BOARD_HAUPPAUGE_HVR1300 56 | 211 | #define CX88_BOARD_HAUPPAUGE_HVR1300 56 |
212 | #define CX88_BOARD_ADSTECH_PTV_390 57 | ||
212 | 213 | ||
213 | enum cx88_itype { | 214 | enum cx88_itype { |
214 | CX88_VMUX_COMPOSITE1 = 1, | 215 | CX88_VMUX_COMPOSITE1 = 1, |
@@ -316,8 +317,6 @@ struct cx88_core { | |||
316 | 317 | ||
317 | /* config info -- dvb */ | 318 | /* config info -- dvb */ |
318 | #if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE) | 319 | #if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE) |
319 | struct dvb_pll_desc *pll_desc; | ||
320 | unsigned int pll_addr; | ||
321 | int (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); | 320 | int (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); |
322 | #endif | 321 | #endif |
323 | 322 | ||
@@ -463,13 +462,10 @@ struct cx8802_dev { | |||
463 | u32 mailbox; | 462 | u32 mailbox; |
464 | int width; | 463 | int width; |
465 | int height; | 464 | int height; |
466 | int fw_size; | ||
467 | 465 | ||
468 | #if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE) | 466 | #if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE) |
469 | /* for dvb only */ | 467 | /* for dvb only */ |
470 | struct videobuf_dvb dvb; | 468 | struct videobuf_dvb dvb; |
471 | void* fe_handle; | ||
472 | int (*fe_release)(void *handle); | ||
473 | 469 | ||
474 | void *card_priv; | 470 | void *card_priv; |
475 | #endif | 471 | #endif |
diff --git a/drivers/media/video/et61x251/Kconfig b/drivers/media/video/et61x251/Kconfig index 664676f44068..dcc1a0335440 100644 --- a/drivers/media/video/et61x251/Kconfig +++ b/drivers/media/video/et61x251/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config USB_ET61X251 | 1 | config USB_ET61X251 |
2 | tristate "USB ET61X[12]51 PC Camera Controller support" | 2 | tristate "USB ET61X[12]51 PC Camera Controller support" |
3 | depends on VIDEO_V4L1 | 3 | depends on VIDEO_V4L2 |
4 | ---help--- | 4 | ---help--- |
5 | Say Y here if you want support for cameras based on Etoms ET61X151 | 5 | Say Y here if you want support for cameras based on Etoms ET61X151 |
6 | or ET61X251 PC Camera Controllers. | 6 | or ET61X251 PC Camera Controllers. |
diff --git a/drivers/media/video/et61x251/et61x251.h b/drivers/media/video/et61x251/et61x251.h index 262f98e12409..02c741d8f85a 100644 --- a/drivers/media/video/et61x251/et61x251.h +++ b/drivers/media/video/et61x251/et61x251.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/stddef.h> | 37 | #include <linux/stddef.h> |
38 | #include <linux/string.h> | 38 | #include <linux/string.h> |
39 | #include <linux/kref.h> | ||
39 | 40 | ||
40 | #include "et61x251_sensor.h" | 41 | #include "et61x251_sensor.h" |
41 | 42 | ||
@@ -134,7 +135,7 @@ struct et61x251_module_param { | |||
134 | }; | 135 | }; |
135 | 136 | ||
136 | static DEFINE_MUTEX(et61x251_sysfs_lock); | 137 | static DEFINE_MUTEX(et61x251_sysfs_lock); |
137 | static DECLARE_RWSEM(et61x251_disconnect); | 138 | static DECLARE_RWSEM(et61x251_dev_lock); |
138 | 139 | ||
139 | struct et61x251_device { | 140 | struct et61x251_device { |
140 | struct video_device* v4ldev; | 141 | struct video_device* v4ldev; |
@@ -158,12 +159,14 @@ struct et61x251_device { | |||
158 | struct et61x251_sysfs_attr sysfs; | 159 | struct et61x251_sysfs_attr sysfs; |
159 | struct et61x251_module_param module_param; | 160 | struct et61x251_module_param module_param; |
160 | 161 | ||
162 | struct kref kref; | ||
161 | enum et61x251_dev_state state; | 163 | enum et61x251_dev_state state; |
162 | u8 users; | 164 | u8 users; |
163 | 165 | ||
164 | struct mutex dev_mutex, fileop_mutex; | 166 | struct completion probe; |
167 | struct mutex open_mutex, fileop_mutex; | ||
165 | spinlock_t queue_lock; | 168 | spinlock_t queue_lock; |
166 | wait_queue_head_t open, wait_frame, wait_stream; | 169 | wait_queue_head_t wait_open, wait_frame, wait_stream; |
167 | }; | 170 | }; |
168 | 171 | ||
169 | /*****************************************************************************/ | 172 | /*****************************************************************************/ |
@@ -177,7 +180,7 @@ et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id) | |||
177 | 180 | ||
178 | void | 181 | void |
179 | et61x251_attach_sensor(struct et61x251_device* cam, | 182 | et61x251_attach_sensor(struct et61x251_device* cam, |
180 | struct et61x251_sensor* sensor) | 183 | const struct et61x251_sensor* sensor) |
181 | { | 184 | { |
182 | memcpy(&cam->sensor, sensor, sizeof(struct et61x251_sensor)); | 185 | memcpy(&cam->sensor, sensor, sizeof(struct et61x251_sensor)); |
183 | } | 186 | } |
@@ -195,8 +198,8 @@ do { \ | |||
195 | else if ((level) == 2) \ | 198 | else if ((level) == 2) \ |
196 | dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ | 199 | dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ |
197 | else if ((level) >= 3) \ | 200 | else if ((level) >= 3) \ |
198 | dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ | 201 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \ |
199 | __FUNCTION__, __LINE__ , ## args); \ | 202 | __FILE__, __FUNCTION__, __LINE__ , ## args); \ |
200 | } \ | 203 | } \ |
201 | } while (0) | 204 | } while (0) |
202 | # define KDBG(level, fmt, args...) \ | 205 | # define KDBG(level, fmt, args...) \ |
@@ -205,8 +208,8 @@ do { \ | |||
205 | if ((level) == 1 || (level) == 2) \ | 208 | if ((level) == 1 || (level) == 2) \ |
206 | pr_info("et61x251: " fmt "\n", ## args); \ | 209 | pr_info("et61x251: " fmt "\n", ## args); \ |
207 | else if ((level) == 3) \ | 210 | else if ((level) == 3) \ |
208 | pr_debug("et61x251: [%s:%d] " fmt "\n", __FUNCTION__, \ | 211 | pr_debug("sn9c102: [%s:%s:%d] " fmt "\n", __FILE__, \ |
209 | __LINE__ , ## args); \ | 212 | __FUNCTION__, __LINE__ , ## args); \ |
210 | } \ | 213 | } \ |
211 | } while (0) | 214 | } while (0) |
212 | # define V4LDBG(level, name, cmd) \ | 215 | # define V4LDBG(level, name, cmd) \ |
@@ -222,8 +225,8 @@ do { \ | |||
222 | 225 | ||
223 | #undef PDBG | 226 | #undef PDBG |
224 | #define PDBG(fmt, args...) \ | 227 | #define PDBG(fmt, args...) \ |
225 | dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ | 228 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \ |
226 | __FUNCTION__, __LINE__ , ## args) | 229 | __LINE__ , ## args) |
227 | 230 | ||
228 | #undef PDBGG | 231 | #undef PDBGG |
229 | #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ | 232 | #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ |
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index a6525513cd1e..585bd1fe0765 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c | |||
@@ -45,11 +45,11 @@ | |||
45 | 45 | ||
46 | #define ET61X251_MODULE_NAME "V4L2 driver for ET61X[12]51 " \ | 46 | #define ET61X251_MODULE_NAME "V4L2 driver for ET61X[12]51 " \ |
47 | "PC Camera Controllers" | 47 | "PC Camera Controllers" |
48 | #define ET61X251_MODULE_AUTHOR "(C) 2006 Luca Risolia" | 48 | #define ET61X251_MODULE_AUTHOR "(C) 2006-2007 Luca Risolia" |
49 | #define ET61X251_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" | 49 | #define ET61X251_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" |
50 | #define ET61X251_MODULE_LICENSE "GPL" | 50 | #define ET61X251_MODULE_LICENSE "GPL" |
51 | #define ET61X251_MODULE_VERSION "1:1.04" | 51 | #define ET61X251_MODULE_VERSION "1:1.09" |
52 | #define ET61X251_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 4) | 52 | #define ET61X251_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 9) |
53 | 53 | ||
54 | /*****************************************************************************/ | 54 | /*****************************************************************************/ |
55 | 55 | ||
@@ -245,7 +245,8 @@ int et61x251_read_reg(struct et61x251_device* cam, u16 index) | |||
245 | 245 | ||
246 | 246 | ||
247 | static int | 247 | static int |
248 | et61x251_i2c_wait(struct et61x251_device* cam, struct et61x251_sensor* sensor) | 248 | et61x251_i2c_wait(struct et61x251_device* cam, |
249 | const struct et61x251_sensor* sensor) | ||
249 | { | 250 | { |
250 | int i, r; | 251 | int i, r; |
251 | 252 | ||
@@ -270,7 +271,7 @@ et61x251_i2c_wait(struct et61x251_device* cam, struct et61x251_sensor* sensor) | |||
270 | 271 | ||
271 | int | 272 | int |
272 | et61x251_i2c_try_read(struct et61x251_device* cam, | 273 | et61x251_i2c_try_read(struct et61x251_device* cam, |
273 | struct et61x251_sensor* sensor, u8 address) | 274 | const struct et61x251_sensor* sensor, u8 address) |
274 | { | 275 | { |
275 | struct usb_device* udev = cam->usbdev; | 276 | struct usb_device* udev = cam->usbdev; |
276 | u8* data = cam->control_buffer; | 277 | u8* data = cam->control_buffer; |
@@ -303,7 +304,8 @@ et61x251_i2c_try_read(struct et61x251_device* cam, | |||
303 | 304 | ||
304 | int | 305 | int |
305 | et61x251_i2c_try_write(struct et61x251_device* cam, | 306 | et61x251_i2c_try_write(struct et61x251_device* cam, |
306 | struct et61x251_sensor* sensor, u8 address, u8 value) | 307 | const struct et61x251_sensor* sensor, u8 address, |
308 | u8 value) | ||
307 | { | 309 | { |
308 | struct usb_device* udev = cam->usbdev; | 310 | struct usb_device* udev = cam->usbdev; |
309 | u8* data = cam->control_buffer; | 311 | u8* data = cam->control_buffer; |
@@ -615,7 +617,7 @@ static int et61x251_start_transfer(struct et61x251_device* cam) | |||
615 | return 0; | 617 | return 0; |
616 | 618 | ||
617 | free_urbs: | 619 | free_urbs: |
618 | for (i = 0; (i < ET61X251_URBS) && cam->urb[i]; i++) | 620 | for (i = 0; (i < ET61X251_URBS) && cam->urb[i]; i++) |
619 | usb_free_urb(cam->urb[i]); | 621 | usb_free_urb(cam->urb[i]); |
620 | 622 | ||
621 | free_buffers: | 623 | free_buffers: |
@@ -682,7 +684,7 @@ static u8 et61x251_strtou8(const char* buff, size_t len, ssize_t* count) | |||
682 | 684 | ||
683 | if (len < 4) { | 685 | if (len < 4) { |
684 | strncpy(str, buff, len); | 686 | strncpy(str, buff, len); |
685 | str[len+1] = '\0'; | 687 | str[len] = '\0'; |
686 | } else { | 688 | } else { |
687 | strncpy(str, buff, 4); | 689 | strncpy(str, buff, 4); |
688 | str[4] = '\0'; | 690 | str[4] = '\0'; |
@@ -977,30 +979,30 @@ static CLASS_DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR, | |||
977 | 979 | ||
978 | static int et61x251_create_sysfs(struct et61x251_device* cam) | 980 | static int et61x251_create_sysfs(struct et61x251_device* cam) |
979 | { | 981 | { |
980 | struct video_device *v4ldev = cam->v4ldev; | 982 | struct class_device *classdev = &(cam->v4ldev->class_dev); |
981 | int err = 0; | 983 | int err = 0; |
982 | 984 | ||
983 | if ((err = video_device_create_file(v4ldev, &class_device_attr_reg))) | 985 | if ((err = class_device_create_file(classdev, &class_device_attr_reg))) |
984 | goto err_out; | 986 | goto err_out; |
985 | if ((err = video_device_create_file(v4ldev, &class_device_attr_val))) | 987 | if ((err = class_device_create_file(classdev, &class_device_attr_val))) |
986 | goto err_reg; | 988 | goto err_reg; |
987 | 989 | ||
988 | if (cam->sensor.sysfs_ops) { | 990 | if (cam->sensor.sysfs_ops) { |
989 | if ((err = video_device_create_file(v4ldev, | 991 | if ((err = class_device_create_file(classdev, |
990 | &class_device_attr_i2c_reg))) | 992 | &class_device_attr_i2c_reg))) |
991 | goto err_val; | 993 | goto err_val; |
992 | if ((err = video_device_create_file(v4ldev, | 994 | if ((err = class_device_create_file(classdev, |
993 | &class_device_attr_i2c_val))) | 995 | &class_device_attr_i2c_val))) |
994 | goto err_i2c_reg; | 996 | goto err_i2c_reg; |
995 | } | 997 | } |
996 | 998 | ||
997 | err_i2c_reg: | 999 | err_i2c_reg: |
998 | if (cam->sensor.sysfs_ops) | 1000 | if (cam->sensor.sysfs_ops) |
999 | video_device_remove_file(v4ldev, &class_device_attr_i2c_reg); | 1001 | class_device_remove_file(classdev, &class_device_attr_i2c_reg); |
1000 | err_val: | 1002 | err_val: |
1001 | video_device_remove_file(v4ldev, &class_device_attr_val); | 1003 | class_device_remove_file(classdev, &class_device_attr_val); |
1002 | err_reg: | 1004 | err_reg: |
1003 | video_device_remove_file(v4ldev, &class_device_attr_reg); | 1005 | class_device_remove_file(classdev, &class_device_attr_reg); |
1004 | err_out: | 1006 | err_out: |
1005 | return err; | 1007 | return err; |
1006 | } | 1008 | } |
@@ -1103,7 +1105,8 @@ static int et61x251_init(struct et61x251_device* cam) | |||
1103 | int err = 0; | 1105 | int err = 0; |
1104 | 1106 | ||
1105 | if (!(cam->state & DEV_INITIALIZED)) { | 1107 | if (!(cam->state & DEV_INITIALIZED)) { |
1106 | init_waitqueue_head(&cam->open); | 1108 | mutex_init(&cam->open_mutex); |
1109 | init_waitqueue_head(&cam->wait_open); | ||
1107 | qctrl = s->qctrl; | 1110 | qctrl = s->qctrl; |
1108 | rect = &(s->cropcap.defrect); | 1111 | rect = &(s->cropcap.defrect); |
1109 | cam->compression.quality = ET61X251_COMPRESSION_QUALITY; | 1112 | cam->compression.quality = ET61X251_COMPRESSION_QUALITY; |
@@ -1177,64 +1180,80 @@ static int et61x251_init(struct et61x251_device* cam) | |||
1177 | return 0; | 1180 | return 0; |
1178 | } | 1181 | } |
1179 | 1182 | ||
1183 | /*****************************************************************************/ | ||
1180 | 1184 | ||
1181 | static void et61x251_release_resources(struct et61x251_device* cam) | 1185 | static void et61x251_release_resources(struct kref *kref) |
1182 | { | 1186 | { |
1187 | struct et61x251_device *cam; | ||
1188 | |||
1183 | mutex_lock(&et61x251_sysfs_lock); | 1189 | mutex_lock(&et61x251_sysfs_lock); |
1184 | 1190 | ||
1191 | cam = container_of(kref, struct et61x251_device, kref); | ||
1192 | |||
1185 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); | 1193 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); |
1186 | video_set_drvdata(cam->v4ldev, NULL); | 1194 | video_set_drvdata(cam->v4ldev, NULL); |
1187 | video_unregister_device(cam->v4ldev); | 1195 | video_unregister_device(cam->v4ldev); |
1196 | usb_put_dev(cam->usbdev); | ||
1197 | kfree(cam->control_buffer); | ||
1198 | kfree(cam); | ||
1188 | 1199 | ||
1189 | mutex_unlock(&et61x251_sysfs_lock); | 1200 | mutex_unlock(&et61x251_sysfs_lock); |
1190 | |||
1191 | kfree(cam->control_buffer); | ||
1192 | } | 1201 | } |
1193 | 1202 | ||
1194 | /*****************************************************************************/ | ||
1195 | 1203 | ||
1196 | static int et61x251_open(struct inode* inode, struct file* filp) | 1204 | static int et61x251_open(struct inode* inode, struct file* filp) |
1197 | { | 1205 | { |
1198 | struct et61x251_device* cam; | 1206 | struct et61x251_device* cam; |
1199 | int err = 0; | 1207 | int err = 0; |
1200 | 1208 | ||
1201 | /* | 1209 | if (!down_read_trylock(&et61x251_dev_lock)) |
1202 | This is the only safe way to prevent race conditions with | ||
1203 | disconnect | ||
1204 | */ | ||
1205 | if (!down_read_trylock(&et61x251_disconnect)) | ||
1206 | return -ERESTARTSYS; | 1210 | return -ERESTARTSYS; |
1207 | 1211 | ||
1208 | cam = video_get_drvdata(video_devdata(filp)); | 1212 | cam = video_get_drvdata(video_devdata(filp)); |
1209 | 1213 | ||
1210 | if (mutex_lock_interruptible(&cam->dev_mutex)) { | 1214 | if (wait_for_completion_interruptible(&cam->probe)) { |
1211 | up_read(&et61x251_disconnect); | 1215 | up_read(&et61x251_dev_lock); |
1212 | return -ERESTARTSYS; | 1216 | return -ERESTARTSYS; |
1213 | } | 1217 | } |
1214 | 1218 | ||
1219 | kref_get(&cam->kref); | ||
1220 | |||
1221 | if (mutex_lock_interruptible(&cam->open_mutex)) { | ||
1222 | kref_put(&cam->kref, et61x251_release_resources); | ||
1223 | up_read(&et61x251_dev_lock); | ||
1224 | return -ERESTARTSYS; | ||
1225 | } | ||
1226 | |||
1227 | if (cam->state & DEV_DISCONNECTED) { | ||
1228 | DBG(1, "Device not present"); | ||
1229 | err = -ENODEV; | ||
1230 | goto out; | ||
1231 | } | ||
1232 | |||
1215 | if (cam->users) { | 1233 | if (cam->users) { |
1216 | DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor); | 1234 | DBG(2, "Device /dev/video%d is already in use", |
1235 | cam->v4ldev->minor); | ||
1236 | DBG(3, "Simultaneous opens are not supported"); | ||
1217 | if ((filp->f_flags & O_NONBLOCK) || | 1237 | if ((filp->f_flags & O_NONBLOCK) || |
1218 | (filp->f_flags & O_NDELAY)) { | 1238 | (filp->f_flags & O_NDELAY)) { |
1219 | err = -EWOULDBLOCK; | 1239 | err = -EWOULDBLOCK; |
1220 | goto out; | 1240 | goto out; |
1221 | } | 1241 | } |
1222 | mutex_unlock(&cam->dev_mutex); | 1242 | DBG(2, "A blocking open() has been requested. Wait for the " |
1223 | err = wait_event_interruptible_exclusive(cam->open, | 1243 | "device to be released..."); |
1224 | cam->state & DEV_DISCONNECTED | 1244 | up_read(&et61x251_dev_lock); |
1245 | err = wait_event_interruptible_exclusive(cam->wait_open, | ||
1246 | (cam->state & DEV_DISCONNECTED) | ||
1225 | || !cam->users); | 1247 | || !cam->users); |
1226 | if (err) { | 1248 | down_read(&et61x251_dev_lock); |
1227 | up_read(&et61x251_disconnect); | 1249 | if (err) |
1228 | return err; | 1250 | goto out; |
1229 | } | ||
1230 | if (cam->state & DEV_DISCONNECTED) { | 1251 | if (cam->state & DEV_DISCONNECTED) { |
1231 | up_read(&et61x251_disconnect); | 1252 | err = -ENODEV; |
1232 | return -ENODEV; | 1253 | goto out; |
1233 | } | 1254 | } |
1234 | mutex_lock(&cam->dev_mutex); | ||
1235 | } | 1255 | } |
1236 | 1256 | ||
1237 | |||
1238 | if (cam->state & DEV_MISCONFIGURED) { | 1257 | if (cam->state & DEV_MISCONFIGURED) { |
1239 | err = et61x251_init(cam); | 1258 | err = et61x251_init(cam); |
1240 | if (err) { | 1259 | if (err) { |
@@ -1259,36 +1278,32 @@ static int et61x251_open(struct inode* inode, struct file* filp) | |||
1259 | DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); | 1278 | DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); |
1260 | 1279 | ||
1261 | out: | 1280 | out: |
1262 | mutex_unlock(&cam->dev_mutex); | 1281 | mutex_unlock(&cam->open_mutex); |
1263 | up_read(&et61x251_disconnect); | 1282 | if (err) |
1283 | kref_put(&cam->kref, et61x251_release_resources); | ||
1284 | up_read(&et61x251_dev_lock); | ||
1264 | return err; | 1285 | return err; |
1265 | } | 1286 | } |
1266 | 1287 | ||
1267 | 1288 | ||
1268 | static int et61x251_release(struct inode* inode, struct file* filp) | 1289 | static int et61x251_release(struct inode* inode, struct file* filp) |
1269 | { | 1290 | { |
1270 | struct et61x251_device* cam = video_get_drvdata(video_devdata(filp)); | 1291 | struct et61x251_device* cam; |
1271 | 1292 | ||
1272 | mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */ | 1293 | down_write(&et61x251_dev_lock); |
1273 | 1294 | ||
1274 | et61x251_stop_transfer(cam); | 1295 | cam = video_get_drvdata(video_devdata(filp)); |
1275 | 1296 | ||
1297 | et61x251_stop_transfer(cam); | ||
1276 | et61x251_release_buffers(cam); | 1298 | et61x251_release_buffers(cam); |
1277 | |||
1278 | if (cam->state & DEV_DISCONNECTED) { | ||
1279 | et61x251_release_resources(cam); | ||
1280 | usb_put_dev(cam->usbdev); | ||
1281 | mutex_unlock(&cam->dev_mutex); | ||
1282 | kfree(cam); | ||
1283 | return 0; | ||
1284 | } | ||
1285 | |||
1286 | cam->users--; | 1299 | cam->users--; |
1287 | wake_up_interruptible_nr(&cam->open, 1); | 1300 | wake_up_interruptible_nr(&cam->wait_open, 1); |
1288 | 1301 | ||
1289 | DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); | 1302 | DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); |
1290 | 1303 | ||
1291 | mutex_unlock(&cam->dev_mutex); | 1304 | kref_put(&cam->kref, et61x251_release_resources); |
1305 | |||
1306 | up_write(&et61x251_dev_lock); | ||
1292 | 1307 | ||
1293 | return 0; | 1308 | return 0; |
1294 | } | 1309 | } |
@@ -1324,7 +1339,7 @@ et61x251_read(struct file* filp, char __user * buf, | |||
1324 | DBG(3, "Close and open the device again to choose the read " | 1339 | DBG(3, "Close and open the device again to choose the read " |
1325 | "method"); | 1340 | "method"); |
1326 | mutex_unlock(&cam->fileop_mutex); | 1341 | mutex_unlock(&cam->fileop_mutex); |
1327 | return -EINVAL; | 1342 | return -EBUSY; |
1328 | } | 1343 | } |
1329 | 1344 | ||
1330 | if (cam->io == IO_NONE) { | 1345 | if (cam->io == IO_NONE) { |
@@ -1504,7 +1519,12 @@ static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma) | |||
1504 | return -EIO; | 1519 | return -EIO; |
1505 | } | 1520 | } |
1506 | 1521 | ||
1507 | if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || | 1522 | if (!(vma->vm_flags & (VM_WRITE | VM_READ))) { |
1523 | mutex_unlock(&cam->fileop_mutex); | ||
1524 | return -EACCES; | ||
1525 | } | ||
1526 | |||
1527 | if (cam->io != IO_MMAP || | ||
1508 | size != PAGE_ALIGN(cam->frame[0].buf.length)) { | 1528 | size != PAGE_ALIGN(cam->frame[0].buf.length)) { |
1509 | mutex_unlock(&cam->fileop_mutex); | 1529 | mutex_unlock(&cam->fileop_mutex); |
1510 | return -EINVAL; | 1530 | return -EINVAL; |
@@ -1535,7 +1555,6 @@ static int et61x251_mmap(struct file* filp, struct vm_area_struct *vma) | |||
1535 | 1555 | ||
1536 | vma->vm_ops = &et61x251_vm_ops; | 1556 | vma->vm_ops = &et61x251_vm_ops; |
1537 | vma->vm_private_data = &cam->frame[i]; | 1557 | vma->vm_private_data = &cam->frame[i]; |
1538 | |||
1539 | et61x251_vm_open(vma); | 1558 | et61x251_vm_open(vma); |
1540 | 1559 | ||
1541 | mutex_unlock(&cam->fileop_mutex); | 1560 | mutex_unlock(&cam->fileop_mutex); |
@@ -1764,7 +1783,7 @@ et61x251_vidioc_s_crop(struct et61x251_device* cam, void __user * arg) | |||
1764 | if (cam->frame[i].vma_use_count) { | 1783 | if (cam->frame[i].vma_use_count) { |
1765 | DBG(3, "VIDIOC_S_CROP failed. " | 1784 | DBG(3, "VIDIOC_S_CROP failed. " |
1766 | "Unmap the buffers first."); | 1785 | "Unmap the buffers first."); |
1767 | return -EINVAL; | 1786 | return -EBUSY; |
1768 | } | 1787 | } |
1769 | 1788 | ||
1770 | /* Preserve R,G or B origin */ | 1789 | /* Preserve R,G or B origin */ |
@@ -1921,6 +1940,8 @@ et61x251_vidioc_g_fmt(struct et61x251_device* cam, void __user * arg) | |||
1921 | if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1940 | if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1922 | return -EINVAL; | 1941 | return -EINVAL; |
1923 | 1942 | ||
1943 | pfmt->colorspace = (pfmt->pixelformat == V4L2_PIX_FMT_ET61X251) ? | ||
1944 | 0 : V4L2_COLORSPACE_SRGB; | ||
1924 | pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_ET61X251) | 1945 | pfmt->bytesperline = (pfmt->pixelformat==V4L2_PIX_FMT_ET61X251) |
1925 | ? 0 : (pfmt->width * pfmt->priv) / 8; | 1946 | ? 0 : (pfmt->width * pfmt->priv) / 8; |
1926 | pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); | 1947 | pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8); |
@@ -1996,6 +2017,8 @@ et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd, | |||
1996 | pix->pixelformat != V4L2_PIX_FMT_SBGGR8) | 2017 | pix->pixelformat != V4L2_PIX_FMT_SBGGR8) |
1997 | pix->pixelformat = pfmt->pixelformat; | 2018 | pix->pixelformat = pfmt->pixelformat; |
1998 | pix->priv = pfmt->priv; /* bpp */ | 2019 | pix->priv = pfmt->priv; /* bpp */ |
2020 | pix->colorspace = (pix->pixelformat == V4L2_PIX_FMT_ET61X251) ? | ||
2021 | 0 : V4L2_COLORSPACE_SRGB; | ||
1999 | pix->colorspace = pfmt->colorspace; | 2022 | pix->colorspace = pfmt->colorspace; |
2000 | pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_ET61X251) | 2023 | pix->bytesperline = (pix->pixelformat == V4L2_PIX_FMT_ET61X251) |
2001 | ? 0 : (pix->width * pix->priv) / 8; | 2024 | ? 0 : (pix->width * pix->priv) / 8; |
@@ -2013,7 +2036,7 @@ et61x251_vidioc_try_s_fmt(struct et61x251_device* cam, unsigned int cmd, | |||
2013 | if (cam->frame[i].vma_use_count) { | 2036 | if (cam->frame[i].vma_use_count) { |
2014 | DBG(3, "VIDIOC_S_FMT failed. " | 2037 | DBG(3, "VIDIOC_S_FMT failed. " |
2015 | "Unmap the buffers first."); | 2038 | "Unmap the buffers first."); |
2016 | return -EINVAL; | 2039 | return -EBUSY; |
2017 | } | 2040 | } |
2018 | 2041 | ||
2019 | if (cam->stream == STREAM_ON) | 2042 | if (cam->stream == STREAM_ON) |
@@ -2129,14 +2152,14 @@ et61x251_vidioc_reqbufs(struct et61x251_device* cam, void __user * arg) | |||
2129 | if (cam->io == IO_READ) { | 2152 | if (cam->io == IO_READ) { |
2130 | DBG(3, "Close and open the device again to choose the mmap " | 2153 | DBG(3, "Close and open the device again to choose the mmap " |
2131 | "I/O method"); | 2154 | "I/O method"); |
2132 | return -EINVAL; | 2155 | return -EBUSY; |
2133 | } | 2156 | } |
2134 | 2157 | ||
2135 | for (i = 0; i < cam->nbuffers; i++) | 2158 | for (i = 0; i < cam->nbuffers; i++) |
2136 | if (cam->frame[i].vma_use_count) { | 2159 | if (cam->frame[i].vma_use_count) { |
2137 | DBG(3, "VIDIOC_REQBUFS failed. " | 2160 | DBG(3, "VIDIOC_REQBUFS failed. " |
2138 | "Previous buffers are still mapped."); | 2161 | "Previous buffers are still mapped."); |
2139 | return -EINVAL; | 2162 | return -EBUSY; |
2140 | } | 2163 | } |
2141 | 2164 | ||
2142 | if (cam->stream == STREAM_ON) | 2165 | if (cam->stream == STREAM_ON) |
@@ -2284,9 +2307,6 @@ et61x251_vidioc_streamon(struct et61x251_device* cam, void __user * arg) | |||
2284 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) | 2307 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) |
2285 | return -EINVAL; | 2308 | return -EINVAL; |
2286 | 2309 | ||
2287 | if (list_empty(&cam->inqueue)) | ||
2288 | return -EINVAL; | ||
2289 | |||
2290 | cam->stream = STREAM_ON; | 2310 | cam->stream = STREAM_ON; |
2291 | 2311 | ||
2292 | DBG(3, "Stream on"); | 2312 | DBG(3, "Stream on"); |
@@ -2535,8 +2555,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2535 | goto fail; | 2555 | goto fail; |
2536 | } | 2556 | } |
2537 | 2557 | ||
2538 | mutex_init(&cam->dev_mutex); | ||
2539 | |||
2540 | DBG(2, "ET61X[12]51 PC Camera Controller detected " | 2558 | DBG(2, "ET61X[12]51 PC Camera Controller detected " |
2541 | "(vid/pid 0x%04X:0x%04X)",id->idVendor, id->idProduct); | 2559 | "(vid/pid 0x%04X:0x%04X)",id->idVendor, id->idProduct); |
2542 | 2560 | ||
@@ -2568,7 +2586,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2568 | cam->v4ldev->release = video_device_release; | 2586 | cam->v4ldev->release = video_device_release; |
2569 | video_set_drvdata(cam->v4ldev, cam); | 2587 | video_set_drvdata(cam->v4ldev, cam); |
2570 | 2588 | ||
2571 | mutex_lock(&cam->dev_mutex); | 2589 | init_completion(&cam->probe); |
2572 | 2590 | ||
2573 | err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, | 2591 | err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, |
2574 | video_nr[dev_nr]); | 2592 | video_nr[dev_nr]); |
@@ -2578,7 +2596,7 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2578 | DBG(1, "Free /dev/videoX node not found"); | 2596 | DBG(1, "Free /dev/videoX node not found"); |
2579 | video_nr[dev_nr] = -1; | 2597 | video_nr[dev_nr] = -1; |
2580 | dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; | 2598 | dev_nr = (dev_nr < ET61X251_MAX_DEVICES-1) ? dev_nr+1 : 0; |
2581 | mutex_unlock(&cam->dev_mutex); | 2599 | complete_all(&cam->probe); |
2582 | goto fail; | 2600 | goto fail; |
2583 | } | 2601 | } |
2584 | 2602 | ||
@@ -2599,11 +2617,15 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2599 | "device controlling. Error #%d", err); | 2617 | "device controlling. Error #%d", err); |
2600 | #else | 2618 | #else |
2601 | DBG(2, "Optional device control through 'sysfs' interface disabled"); | 2619 | DBG(2, "Optional device control through 'sysfs' interface disabled"); |
2620 | DBG(3, "Compile the kernel with the 'CONFIG_VIDEO_ADV_DEBUG' " | ||
2621 | "configuration option to enable it."); | ||
2602 | #endif | 2622 | #endif |
2603 | 2623 | ||
2604 | usb_set_intfdata(intf, cam); | 2624 | usb_set_intfdata(intf, cam); |
2625 | kref_init(&cam->kref); | ||
2626 | usb_get_dev(cam->usbdev); | ||
2605 | 2627 | ||
2606 | mutex_unlock(&cam->dev_mutex); | 2628 | complete_all(&cam->probe); |
2607 | 2629 | ||
2608 | return 0; | 2630 | return 0; |
2609 | 2631 | ||
@@ -2620,40 +2642,31 @@ fail: | |||
2620 | 2642 | ||
2621 | static void et61x251_usb_disconnect(struct usb_interface* intf) | 2643 | static void et61x251_usb_disconnect(struct usb_interface* intf) |
2622 | { | 2644 | { |
2623 | struct et61x251_device* cam = usb_get_intfdata(intf); | 2645 | struct et61x251_device* cam; |
2624 | |||
2625 | if (!cam) | ||
2626 | return; | ||
2627 | 2646 | ||
2628 | down_write(&et61x251_disconnect); | 2647 | down_write(&et61x251_dev_lock); |
2629 | 2648 | ||
2630 | mutex_lock(&cam->dev_mutex); | 2649 | cam = usb_get_intfdata(intf); |
2631 | 2650 | ||
2632 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); | 2651 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); |
2633 | 2652 | ||
2634 | wake_up_interruptible_all(&cam->open); | ||
2635 | |||
2636 | if (cam->users) { | 2653 | if (cam->users) { |
2637 | DBG(2, "Device /dev/video%d is open! Deregistration and " | 2654 | DBG(2, "Device /dev/video%d is open! Deregistration and " |
2638 | "memory deallocation are deferred on close.", | 2655 | "memory deallocation are deferred.", |
2639 | cam->v4ldev->minor); | 2656 | cam->v4ldev->minor); |
2640 | cam->state |= DEV_MISCONFIGURED; | 2657 | cam->state |= DEV_MISCONFIGURED; |
2641 | et61x251_stop_transfer(cam); | 2658 | et61x251_stop_transfer(cam); |
2642 | cam->state |= DEV_DISCONNECTED; | 2659 | cam->state |= DEV_DISCONNECTED; |
2643 | wake_up_interruptible(&cam->wait_frame); | 2660 | wake_up_interruptible(&cam->wait_frame); |
2644 | wake_up(&cam->wait_stream); | 2661 | wake_up(&cam->wait_stream); |
2645 | usb_get_dev(cam->usbdev); | 2662 | } else |
2646 | } else { | ||
2647 | cam->state |= DEV_DISCONNECTED; | 2663 | cam->state |= DEV_DISCONNECTED; |
2648 | et61x251_release_resources(cam); | ||
2649 | } | ||
2650 | 2664 | ||
2651 | mutex_unlock(&cam->dev_mutex); | 2665 | wake_up_interruptible_all(&cam->wait_open); |
2652 | 2666 | ||
2653 | if (!cam->users) | 2667 | kref_put(&cam->kref, et61x251_release_resources); |
2654 | kfree(cam); | ||
2655 | 2668 | ||
2656 | up_write(&et61x251_disconnect); | 2669 | up_write(&et61x251_dev_lock); |
2657 | } | 2670 | } |
2658 | 2671 | ||
2659 | 2672 | ||
diff --git a/drivers/media/video/et61x251/et61x251_sensor.h b/drivers/media/video/et61x251/et61x251_sensor.h index 5fadb5de68bf..e14586330623 100644 --- a/drivers/media/video/et61x251/et61x251_sensor.h +++ b/drivers/media/video/et61x251/et61x251_sensor.h | |||
@@ -22,7 +22,7 @@ | |||
22 | #define _ET61X251_SENSOR_H_ | 22 | #define _ET61X251_SENSOR_H_ |
23 | 23 | ||
24 | #include <linux/usb.h> | 24 | #include <linux/usb.h> |
25 | #include <linux/videodev.h> | 25 | #include <linux/videodev2.h> |
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
27 | #include <linux/stddef.h> | 27 | #include <linux/stddef.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
@@ -47,7 +47,7 @@ et61x251_match_id(struct et61x251_device* cam, const struct usb_device_id *id); | |||
47 | 47 | ||
48 | extern void | 48 | extern void |
49 | et61x251_attach_sensor(struct et61x251_device* cam, | 49 | et61x251_attach_sensor(struct et61x251_device* cam, |
50 | struct et61x251_sensor* sensor); | 50 | const struct et61x251_sensor* sensor); |
51 | 51 | ||
52 | /*****************************************************************************/ | 52 | /*****************************************************************************/ |
53 | 53 | ||
@@ -56,10 +56,10 @@ extern int et61x251_read_reg(struct et61x251_device*, u16 index); | |||
56 | extern int et61x251_i2c_write(struct et61x251_device*, u8 address, u8 value); | 56 | extern int et61x251_i2c_write(struct et61x251_device*, u8 address, u8 value); |
57 | extern int et61x251_i2c_read(struct et61x251_device*, u8 address); | 57 | extern int et61x251_i2c_read(struct et61x251_device*, u8 address); |
58 | extern int et61x251_i2c_try_write(struct et61x251_device*, | 58 | extern int et61x251_i2c_try_write(struct et61x251_device*, |
59 | struct et61x251_sensor*, u8 address, | 59 | const struct et61x251_sensor*, u8 address, |
60 | u8 value); | 60 | u8 value); |
61 | extern int et61x251_i2c_try_read(struct et61x251_device*, | 61 | extern int et61x251_i2c_try_read(struct et61x251_device*, |
62 | struct et61x251_sensor*, u8 address); | 62 | const struct et61x251_sensor*, u8 address); |
63 | extern int et61x251_i2c_raw_write(struct et61x251_device*, u8 n, u8 data1, | 63 | extern int et61x251_i2c_raw_write(struct et61x251_device*, u8 n, u8 data1, |
64 | u8 data2, u8 data3, u8 data4, u8 data5, | 64 | u8 data2, u8 data3, u8 data4, u8 data5, |
65 | u8 data6, u8 data7, u8 data8, u8 address); | 65 | u8 data6, u8 data7, u8 data8, u8 address); |
diff --git a/drivers/media/video/et61x251/et61x251_tas5130d1b.c b/drivers/media/video/et61x251/et61x251_tas5130d1b.c index b06643409842..04b7fbb310a8 100644 --- a/drivers/media/video/et61x251/et61x251_tas5130d1b.c +++ b/drivers/media/video/et61x251/et61x251_tas5130d1b.c | |||
@@ -69,7 +69,7 @@ static int tas5130d1b_set_ctrl(struct et61x251_device* cam, | |||
69 | } | 69 | } |
70 | 70 | ||
71 | 71 | ||
72 | static struct et61x251_sensor tas5130d1b = { | 72 | static const struct et61x251_sensor tas5130d1b = { |
73 | .name = "TAS5130D1B", | 73 | .name = "TAS5130D1B", |
74 | .interface = ET61X251_I2C_3WIRES, | 74 | .interface = ET61X251_I2C_3WIRES, |
75 | .rsta = ET61X251_I2C_RSTA_STOP, | 75 | .rsta = ET61X251_I2C_RSTA_STOP, |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index ed92b6f7187a..2d709e064679 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/errno.h> | 37 | #include <linux/errno.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/i2c.h> | 39 | #include <linux/i2c.h> |
40 | #include <linux/i2c-id.h> | ||
40 | #include <linux/workqueue.h> | 41 | #include <linux/workqueue.h> |
41 | #include <asm/semaphore.h> | 42 | #include <asm/semaphore.h> |
42 | 43 | ||
@@ -60,21 +61,22 @@ MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults | |||
60 | 61 | ||
61 | /* ----------------------------------------------------------------------- */ | 62 | /* ----------------------------------------------------------------------- */ |
62 | 63 | ||
63 | static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 64 | static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, |
65 | int size, int offset) | ||
64 | { | 66 | { |
65 | unsigned char buf[3]; | 67 | unsigned char buf[6]; |
66 | int start, range, toggle, dev, code; | 68 | int start, range, toggle, dev, code; |
67 | 69 | ||
68 | /* poll IR chip */ | 70 | /* poll IR chip */ |
69 | if (3 != i2c_master_recv(&ir->c,buf,3)) | 71 | if (size != i2c_master_recv(&ir->c,buf,size)) |
70 | return -EIO; | 72 | return -EIO; |
71 | 73 | ||
72 | /* split rc5 data block ... */ | 74 | /* split rc5 data block ... */ |
73 | start = (buf[0] >> 7) & 1; | 75 | start = (buf[offset] >> 7) & 1; |
74 | range = (buf[0] >> 6) & 1; | 76 | range = (buf[offset] >> 6) & 1; |
75 | toggle = (buf[0] >> 5) & 1; | 77 | toggle = (buf[offset] >> 5) & 1; |
76 | dev = buf[0] & 0x1f; | 78 | dev = buf[offset] & 0x1f; |
77 | code = (buf[1] >> 2) & 0x3f; | 79 | code = (buf[offset+1] >> 2) & 0x3f; |
78 | 80 | ||
79 | /* rc5 has two start bits | 81 | /* rc5 has two start bits |
80 | * the first bit must be one | 82 | * the first bit must be one |
@@ -96,6 +98,16 @@ static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
96 | return 1; | 98 | return 1; |
97 | } | 99 | } |
98 | 100 | ||
101 | static inline int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
102 | { | ||
103 | return get_key_haup_common (ir, ir_key, ir_raw, 3, 0); | ||
104 | } | ||
105 | |||
106 | static inline int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
107 | { | ||
108 | return get_key_haup_common (ir, ir_key, ir_raw, 6, 3); | ||
109 | } | ||
110 | |||
99 | static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 111 | static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
100 | { | 112 | { |
101 | unsigned char b; | 113 | unsigned char b; |
@@ -270,8 +282,9 @@ static void ir_timer(unsigned long data) | |||
270 | static void ir_work(struct work_struct *work) | 282 | static void ir_work(struct work_struct *work) |
271 | { | 283 | { |
272 | struct IR_i2c *ir = container_of(work, struct IR_i2c, work); | 284 | struct IR_i2c *ir = container_of(work, struct IR_i2c, work); |
285 | |||
273 | ir_key_poll(ir); | 286 | ir_key_poll(ir); |
274 | mod_timer(&ir->timer, jiffies+HZ/10); | 287 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(100)); |
275 | } | 288 | } |
276 | 289 | ||
277 | /* ----------------------------------------------------------------------- */ | 290 | /* ----------------------------------------------------------------------- */ |
@@ -354,9 +367,21 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
354 | case 0x7a: | 367 | case 0x7a: |
355 | case 0x47: | 368 | case 0x47: |
356 | case 0x71: | 369 | case 0x71: |
357 | /* Handled by saa7134-input */ | 370 | if (adap->id == I2C_HW_B_CX2388x) { |
358 | name = "SAA713x remote"; | 371 | /* Handled by cx88-input */ |
359 | ir_type = IR_TYPE_OTHER; | 372 | name = "CX2388x remote"; |
373 | ir_type = IR_TYPE_RC5; | ||
374 | ir->get_key = get_key_haup_xvr; | ||
375 | if (hauppauge == 1) { | ||
376 | ir_codes = ir_codes_hauppauge_new; | ||
377 | } else { | ||
378 | ir_codes = ir_codes_rc5_tv; | ||
379 | } | ||
380 | } else { | ||
381 | /* Handled by saa7134-input */ | ||
382 | name = "SAA713x remote"; | ||
383 | ir_type = IR_TYPE_OTHER; | ||
384 | } | ||
360 | break; | 385 | break; |
361 | default: | 386 | default: |
362 | /* shouldn't happen */ | 387 | /* shouldn't happen */ |
@@ -450,6 +475,7 @@ static int ir_probe(struct i2c_adapter *adap) | |||
450 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; | 475 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; |
451 | static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, -1 }; | 476 | static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, -1 }; |
452 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; | 477 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; |
478 | static const int probe_cx88[] = { 0x18, 0x71, -1 }; | ||
453 | const int *probe = NULL; | 479 | const int *probe = NULL; |
454 | struct i2c_client c; | 480 | struct i2c_client c; |
455 | unsigned char buf; | 481 | unsigned char buf; |
@@ -468,6 +494,9 @@ static int ir_probe(struct i2c_adapter *adap) | |||
468 | case I2C_HW_B_EM28XX: | 494 | case I2C_HW_B_EM28XX: |
469 | probe = probe_em28XX; | 495 | probe = probe_em28XX; |
470 | break; | 496 | break; |
497 | case I2C_HW_B_CX2388x: | ||
498 | probe = probe_cx88; | ||
499 | break; | ||
471 | } | 500 | } |
472 | if (NULL == probe) | 501 | if (NULL == probe) |
473 | return 0; | 502 | return 0; |
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index efc66355339a..4c93466a89e5 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -181,7 +181,7 @@ MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC"); | |||
181 | MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K"); | 181 | MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K"); |
182 | MODULE_PARM_DESC(debug, | 182 | MODULE_PARM_DESC(debug, |
183 | "Debug level (bitmask). Default: errors only\n" | 183 | "Debug level (bitmask). Default: errors only\n" |
184 | "\t\t\t(debug = 511 gives full debugging)"); | 184 | "\t\t\t(debug = 1023 gives full debugging)"); |
185 | MODULE_PARM_DESC(ivtv_pci_latency, | 185 | MODULE_PARM_DESC(ivtv_pci_latency, |
186 | "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n" | 186 | "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n" |
187 | "\t\t\tDefault: Yes"); | 187 | "\t\t\tDefault: Yes"); |
@@ -339,6 +339,7 @@ static void ivtv_process_eeprom(struct ivtv *itv) | |||
339 | /* In a few cases the PCI subsystem IDs do not correctly | 339 | /* In a few cases the PCI subsystem IDs do not correctly |
340 | identify the card. A better method is to check the | 340 | identify the card. A better method is to check the |
341 | model number from the eeprom instead. */ | 341 | model number from the eeprom instead. */ |
342 | case 30012 ... 30039: /* Low profile PVR250 */ | ||
342 | case 32000 ... 32999: | 343 | case 32000 ... 32999: |
343 | case 48000 ... 48099: /* 48??? range are PVR250s with a cx23415 */ | 344 | case 48000 ... 48099: /* 48??? range are PVR250s with a cx23415 */ |
344 | case 48400 ... 48599: | 345 | case 48400 ... 48599: |
@@ -622,6 +623,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) | |||
622 | itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */ | 623 | itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */ |
623 | itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */ | 624 | itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */ |
624 | 625 | ||
626 | mutex_init(&itv->serialize_lock); | ||
625 | mutex_init(&itv->i2c_bus_lock); | 627 | mutex_init(&itv->i2c_bus_lock); |
626 | mutex_init(&itv->udma.lock); | 628 | mutex_init(&itv->udma.lock); |
627 | 629 | ||
@@ -1288,10 +1290,7 @@ static void ivtv_remove(struct pci_dev *pci_dev) | |||
1288 | 1290 | ||
1289 | IVTV_DEBUG_INFO(" Releasing irq.\n"); | 1291 | IVTV_DEBUG_INFO(" Releasing irq.\n"); |
1290 | free_irq(itv->dev->irq, (void *)itv); | 1292 | free_irq(itv->dev->irq, (void *)itv); |
1291 | 1293 | ivtv_iounmap(itv); | |
1292 | if (itv->dev) { | ||
1293 | ivtv_iounmap(itv); | ||
1294 | } | ||
1295 | 1294 | ||
1296 | IVTV_DEBUG_INFO(" Releasing mem.\n"); | 1295 | IVTV_DEBUG_INFO(" Releasing mem.\n"); |
1297 | release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); | 1296 | release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); |
@@ -1326,9 +1325,9 @@ static int module_start(void) | |||
1326 | return -1; | 1325 | return -1; |
1327 | } | 1326 | } |
1328 | 1327 | ||
1329 | if (ivtv_debug < 0 || ivtv_debug > 511) { | 1328 | if (ivtv_debug < 0 || ivtv_debug > 1023) { |
1330 | ivtv_debug = 0; | 1329 | ivtv_debug = 0; |
1331 | printk(KERN_INFO "ivtv: debug value must be >= 0 and <= 511!\n"); | 1330 | printk(KERN_INFO "ivtv: debug value must be >= 0 and <= 1023!\n"); |
1332 | } | 1331 | } |
1333 | 1332 | ||
1334 | if (pci_register_driver(&ivtv_pci_driver)) { | 1333 | if (pci_register_driver(&ivtv_pci_driver)) { |
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index e6e56f175f3f..6c1a85f1ee1b 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -268,6 +268,8 @@ extern const u32 yuv_offset[4]; | |||
268 | #define IVTV_DBGFLG_IRQ (1 << 6) | 268 | #define IVTV_DBGFLG_IRQ (1 << 6) |
269 | #define IVTV_DBGFLG_DEC (1 << 7) | 269 | #define IVTV_DBGFLG_DEC (1 << 7) |
270 | #define IVTV_DBGFLG_YUV (1 << 8) | 270 | #define IVTV_DBGFLG_YUV (1 << 8) |
271 | /* Flag to turn on high volume debugging */ | ||
272 | #define IVTV_DBGFLG_HIGHVOL (1 << 9) | ||
271 | 273 | ||
272 | /* NOTE: extra space before comma in 'itv->num , ## args' is required for | 274 | /* NOTE: extra space before comma in 'itv->num , ## args' is required for |
273 | gcc-2.95, otherwise it won't compile. */ | 275 | gcc-2.95, otherwise it won't compile. */ |
@@ -286,6 +288,21 @@ extern const u32 yuv_offset[4]; | |||
286 | #define IVTV_DEBUG_DEC(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args) | 288 | #define IVTV_DEBUG_DEC(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args) |
287 | #define IVTV_DEBUG_YUV(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) | 289 | #define IVTV_DEBUG_YUV(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) |
288 | 290 | ||
291 | #define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \ | ||
292 | do { \ | ||
293 | if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \ | ||
294 | printk(KERN_INFO "ivtv%d " type ": " fmt, itv->num , ## args); \ | ||
295 | } while (0) | ||
296 | #define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warning", fmt , ## args) | ||
297 | #define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info",fmt , ## args) | ||
298 | #define IVTV_DEBUG_HI_API(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_API, "api", fmt , ## args) | ||
299 | #define IVTV_DEBUG_HI_DMA(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DMA, "dma", fmt , ## args) | ||
300 | #define IVTV_DEBUG_HI_IOCTL(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args) | ||
301 | #define IVTV_DEBUG_HI_I2C(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_I2C, "i2c", fmt , ## args) | ||
302 | #define IVTV_DEBUG_HI_IRQ(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IRQ, "irq", fmt , ## args) | ||
303 | #define IVTV_DEBUG_HI_DEC(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DEC, "dec", fmt , ## args) | ||
304 | #define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) | ||
305 | |||
289 | #define IVTV_FB_DEBUG(x, type, fmt, args...) \ | 306 | #define IVTV_FB_DEBUG(x, type, fmt, args...) \ |
290 | do { \ | 307 | do { \ |
291 | if ((x) & ivtv_debug) \ | 308 | if ((x) & ivtv_debug) \ |
@@ -650,7 +667,6 @@ struct vbi_info { | |||
650 | /* convenience pointer to sliced struct in vbi_in union */ | 667 | /* convenience pointer to sliced struct in vbi_in union */ |
651 | struct v4l2_sliced_vbi_format *sliced_in; | 668 | struct v4l2_sliced_vbi_format *sliced_in; |
652 | u32 service_set_in; | 669 | u32 service_set_in; |
653 | u32 service_set_out; | ||
654 | int insert_mpeg; | 670 | int insert_mpeg; |
655 | 671 | ||
656 | /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines. | 672 | /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines. |
@@ -723,6 +739,7 @@ struct ivtv { | |||
723 | int search_pack_header; | 739 | int search_pack_header; |
724 | 740 | ||
725 | spinlock_t dma_reg_lock; /* lock access to DMA engine registers */ | 741 | spinlock_t dma_reg_lock; /* lock access to DMA engine registers */ |
742 | struct mutex serialize_lock; /* lock used to serialize starting streams */ | ||
726 | 743 | ||
727 | /* User based DMA for OSD */ | 744 | /* User based DMA for OSD */ |
728 | struct ivtv_user_dma udma; | 745 | struct ivtv_user_dma udma; |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 555d5e6369c3..ee7e884e9c4f 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -406,7 +406,7 @@ static ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t co | |||
406 | ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0; | 406 | ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0; |
407 | struct ivtv *itv = s->itv; | 407 | struct ivtv *itv = s->itv; |
408 | 408 | ||
409 | IVTV_DEBUG_INFO("read %zd from %s, got %zd\n", count, s->name, rc); | 409 | IVTV_DEBUG_HI_INFO("read %zd from %s, got %zd\n", count, s->name, rc); |
410 | if (rc > 0) | 410 | if (rc > 0) |
411 | pos += rc; | 411 | pos += rc; |
412 | return rc; | 412 | return rc; |
@@ -497,7 +497,7 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_ | |||
497 | struct ivtv_stream *s = &itv->streams[id->type]; | 497 | struct ivtv_stream *s = &itv->streams[id->type]; |
498 | int rc; | 498 | int rc; |
499 | 499 | ||
500 | IVTV_DEBUG_IOCTL("read %zd bytes from %s\n", count, s->name); | 500 | IVTV_DEBUG_HI_IOCTL("read %zd bytes from %s\n", count, s->name); |
501 | 501 | ||
502 | rc = ivtv_start_capture(id); | 502 | rc = ivtv_start_capture(id); |
503 | if (rc) | 503 | if (rc) |
@@ -535,7 +535,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c | |||
535 | int rc; | 535 | int rc; |
536 | DEFINE_WAIT(wait); | 536 | DEFINE_WAIT(wait); |
537 | 537 | ||
538 | IVTV_DEBUG_IOCTL("write %zd bytes to %s\n", count, s->name); | 538 | IVTV_DEBUG_HI_IOCTL("write %zd bytes to %s\n", count, s->name); |
539 | 539 | ||
540 | if (s->type != IVTV_DEC_STREAM_TYPE_MPG && | 540 | if (s->type != IVTV_DEC_STREAM_TYPE_MPG && |
541 | s->type != IVTV_DEC_STREAM_TYPE_YUV && | 541 | s->type != IVTV_DEC_STREAM_TYPE_YUV && |
@@ -643,7 +643,7 @@ retry: | |||
643 | to transfer the rest. */ | 643 | to transfer the rest. */ |
644 | if (count && !(filp->f_flags & O_NONBLOCK)) | 644 | if (count && !(filp->f_flags & O_NONBLOCK)) |
645 | goto retry; | 645 | goto retry; |
646 | IVTV_DEBUG_INFO("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); | 646 | IVTV_DEBUG_HI_INFO("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); |
647 | return bytes_written; | 647 | return bytes_written; |
648 | } | 648 | } |
649 | 649 | ||
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c index d4c910b782af..2b6208a6a108 100644 --- a/drivers/media/video/ivtv/ivtv-firmware.c +++ b/drivers/media/video/ivtv/ivtv-firmware.c | |||
@@ -56,9 +56,7 @@ retry: | |||
56 | volatile u32 __iomem *dst = (volatile u32 __iomem *)mem; | 56 | volatile u32 __iomem *dst = (volatile u32 __iomem *)mem; |
57 | const u32 *src = (const u32 *)fw->data; | 57 | const u32 *src = (const u32 *)fw->data; |
58 | 58 | ||
59 | /* temporarily allow 256 KB encoding firmwares as well for | 59 | if (fw->size != size) { |
60 | compatibility with blackbird cards */ | ||
61 | if (fw->size != size && fw->size != 256 * 1024) { | ||
62 | /* Due to race conditions in firmware loading (esp. with udev <0.95) | 60 | /* Due to race conditions in firmware loading (esp. with udev <0.95) |
63 | the wrong file was sometimes loaded. So we check filesizes to | 61 | the wrong file was sometimes loaded. So we check filesizes to |
64 | see if at least the right-sized file was loaded. If not, then we | 62 | see if at least the right-sized file was loaded. If not, then we |
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c index bc8f8ca2961f..676418cbaaad 100644 --- a/drivers/media/video/ivtv/ivtv-gpio.c +++ b/drivers/media/video/ivtv/ivtv-gpio.c | |||
@@ -115,8 +115,7 @@ void ivtv_reset_ir_gpio(struct ivtv *itv) | |||
115 | curout = (curout & ~0xF) | 1; | 115 | curout = (curout & ~0xF) | 1; |
116 | write_reg(curout, IVTV_REG_GPIO_OUT); | 116 | write_reg(curout, IVTV_REG_GPIO_OUT); |
117 | /* We could use something else for smaller time */ | 117 | /* We could use something else for smaller time */ |
118 | current->state = TASK_INTERRUPTIBLE; | 118 | schedule_timeout_interruptible(msecs_to_jiffies(1)); |
119 | schedule_timeout(1); | ||
120 | curout |= 2; | 119 | curout |= 2; |
121 | write_reg(curout, IVTV_REG_GPIO_OUT); | 120 | write_reg(curout, IVTV_REG_GPIO_OUT); |
122 | curdir &= ~0x80; | 121 | curdir &= ~0x80; |
@@ -138,13 +137,11 @@ int ivtv_reset_tuner_gpio(enum v4l2_tuner_type mode, void *priv, int ptr) | |||
138 | 137 | ||
139 | curout &= ~(1 << 12); | 138 | curout &= ~(1 << 12); |
140 | write_reg(curout, IVTV_REG_GPIO_OUT); | 139 | write_reg(curout, IVTV_REG_GPIO_OUT); |
141 | current->state = TASK_INTERRUPTIBLE; | 140 | schedule_timeout_interruptible(msecs_to_jiffies(1)); |
142 | schedule_timeout(1); | ||
143 | 141 | ||
144 | curout |= (1 << 12); | 142 | curout |= (1 << 12); |
145 | write_reg(curout, IVTV_REG_GPIO_OUT); | 143 | write_reg(curout, IVTV_REG_GPIO_OUT); |
146 | current->state = TASK_INTERRUPTIBLE; | 144 | schedule_timeout_interruptible(msecs_to_jiffies(1)); |
147 | schedule_timeout(1); | ||
148 | 145 | ||
149 | return 0; | 146 | return 0; |
150 | } | 147 | } |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 57af1762de1f..4773453e8dab 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -1159,7 +1159,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1159 | 1159 | ||
1160 | memset(fb, 0, sizeof(*fb)); | 1160 | memset(fb, 0, sizeof(*fb)); |
1161 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1161 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1162 | break; | 1162 | return -EINVAL; |
1163 | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | | 1163 | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | |
1164 | V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA; | 1164 | V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA; |
1165 | fb->fmt.pixelformat = itv->osd_pixelformat; | 1165 | fb->fmt.pixelformat = itv->osd_pixelformat; |
@@ -1179,7 +1179,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void | |||
1179 | struct v4l2_framebuffer *fb = arg; | 1179 | struct v4l2_framebuffer *fb = arg; |
1180 | 1180 | ||
1181 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) | 1181 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) |
1182 | break; | 1182 | return -EINVAL; |
1183 | itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; | 1183 | itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; |
1184 | itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0; | 1184 | itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0; |
1185 | itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; | 1185 | itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; |
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index ba98bf054f2e..1a3ee464a826 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c | |||
@@ -48,7 +48,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv) | |||
48 | struct list_head *p; | 48 | struct list_head *p; |
49 | int i = 0; | 49 | int i = 0; |
50 | 50 | ||
51 | IVTV_DEBUG_DMA("ivtv_pio_work_handler\n"); | 51 | IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n"); |
52 | if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS || | 52 | if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS || |
53 | s->v4l2dev == NULL || !ivtv_use_pio(s)) { | 53 | s->v4l2dev == NULL || !ivtv_use_pio(s)) { |
54 | itv->cur_pio_stream = -1; | 54 | itv->cur_pio_stream = -1; |
@@ -56,7 +56,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv) | |||
56 | write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); | 56 | write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); |
57 | return; | 57 | return; |
58 | } | 58 | } |
59 | IVTV_DEBUG_DMA("Process PIO %s\n", s->name); | 59 | IVTV_DEBUG_HI_DMA("Process PIO %s\n", s->name); |
60 | buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list); | 60 | buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list); |
61 | list_for_each(p, &s->q_dma.list) { | 61 | list_for_each(p, &s->q_dma.list) { |
62 | struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); | 62 | struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); |
@@ -187,7 +187,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA | |||
187 | bytes_needed += UVsize; | 187 | bytes_needed += UVsize; |
188 | } | 188 | } |
189 | 189 | ||
190 | IVTV_DEBUG_DMA("%s %s: 0x%08x bytes at 0x%08x\n", | 190 | IVTV_DEBUG_HI_DMA("%s %s: 0x%08x bytes at 0x%08x\n", |
191 | ivtv_use_pio(s) ? "PIO" : "DMA", s->name, bytes_needed, offset); | 191 | ivtv_use_pio(s) ? "PIO" : "DMA", s->name, bytes_needed, offset); |
192 | 192 | ||
193 | rc = ivtv_queue_move(s, &s->q_free, &s->q_full, &s->q_predma, bytes_needed); | 193 | rc = ivtv_queue_move(s, &s->q_free, &s->q_full, &s->q_predma, bytes_needed); |
@@ -242,7 +242,7 @@ static void dma_post(struct ivtv_stream *s) | |||
242 | u32 *u32buf; | 242 | u32 *u32buf; |
243 | int x = 0; | 243 | int x = 0; |
244 | 244 | ||
245 | IVTV_DEBUG_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA", | 245 | IVTV_DEBUG_HI_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA", |
246 | s->name, s->dma_offset); | 246 | s->name, s->dma_offset); |
247 | list_for_each(p, &s->q_dma.list) { | 247 | list_for_each(p, &s->q_dma.list) { |
248 | buf = list_entry(p, struct ivtv_buffer, list); | 248 | buf = list_entry(p, struct ivtv_buffer, list); |
@@ -321,7 +321,7 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock) | |||
321 | unsigned long flags = 0; | 321 | unsigned long flags = 0; |
322 | int idx = 0; | 322 | int idx = 0; |
323 | 323 | ||
324 | IVTV_DEBUG_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset); | 324 | IVTV_DEBUG_HI_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset); |
325 | buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list); | 325 | buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list); |
326 | list_for_each(p, &s->q_predma.list) { | 326 | list_for_each(p, &s->q_predma.list) { |
327 | struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); | 327 | struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); |
@@ -368,7 +368,7 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) | |||
368 | struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | 368 | struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; |
369 | int i; | 369 | int i; |
370 | 370 | ||
371 | IVTV_DEBUG_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name); | 371 | IVTV_DEBUG_HI_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name); |
372 | 372 | ||
373 | if (s->q_predma.bytesused) | 373 | if (s->q_predma.bytesused) |
374 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); | 374 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); |
@@ -397,7 +397,7 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) | |||
397 | itv->vbi.dma_offset = s_vbi->dma_offset; | 397 | itv->vbi.dma_offset = s_vbi->dma_offset; |
398 | s_vbi->SG_length = 0; | 398 | s_vbi->SG_length = 0; |
399 | set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags); | 399 | set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags); |
400 | IVTV_DEBUG_DMA("include DMA for %s\n", s->name); | 400 | IVTV_DEBUG_HI_DMA("include DMA for %s\n", s->name); |
401 | } | 401 | } |
402 | 402 | ||
403 | /* Mark last buffer size for Interrupt flag */ | 403 | /* Mark last buffer size for Interrupt flag */ |
@@ -431,7 +431,7 @@ static void ivtv_dma_dec_start(struct ivtv_stream *s) | |||
431 | 431 | ||
432 | if (s->q_predma.bytesused) | 432 | if (s->q_predma.bytesused) |
433 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); | 433 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); |
434 | IVTV_DEBUG_DMA("start DMA for %s\n", s->name); | 434 | IVTV_DEBUG_HI_DMA("start DMA for %s\n", s->name); |
435 | /* put SG Handle into register 0x0c */ | 435 | /* put SG Handle into register 0x0c */ |
436 | write_reg(s->SG_handle, IVTV_REG_DECDMAADDR); | 436 | write_reg(s->SG_handle, IVTV_REG_DECDMAADDR); |
437 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); | 437 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); |
@@ -447,7 +447,7 @@ static void ivtv_irq_dma_read(struct ivtv *itv) | |||
447 | struct ivtv_buffer *buf; | 447 | struct ivtv_buffer *buf; |
448 | int hw_stream_type; | 448 | int hw_stream_type; |
449 | 449 | ||
450 | IVTV_DEBUG_IRQ("DEC DMA READ\n"); | 450 | IVTV_DEBUG_HI_IRQ("DEC DMA READ\n"); |
451 | del_timer(&itv->dma_timer); | 451 | del_timer(&itv->dma_timer); |
452 | if (read_reg(IVTV_REG_DMASTATUS) & 0x14) { | 452 | if (read_reg(IVTV_REG_DMASTATUS) & 0x14) { |
453 | IVTV_DEBUG_WARN("DEC DMA ERROR %x\n", read_reg(IVTV_REG_DMASTATUS)); | 453 | IVTV_DEBUG_WARN("DEC DMA ERROR %x\n", read_reg(IVTV_REG_DMASTATUS)); |
@@ -462,7 +462,7 @@ static void ivtv_irq_dma_read(struct ivtv *itv) | |||
462 | s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; | 462 | s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; |
463 | hw_stream_type = 0; | 463 | hw_stream_type = 0; |
464 | } | 464 | } |
465 | IVTV_DEBUG_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused); | 465 | IVTV_DEBUG_HI_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused); |
466 | 466 | ||
467 | ivtv_stream_sync_for_cpu(s); | 467 | ivtv_stream_sync_for_cpu(s); |
468 | 468 | ||
@@ -495,7 +495,7 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv) | |||
495 | 495 | ||
496 | del_timer(&itv->dma_timer); | 496 | del_timer(&itv->dma_timer); |
497 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); | 497 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); |
498 | IVTV_DEBUG_IRQ("ENC DMA COMPLETE %x %d\n", data[0], data[1]); | 498 | IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d\n", data[0], data[1]); |
499 | if (test_and_clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags)) | 499 | if (test_and_clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags)) |
500 | data[1] = 3; | 500 | data[1] = 3; |
501 | else if (data[1] > 2) | 501 | else if (data[1] > 2) |
@@ -532,7 +532,7 @@ static void ivtv_irq_enc_pio_complete(struct ivtv *itv) | |||
532 | return; | 532 | return; |
533 | } | 533 | } |
534 | s = &itv->streams[itv->cur_pio_stream]; | 534 | s = &itv->streams[itv->cur_pio_stream]; |
535 | IVTV_DEBUG_IRQ("ENC PIO COMPLETE %s\n", s->name); | 535 | IVTV_DEBUG_HI_IRQ("ENC PIO COMPLETE %s\n", s->name); |
536 | s->SG_length = 0; | 536 | s->SG_length = 0; |
537 | clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); | 537 | clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); |
538 | clear_bit(IVTV_F_I_PIO, &itv->i_flags); | 538 | clear_bit(IVTV_F_I_PIO, &itv->i_flags); |
@@ -590,7 +590,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv) | |||
590 | 590 | ||
591 | /* Get DMA destination and size arguments from card */ | 591 | /* Get DMA destination and size arguments from card */ |
592 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, data); | 592 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, data); |
593 | IVTV_DEBUG_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]); | 593 | IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]); |
594 | 594 | ||
595 | if (data[0] > 2 || data[1] == 0 || data[2] == 0) { | 595 | if (data[0] > 2 || data[1] == 0 || data[2] == 0) { |
596 | IVTV_DEBUG_WARN("Unknown input: %08x %08x %08x\n", | 596 | IVTV_DEBUG_WARN("Unknown input: %08x %08x %08x\n", |
@@ -610,7 +610,7 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv) | |||
610 | u32 data[CX2341X_MBOX_MAX_DATA]; | 610 | u32 data[CX2341X_MBOX_MAX_DATA]; |
611 | struct ivtv_stream *s; | 611 | struct ivtv_stream *s; |
612 | 612 | ||
613 | IVTV_DEBUG_IRQ("ENC START VBI CAP\n"); | 613 | IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n"); |
614 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | 614 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; |
615 | 615 | ||
616 | /* If more than two VBI buffers are pending, then | 616 | /* If more than two VBI buffers are pending, then |
@@ -644,7 +644,7 @@ static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv) | |||
644 | u32 data[CX2341X_MBOX_MAX_DATA]; | 644 | u32 data[CX2341X_MBOX_MAX_DATA]; |
645 | struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI]; | 645 | struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI]; |
646 | 646 | ||
647 | IVTV_DEBUG_IRQ("DEC VBI REINSERT\n"); | 647 | IVTV_DEBUG_HI_IRQ("DEC VBI REINSERT\n"); |
648 | if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) && | 648 | if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) && |
649 | !stream_enc_dma_append(s, data)) { | 649 | !stream_enc_dma_append(s, data)) { |
650 | set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags); | 650 | set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags); |
@@ -669,7 +669,7 @@ static void ivtv_irq_dec_data_req(struct ivtv *itv) | |||
669 | itv->dma_data_req_offset = data[1]; | 669 | itv->dma_data_req_offset = data[1]; |
670 | s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; | 670 | s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; |
671 | } | 671 | } |
672 | IVTV_DEBUG_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused, | 672 | IVTV_DEBUG_HI_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused, |
673 | itv->dma_data_req_offset, itv->dma_data_req_size); | 673 | itv->dma_data_req_offset, itv->dma_data_req_size); |
674 | if (itv->dma_data_req_size == 0 || s->q_full.bytesused < itv->dma_data_req_size) { | 674 | if (itv->dma_data_req_size == 0 || s->q_full.bytesused < itv->dma_data_req_size) { |
675 | set_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags); | 675 | set_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags); |
@@ -791,10 +791,10 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id) | |||
791 | /* Exclude interrupts noted below from the output, otherwise the log is flooded with | 791 | /* Exclude interrupts noted below from the output, otherwise the log is flooded with |
792 | these messages */ | 792 | these messages */ |
793 | if (combo & ~0xff6d0400) | 793 | if (combo & ~0xff6d0400) |
794 | IVTV_DEBUG_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo); | 794 | IVTV_DEBUG_HI_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo); |
795 | 795 | ||
796 | if (combo & IVTV_IRQ_DEC_DMA_COMPLETE) { | 796 | if (combo & IVTV_IRQ_DEC_DMA_COMPLETE) { |
797 | IVTV_DEBUG_IRQ("DEC DMA COMPLETE\n"); | 797 | IVTV_DEBUG_HI_IRQ("DEC DMA COMPLETE\n"); |
798 | } | 798 | } |
799 | 799 | ||
800 | if (combo & IVTV_IRQ_DMA_READ) { | 800 | if (combo & IVTV_IRQ_DMA_READ) { |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 6af88ae9295f..287117187499 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -446,6 +446,9 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) | |||
446 | if (s->v4l2dev == NULL) | 446 | if (s->v4l2dev == NULL) |
447 | return -EINVAL; | 447 | return -EINVAL; |
448 | 448 | ||
449 | /* Big serialization lock to ensure no two streams are started | ||
450 | simultaneously: that can give all sorts of weird results. */ | ||
451 | mutex_lock(&itv->serialize_lock); | ||
449 | IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); | 452 | IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); |
450 | 453 | ||
451 | switch (s->type) { | 454 | switch (s->type) { |
@@ -487,6 +490,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) | |||
487 | 0, sizeof(itv->vbi.sliced_mpeg_size)); | 490 | 0, sizeof(itv->vbi.sliced_mpeg_size)); |
488 | break; | 491 | break; |
489 | default: | 492 | default: |
493 | mutex_unlock(&itv->serialize_lock); | ||
490 | return -EINVAL; | 494 | return -EINVAL; |
491 | } | 495 | } |
492 | s->subtype = subtype; | 496 | s->subtype = subtype; |
@@ -568,6 +572,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) | |||
568 | if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype)) | 572 | if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype)) |
569 | { | 573 | { |
570 | IVTV_DEBUG_WARN( "Error starting capture!\n"); | 574 | IVTV_DEBUG_WARN( "Error starting capture!\n"); |
575 | mutex_unlock(&itv->serialize_lock); | ||
571 | return -EINVAL; | 576 | return -EINVAL; |
572 | } | 577 | } |
573 | 578 | ||
@@ -583,6 +588,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) | |||
583 | 588 | ||
584 | /* you're live! sit back and await interrupts :) */ | 589 | /* you're live! sit back and await interrupts :) */ |
585 | atomic_inc(&itv->capturing); | 590 | atomic_inc(&itv->capturing); |
591 | mutex_unlock(&itv->serialize_lock); | ||
586 | return 0; | 592 | return 0; |
587 | } | 593 | } |
588 | 594 | ||
@@ -762,17 +768,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) | |||
762 | /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */ | 768 | /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */ |
763 | ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype); | 769 | ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype); |
764 | 770 | ||
765 | /* only run these if we're shutting down the last cap */ | ||
766 | if (atomic_read(&itv->capturing) - 1 == 0) { | ||
767 | /* event notification (off) */ | ||
768 | if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) { | ||
769 | /* type: 0 = refresh */ | ||
770 | /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */ | ||
771 | ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1); | ||
772 | ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST); | ||
773 | } | ||
774 | } | ||
775 | |||
776 | then = jiffies; | 771 | then = jiffies; |
777 | 772 | ||
778 | if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) { | 773 | if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) { |
@@ -812,7 +807,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) | |||
812 | then = jiffies; | 807 | then = jiffies; |
813 | /* Make sure DMA is complete */ | 808 | /* Make sure DMA is complete */ |
814 | add_wait_queue(&s->waitq, &wait); | 809 | add_wait_queue(&s->waitq, &wait); |
815 | set_current_state(TASK_INTERRUPTIBLE); | ||
816 | do { | 810 | do { |
817 | /* check if DMA is pending */ | 811 | /* check if DMA is pending */ |
818 | if ((s->type == IVTV_ENC_STREAM_TYPE_MPG) && /* MPG Only */ | 812 | if ((s->type == IVTV_ENC_STREAM_TYPE_MPG) && /* MPG Only */ |
@@ -827,9 +821,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) | |||
827 | } else if (read_reg(IVTV_REG_DMASTATUS) & 0x02) { | 821 | } else if (read_reg(IVTV_REG_DMASTATUS) & 0x02) { |
828 | break; | 822 | break; |
829 | } | 823 | } |
830 | 824 | } while (!ivtv_sleep_timeout(HZ / 100, 1) && then + HZ * 2 > jiffies); | |
831 | ivtv_sleep_timeout(HZ / 100, 1); | ||
832 | } while (then + HZ * 2 > jiffies); | ||
833 | 825 | ||
834 | set_current_state(TASK_RUNNING); | 826 | set_current_state(TASK_RUNNING); |
835 | remove_wait_queue(&s->waitq, &wait); | 827 | remove_wait_queue(&s->waitq, &wait); |
@@ -840,17 +832,30 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) | |||
840 | /* Clear capture and no-read bits */ | 832 | /* Clear capture and no-read bits */ |
841 | clear_bit(IVTV_F_S_STREAMING, &s->s_flags); | 833 | clear_bit(IVTV_F_S_STREAMING, &s->s_flags); |
842 | 834 | ||
835 | /* ensure these global cleanup actions are done only once */ | ||
836 | mutex_lock(&itv->serialize_lock); | ||
837 | |||
843 | if (s->type == IVTV_ENC_STREAM_TYPE_VBI) | 838 | if (s->type == IVTV_ENC_STREAM_TYPE_VBI) |
844 | ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP); | 839 | ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP); |
845 | 840 | ||
846 | if (atomic_read(&itv->capturing) > 0) { | 841 | if (atomic_read(&itv->capturing) > 0) { |
842 | mutex_unlock(&itv->serialize_lock); | ||
847 | return 0; | 843 | return 0; |
848 | } | 844 | } |
849 | 845 | ||
850 | /* Set the following Interrupt mask bits for capture */ | 846 | /* Set the following Interrupt mask bits for capture */ |
851 | ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE); | 847 | ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE); |
852 | 848 | ||
849 | /* event notification (off) */ | ||
850 | if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) { | ||
851 | /* type: 0 = refresh */ | ||
852 | /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */ | ||
853 | ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1); | ||
854 | ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST); | ||
855 | } | ||
856 | |||
853 | wake_up(&s->waitq); | 857 | wake_up(&s->waitq); |
858 | mutex_unlock(&itv->serialize_lock); | ||
854 | 859 | ||
855 | return 0; | 860 | return 0; |
856 | } | 861 | } |
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c index 3ba46e07ea1f..a7282a91bd97 100644 --- a/drivers/media/video/ivtv/ivtv-vbi.c +++ b/drivers/media/video/ivtv/ivtv-vbi.c | |||
@@ -219,31 +219,23 @@ ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count) | |||
219 | int found_cc = 0; | 219 | int found_cc = 0; |
220 | int cc_pos = itv->vbi.cc_pos; | 220 | int cc_pos = itv->vbi.cc_pos; |
221 | 221 | ||
222 | if (itv->vbi.service_set_out == 0) | ||
223 | return -EPERM; | ||
224 | |||
225 | while (count >= sizeof(struct v4l2_sliced_vbi_data)) { | 222 | while (count >= sizeof(struct v4l2_sliced_vbi_data)) { |
226 | switch (p->id) { | 223 | switch (p->id) { |
227 | case V4L2_SLICED_CAPTION_525: | 224 | case V4L2_SLICED_CAPTION_525: |
228 | if (p->id == V4L2_SLICED_CAPTION_525 && | 225 | if (p->line == 21) { |
229 | p->line == 21 && | 226 | found_cc = 1; |
230 | (itv->vbi.service_set_out & | 227 | if (p->field) { |
231 | V4L2_SLICED_CAPTION_525) == 0) { | 228 | cc[2] = p->data[0]; |
232 | break; | 229 | cc[3] = p->data[1]; |
233 | } | 230 | } else { |
234 | found_cc = 1; | 231 | cc[0] = p->data[0]; |
235 | if (p->field) { | 232 | cc[1] = p->data[1]; |
236 | cc[2] = p->data[0]; | 233 | } |
237 | cc[3] = p->data[1]; | ||
238 | } else { | ||
239 | cc[0] = p->data[0]; | ||
240 | cc[1] = p->data[1]; | ||
241 | } | 234 | } |
242 | break; | 235 | break; |
243 | 236 | ||
244 | case V4L2_SLICED_VPS: | 237 | case V4L2_SLICED_VPS: |
245 | if (p->line == 16 && p->field == 0 && | 238 | if (p->line == 16 && p->field == 0) { |
246 | (itv->vbi.service_set_out & V4L2_SLICED_VPS)) { | ||
247 | itv->vbi.vps[0] = p->data[2]; | 239 | itv->vbi.vps[0] = p->data[2]; |
248 | itv->vbi.vps[1] = p->data[8]; | 240 | itv->vbi.vps[1] = p->data[8]; |
249 | itv->vbi.vps[2] = p->data[9]; | 241 | itv->vbi.vps[2] = p->data[9]; |
@@ -255,8 +247,7 @@ ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count) | |||
255 | break; | 247 | break; |
256 | 248 | ||
257 | case V4L2_SLICED_WSS_625: | 249 | case V4L2_SLICED_WSS_625: |
258 | if (p->line == 23 && p->field == 0 && | 250 | if (p->line == 23 && p->field == 0) { |
259 | (itv->vbi.service_set_out & V4L2_SLICED_WSS_625)) { | ||
260 | /* No lock needed for WSS */ | 251 | /* No lock needed for WSS */ |
261 | itv->vbi.wss = p->data[0] | (p->data[1] << 8); | 252 | itv->vbi.wss = p->data[0] | (p->data[1] << 8); |
262 | itv->vbi.wss_found = 1; | 253 | itv->vbi.wss_found = 1; |
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 3bb7d6634862..507b1d4260ed 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -157,8 +157,7 @@ static int msp_read(struct i2c_client *client, int dev, int addr) | |||
157 | break; | 157 | break; |
158 | v4l_warn(client, "I/O error #%d (read 0x%02x/0x%02x)\n", err, | 158 | v4l_warn(client, "I/O error #%d (read 0x%02x/0x%02x)\n", err, |
159 | dev, addr); | 159 | dev, addr); |
160 | current->state = TASK_INTERRUPTIBLE; | 160 | schedule_timeout_interruptible(msecs_to_jiffies(10)); |
161 | schedule_timeout(msecs_to_jiffies(10)); | ||
162 | } | 161 | } |
163 | if (err == 3) { | 162 | if (err == 3) { |
164 | v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n"); | 163 | v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n"); |
@@ -197,8 +196,7 @@ static int msp_write(struct i2c_client *client, int dev, int addr, int val) | |||
197 | break; | 196 | break; |
198 | v4l_warn(client, "I/O error #%d (write 0x%02x/0x%02x)\n", err, | 197 | v4l_warn(client, "I/O error #%d (write 0x%02x/0x%02x)\n", err, |
199 | dev, addr); | 198 | dev, addr); |
200 | current->state = TASK_INTERRUPTIBLE; | 199 | schedule_timeout_interruptible(msecs_to_jiffies(10)); |
201 | schedule_timeout(msecs_to_jiffies(10)); | ||
202 | } | 200 | } |
203 | if (err == 3) { | 201 | if (err == 3) { |
204 | v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n"); | 202 | v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n"); |
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c index c7c9f3f8715c..7549114aaaca 100644 --- a/drivers/media/video/mt20xx.c +++ b/drivers/media/video/mt20xx.c | |||
@@ -7,7 +7,7 @@ | |||
7 | #include <linux/i2c.h> | 7 | #include <linux/i2c.h> |
8 | #include <linux/videodev.h> | 8 | #include <linux/videodev.h> |
9 | #include <linux/moduleparam.h> | 9 | #include <linux/moduleparam.h> |
10 | #include <media/tuner.h> | 10 | #include "tuner-driver.h" |
11 | 11 | ||
12 | /* ---------------------------------------------------------------------- */ | 12 | /* ---------------------------------------------------------------------- */ |
13 | 13 | ||
@@ -37,6 +37,19 @@ static char *microtune_part[] = { | |||
37 | [ MT2050 ] = "MT2050", | 37 | [ MT2050 ] = "MT2050", |
38 | }; | 38 | }; |
39 | 39 | ||
40 | struct microtune_priv { | ||
41 | unsigned int xogc; | ||
42 | unsigned int radio_if2; | ||
43 | }; | ||
44 | |||
45 | static void microtune_release(struct i2c_client *c) | ||
46 | { | ||
47 | struct tuner *t = i2c_get_clientdata(c); | ||
48 | |||
49 | kfree(t->priv); | ||
50 | t->priv = NULL; | ||
51 | } | ||
52 | |||
40 | // IsSpurInBand()? | 53 | // IsSpurInBand()? |
41 | static int mt2032_spurcheck(struct i2c_client *c, | 54 | static int mt2032_spurcheck(struct i2c_client *c, |
42 | int f1, int f2, int spectrum_from,int spectrum_to) | 55 | int f1, int f2, int spectrum_from,int spectrum_to) |
@@ -218,6 +231,7 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin, | |||
218 | unsigned char buf[21]; | 231 | unsigned char buf[21]; |
219 | int lint_try,ret,sel,lock=0; | 232 | int lint_try,ret,sel,lock=0; |
220 | struct tuner *t = i2c_get_clientdata(c); | 233 | struct tuner *t = i2c_get_clientdata(c); |
234 | struct microtune_priv *priv = t->priv; | ||
221 | 235 | ||
222 | tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", | 236 | tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", |
223 | rfin,if1,if2,from,to); | 237 | rfin,if1,if2,from,to); |
@@ -227,7 +241,7 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin, | |||
227 | i2c_master_recv(c,buf,21); | 241 | i2c_master_recv(c,buf,21); |
228 | 242 | ||
229 | buf[0]=0; | 243 | buf[0]=0; |
230 | ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc); | 244 | ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc); |
231 | if (ret<0) | 245 | if (ret<0) |
232 | return; | 246 | return; |
233 | 247 | ||
@@ -251,10 +265,10 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin, | |||
251 | 265 | ||
252 | tuner_dbg("mt2032: re-init PLLs by LINT\n"); | 266 | tuner_dbg("mt2032: re-init PLLs by LINT\n"); |
253 | buf[0]=7; | 267 | buf[0]=7; |
254 | buf[1]=0x80 +8+t->xogc; // set LINT to re-init PLLs | 268 | buf[1]=0x80 +8+priv->xogc; // set LINT to re-init PLLs |
255 | i2c_master_send(c,buf,2); | 269 | i2c_master_send(c,buf,2); |
256 | mdelay(10); | 270 | mdelay(10); |
257 | buf[1]=8+t->xogc; | 271 | buf[1]=8+priv->xogc; |
258 | i2c_master_send(c,buf,2); | 272 | i2c_master_send(c,buf,2); |
259 | } | 273 | } |
260 | 274 | ||
@@ -294,17 +308,25 @@ static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
294 | static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq) | 308 | static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq) |
295 | { | 309 | { |
296 | struct tuner *t = i2c_get_clientdata(c); | 310 | struct tuner *t = i2c_get_clientdata(c); |
297 | int if2 = t->radio_if2; | 311 | struct microtune_priv *priv = t->priv; |
312 | int if2 = priv->radio_if2; | ||
298 | 313 | ||
299 | // per Manual for FM tuning: first if center freq. 1085 MHz | 314 | // per Manual for FM tuning: first if center freq. 1085 MHz |
300 | mt2032_set_if_freq(c, freq * 1000 / 16, | 315 | mt2032_set_if_freq(c, freq * 1000 / 16, |
301 | 1085*1000*1000,if2,if2,if2); | 316 | 1085*1000*1000,if2,if2,if2); |
302 | } | 317 | } |
303 | 318 | ||
319 | static struct tuner_operations mt2032_tuner_ops = { | ||
320 | .set_tv_freq = mt2032_set_tv_freq, | ||
321 | .set_radio_freq = mt2032_set_radio_freq, | ||
322 | .release = microtune_release, | ||
323 | }; | ||
324 | |||
304 | // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 | 325 | // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 |
305 | static int mt2032_init(struct i2c_client *c) | 326 | static int mt2032_init(struct i2c_client *c) |
306 | { | 327 | { |
307 | struct tuner *t = i2c_get_clientdata(c); | 328 | struct tuner *t = i2c_get_clientdata(c); |
329 | struct microtune_priv *priv = t->priv; | ||
308 | unsigned char buf[21]; | 330 | unsigned char buf[21]; |
309 | int ret,xogc,xok=0; | 331 | int ret,xogc,xok=0; |
310 | 332 | ||
@@ -351,23 +373,23 @@ static int mt2032_init(struct i2c_client *c) | |||
351 | if (ret!=2) | 373 | if (ret!=2) |
352 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); | 374 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); |
353 | } while (xok != 1 ); | 375 | } while (xok != 1 ); |
354 | t->xogc=xogc; | 376 | priv->xogc=xogc; |
377 | |||
378 | memcpy(&t->ops, &mt2032_tuner_ops, sizeof(struct tuner_operations)); | ||
355 | 379 | ||
356 | t->set_tv_freq = mt2032_set_tv_freq; | ||
357 | t->set_radio_freq = mt2032_set_radio_freq; | ||
358 | return(1); | 380 | return(1); |
359 | } | 381 | } |
360 | 382 | ||
361 | static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna) | 383 | static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna) |
362 | { | 384 | { |
363 | struct tuner *t = i2c_get_clientdata(c); | 385 | struct tuner *t = i2c_get_clientdata(c); |
364 | unsigned char buf[2]; | 386 | unsigned char buf[2]; |
365 | int ret; | 387 | int ret; |
366 | 388 | ||
367 | buf[0] = 6; | 389 | buf[0] = 6; |
368 | buf[1] = antenna ? 0x11 : 0x10; | 390 | buf[1] = antenna ? 0x11 : 0x10; |
369 | ret=i2c_master_send(c,buf,2); | 391 | ret=i2c_master_send(c,buf,2); |
370 | tuner_dbg("mt2050: enabled antenna connector %d\n", antenna); | 392 | tuner_dbg("mt2050: enabled antenna connector %d\n", antenna); |
371 | } | 393 | } |
372 | 394 | ||
373 | static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned int if2) | 395 | static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned int if2) |
@@ -456,12 +478,19 @@ static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
456 | static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq) | 478 | static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq) |
457 | { | 479 | { |
458 | struct tuner *t = i2c_get_clientdata(c); | 480 | struct tuner *t = i2c_get_clientdata(c); |
459 | int if2 = t->radio_if2; | 481 | struct microtune_priv *priv = t->priv; |
482 | int if2 = priv->radio_if2; | ||
460 | 483 | ||
461 | mt2050_set_if_freq(c, freq * 1000 / 16, if2); | 484 | mt2050_set_if_freq(c, freq * 1000 / 16, if2); |
462 | mt2050_set_antenna(c, radio_antenna); | 485 | mt2050_set_antenna(c, radio_antenna); |
463 | } | 486 | } |
464 | 487 | ||
488 | static struct tuner_operations mt2050_tuner_ops = { | ||
489 | .set_tv_freq = mt2050_set_tv_freq, | ||
490 | .set_radio_freq = mt2050_set_radio_freq, | ||
491 | .release = microtune_release, | ||
492 | }; | ||
493 | |||
465 | static int mt2050_init(struct i2c_client *c) | 494 | static int mt2050_init(struct i2c_client *c) |
466 | { | 495 | { |
467 | struct tuner *t = i2c_get_clientdata(c); | 496 | struct tuner *t = i2c_get_clientdata(c); |
@@ -481,28 +510,35 @@ static int mt2050_init(struct i2c_client *c) | |||
481 | i2c_master_recv(c,buf,1); | 510 | i2c_master_recv(c,buf,1); |
482 | 511 | ||
483 | tuner_dbg("mt2050: sro is %x\n",buf[0]); | 512 | tuner_dbg("mt2050: sro is %x\n",buf[0]); |
484 | t->set_tv_freq = mt2050_set_tv_freq; | 513 | |
485 | t->set_radio_freq = mt2050_set_radio_freq; | 514 | memcpy(&t->ops, &mt2050_tuner_ops, sizeof(struct tuner_operations)); |
515 | |||
486 | return 0; | 516 | return 0; |
487 | } | 517 | } |
488 | 518 | ||
489 | int microtune_init(struct i2c_client *c) | 519 | int microtune_init(struct i2c_client *c) |
490 | { | 520 | { |
521 | struct microtune_priv *priv = NULL; | ||
491 | struct tuner *t = i2c_get_clientdata(c); | 522 | struct tuner *t = i2c_get_clientdata(c); |
492 | char *name; | 523 | char *name; |
493 | unsigned char buf[21]; | 524 | unsigned char buf[21]; |
494 | int company_code; | 525 | int company_code; |
495 | 526 | ||
527 | priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL); | ||
528 | if (priv == NULL) | ||
529 | return -ENOMEM; | ||
530 | t->priv = priv; | ||
531 | |||
532 | priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ | ||
533 | |||
496 | memset(buf,0,sizeof(buf)); | 534 | memset(buf,0,sizeof(buf)); |
497 | t->set_tv_freq = NULL; | 535 | |
498 | t->set_radio_freq = NULL; | ||
499 | t->standby = NULL; | ||
500 | if (t->std & V4L2_STD_525_60) { | 536 | if (t->std & V4L2_STD_525_60) { |
501 | tuner_dbg("pinnacle ntsc\n"); | 537 | tuner_dbg("pinnacle ntsc\n"); |
502 | t->radio_if2 = 41300 * 1000; | 538 | priv->radio_if2 = 41300 * 1000; |
503 | } else { | 539 | } else { |
504 | tuner_dbg("pinnacle pal\n"); | 540 | tuner_dbg("pinnacle pal\n"); |
505 | t->radio_if2 = 33300 * 1000; | 541 | priv->radio_if2 = 33300 * 1000; |
506 | } | 542 | } |
507 | name = "unknown"; | 543 | name = "unknown"; |
508 | 544 | ||
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index 3ceb8a6249dd..f8f21ddd9843 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c | |||
@@ -617,7 +617,7 @@ static struct ov7670_win_size { | |||
617 | }, | 617 | }, |
618 | }; | 618 | }; |
619 | 619 | ||
620 | #define N_WIN_SIZES (sizeof(ov7670_win_sizes)/sizeof(ov7670_win_sizes[0])) | 620 | #define N_WIN_SIZES (ARRAY_SIZE(ov7670_win_sizes)) |
621 | 621 | ||
622 | 622 | ||
623 | /* | 623 | /* |
@@ -1183,7 +1183,7 @@ static struct ov7670_control { | |||
1183 | .query = ov7670_q_hflip, | 1183 | .query = ov7670_q_hflip, |
1184 | }, | 1184 | }, |
1185 | }; | 1185 | }; |
1186 | #define N_CONTROLS (sizeof(ov7670_controls)/sizeof(ov7670_controls[0])) | 1186 | #define N_CONTROLS (ARRAY_SIZE(ov7670_controls)) |
1187 | 1187 | ||
1188 | static struct ov7670_control *ov7670_find_control(__u32 id) | 1188 | static struct ov7670_control *ov7670_find_control(__u32 id) |
1189 | { | 1189 | { |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 085332a503de..9c0e8d18c2f6 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -1099,7 +1099,7 @@ static int pwc_video_open(struct inode *inode, struct file *file) | |||
1099 | return -EBUSY; | 1099 | return -EBUSY; |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | down(&pdev->modlock); | 1102 | mutex_lock(&pdev->modlock); |
1103 | if (!pdev->usb_init) { | 1103 | if (!pdev->usb_init) { |
1104 | PWC_DEBUG_OPEN("Doing first time initialization.\n"); | 1104 | PWC_DEBUG_OPEN("Doing first time initialization.\n"); |
1105 | pdev->usb_init = 1; | 1105 | pdev->usb_init = 1; |
@@ -1131,7 +1131,7 @@ static int pwc_video_open(struct inode *inode, struct file *file) | |||
1131 | if (i < 0) { | 1131 | if (i < 0) { |
1132 | PWC_DEBUG_OPEN("Failed to allocate buffers memory.\n"); | 1132 | PWC_DEBUG_OPEN("Failed to allocate buffers memory.\n"); |
1133 | pwc_free_buffers(pdev); | 1133 | pwc_free_buffers(pdev); |
1134 | up(&pdev->modlock); | 1134 | mutex_unlock(&pdev->modlock); |
1135 | return i; | 1135 | return i; |
1136 | } | 1136 | } |
1137 | 1137 | ||
@@ -1172,7 +1172,7 @@ static int pwc_video_open(struct inode *inode, struct file *file) | |||
1172 | if (i) { | 1172 | if (i) { |
1173 | PWC_DEBUG_OPEN("Second attempt at set_video_mode failed.\n"); | 1173 | PWC_DEBUG_OPEN("Second attempt at set_video_mode failed.\n"); |
1174 | pwc_free_buffers(pdev); | 1174 | pwc_free_buffers(pdev); |
1175 | up(&pdev->modlock); | 1175 | mutex_unlock(&pdev->modlock); |
1176 | return i; | 1176 | return i; |
1177 | } | 1177 | } |
1178 | 1178 | ||
@@ -1181,7 +1181,7 @@ static int pwc_video_open(struct inode *inode, struct file *file) | |||
1181 | PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i); | 1181 | PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i); |
1182 | pwc_isoc_cleanup(pdev); | 1182 | pwc_isoc_cleanup(pdev); |
1183 | pwc_free_buffers(pdev); | 1183 | pwc_free_buffers(pdev); |
1184 | up(&pdev->modlock); | 1184 | mutex_unlock(&pdev->modlock); |
1185 | return i; | 1185 | return i; |
1186 | } | 1186 | } |
1187 | 1187 | ||
@@ -1191,7 +1191,7 @@ static int pwc_video_open(struct inode *inode, struct file *file) | |||
1191 | 1191 | ||
1192 | pdev->vopen++; | 1192 | pdev->vopen++; |
1193 | file->private_data = vdev; | 1193 | file->private_data = vdev; |
1194 | up(&pdev->modlock); | 1194 | mutex_unlock(&pdev->modlock); |
1195 | PWC_DEBUG_OPEN("<< video_open() returns 0.\n"); | 1195 | PWC_DEBUG_OPEN("<< video_open() returns 0.\n"); |
1196 | return 0; | 1196 | return 0; |
1197 | } | 1197 | } |
@@ -1685,7 +1685,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1685 | pdev->angle_range.tilt_max = 2500; | 1685 | pdev->angle_range.tilt_max = 2500; |
1686 | } | 1686 | } |
1687 | 1687 | ||
1688 | init_MUTEX(&pdev->modlock); | 1688 | mutex_init(&pdev->modlock); |
1689 | spin_lock_init(&pdev->ptrlock); | 1689 | spin_lock_init(&pdev->ptrlock); |
1690 | 1690 | ||
1691 | pdev->udev = udev; | 1691 | pdev->udev = udev; |
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index acbb9312960a..910a04f53920 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/wait.h> | 31 | #include <linux/wait.h> |
32 | #include <linux/smp_lock.h> | 32 | #include <linux/smp_lock.h> |
33 | #include <linux/version.h> | 33 | #include <linux/version.h> |
34 | #include <asm/semaphore.h> | 34 | #include <linux/mutex.h> |
35 | #include <asm/errno.h> | 35 | #include <asm/errno.h> |
36 | #include <linux/videodev.h> | 36 | #include <linux/videodev.h> |
37 | #include <media/v4l2-common.h> | 37 | #include <media/v4l2-common.h> |
@@ -244,7 +244,7 @@ struct pwc_device | |||
244 | int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */ | 244 | int image_read_pos; /* In case we read data in pieces, keep track of were we are in the imagebuffer */ |
245 | int image_used[MAX_IMAGES]; /* For MCAPTURE and SYNC */ | 245 | int image_used[MAX_IMAGES]; /* For MCAPTURE and SYNC */ |
246 | 246 | ||
247 | struct semaphore modlock; /* to prevent races in video_open(), etc */ | 247 | struct mutex modlock; /* to prevent races in video_open(), etc */ |
248 | spinlock_t ptrlock; /* for manipulating the buffer pointers */ | 248 | spinlock_t ptrlock; /* for manipulating the buffer pointers */ |
249 | 249 | ||
250 | /*** motorized pan/tilt feature */ | 250 | /*** motorized pan/tilt feature */ |
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index c1a392e47170..7ae2d646d000 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c | |||
@@ -37,23 +37,23 @@ | |||
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/mm.h> | 38 | #include <linux/mm.h> |
39 | #include <linux/signal.h> | 39 | #include <linux/signal.h> |
40 | #include <linux/types.h> | ||
41 | #include <linux/i2c.h> | ||
40 | #include <asm/io.h> | 42 | #include <asm/io.h> |
41 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
42 | #include <asm/page.h> | 44 | #include <asm/page.h> |
43 | #include <linux/types.h> | 45 | #include <asm/uaccess.h> |
44 | 46 | ||
45 | #include <linux/videodev.h> | 47 | #include <linux/videodev.h> |
46 | #include <asm/uaccess.h> | 48 | #include <linux/video_decoder.h> |
47 | 49 | ||
48 | MODULE_DESCRIPTION("Philips SAA7111 video decoder driver"); | 50 | MODULE_DESCRIPTION("Philips SAA7111 video decoder driver"); |
49 | MODULE_AUTHOR("Dave Perks"); | 51 | MODULE_AUTHOR("Dave Perks"); |
50 | MODULE_LICENSE("GPL"); | 52 | MODULE_LICENSE("GPL"); |
51 | 53 | ||
52 | #include <linux/i2c.h> | ||
53 | 54 | ||
54 | #define I2C_NAME(s) (s)->name | 55 | #define I2C_NAME(s) (s)->name |
55 | 56 | ||
56 | #include <linux/video_decoder.h> | ||
57 | 57 | ||
58 | static int debug = 0; | 58 | static int debug = 0; |
59 | module_param(debug, int, 0644); | 59 | module_param(debug, int, 0644); |
diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index 87c3144ec7fc..677df51de1a9 100644 --- a/drivers/media/video/saa7114.c +++ b/drivers/media/video/saa7114.c | |||
@@ -35,28 +35,26 @@ | |||
35 | #include <linux/fs.h> | 35 | #include <linux/fs.h> |
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <linux/major.h> | 37 | #include <linux/major.h> |
38 | |||
39 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
40 | |||
41 | #include <linux/mm.h> | 39 | #include <linux/mm.h> |
42 | #include <linux/signal.h> | 40 | #include <linux/signal.h> |
41 | #include <linux/types.h> | ||
42 | #include <linux/i2c.h> | ||
43 | #include <asm/io.h> | 43 | #include <asm/io.h> |
44 | #include <asm/pgtable.h> | 44 | #include <asm/pgtable.h> |
45 | #include <asm/page.h> | 45 | #include <asm/page.h> |
46 | #include <linux/types.h> | 46 | #include <asm/uaccess.h> |
47 | 47 | ||
48 | #include <linux/videodev.h> | 48 | #include <linux/videodev.h> |
49 | #include <asm/uaccess.h> | 49 | #include <linux/video_decoder.h> |
50 | 50 | ||
51 | MODULE_DESCRIPTION("Philips SAA7114H video decoder driver"); | 51 | MODULE_DESCRIPTION("Philips SAA7114H video decoder driver"); |
52 | MODULE_AUTHOR("Maxim Yevtyushkin"); | 52 | MODULE_AUTHOR("Maxim Yevtyushkin"); |
53 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
54 | 54 | ||
55 | #include <linux/i2c.h> | ||
56 | 55 | ||
57 | #define I2C_NAME(x) (x)->name | 56 | #define I2C_NAME(x) (x)->name |
58 | 57 | ||
59 | #include <linux/video_decoder.h> | ||
60 | 58 | ||
61 | static int debug = 0; | 59 | static int debug = 0; |
62 | module_param(debug, int, 0); | 60 | module_param(debug, int, 0); |
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index 309dca368f4a..9f1417a4f7d2 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig | |||
@@ -40,7 +40,7 @@ config VIDEO_SAA7134_DVB | |||
40 | depends on VIDEO_SAA7134 && DVB_CORE | 40 | depends on VIDEO_SAA7134 && DVB_CORE |
41 | select VIDEO_BUF_DVB | 41 | select VIDEO_BUF_DVB |
42 | select FW_LOADER | 42 | select FW_LOADER |
43 | select DVB_PLL | 43 | select DVB_PLL if !DVB_FE_CUSTOMISE |
44 | select DVB_MT352 if !DVB_FE_CUSTOMISE | 44 | select DVB_MT352 if !DVB_FE_CUSTOMISE |
45 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE | 45 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE |
46 | select DVB_NXT200X if !DVB_FE_CUSTOMISE | 46 | select DVB_NXT200X if !DVB_FE_CUSTOMISE |
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index ffb0f647a86d..3c0fc9027ad0 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -75,7 +75,8 @@ typedef struct snd_card_saa7134 { | |||
75 | struct saa7134_dev *dev; | 75 | struct saa7134_dev *dev; |
76 | 76 | ||
77 | unsigned long iobase; | 77 | unsigned long iobase; |
78 | int irq; | 78 | s16 irq; |
79 | u16 mute_was_on; | ||
79 | 80 | ||
80 | spinlock_t lock; | 81 | spinlock_t lock; |
81 | } snd_card_saa7134_t; | 82 | } snd_card_saa7134_t; |
@@ -589,8 +590,10 @@ static int snd_card_saa7134_capture_close(struct snd_pcm_substream * substream) | |||
589 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | 590 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); |
590 | struct saa7134_dev *dev = saa7134->dev; | 591 | struct saa7134_dev *dev = saa7134->dev; |
591 | 592 | ||
592 | dev->ctl_mute = 1; | 593 | if (saa7134->mute_was_on) { |
593 | saa7134_tvaudio_setmute(dev); | 594 | dev->ctl_mute = 1; |
595 | saa7134_tvaudio_setmute(dev); | ||
596 | } | ||
594 | return 0; | 597 | return 0; |
595 | } | 598 | } |
596 | 599 | ||
@@ -637,8 +640,11 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream) | |||
637 | runtime->private_free = snd_card_saa7134_runtime_free; | 640 | runtime->private_free = snd_card_saa7134_runtime_free; |
638 | runtime->hw = snd_card_saa7134_capture; | 641 | runtime->hw = snd_card_saa7134_capture; |
639 | 642 | ||
640 | dev->ctl_mute = 0; | 643 | if (dev->ctl_mute != 0) { |
641 | saa7134_tvaudio_setmute(dev); | 644 | saa7134->mute_was_on = 1; |
645 | dev->ctl_mute = 0; | ||
646 | saa7134_tvaudio_setmute(dev); | ||
647 | } | ||
642 | 648 | ||
643 | if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) | 649 | if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) |
644 | return err; | 650 | return err; |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 50f15adfa7c8..8ec83bd70094 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -400,7 +400,7 @@ struct saa7134_board saa7134_boards[] = { | |||
400 | .inputs = {{ | 400 | .inputs = {{ |
401 | .name = name_tv, | 401 | .name = name_tv, |
402 | .vmux = 1, | 402 | .vmux = 1, |
403 | .amux = LINE2, | 403 | .amux = TV, |
404 | .tv = 1, | 404 | .tv = 1, |
405 | .gpio = 0x20000, | 405 | .gpio = 0x20000, |
406 | },{ | 406 | },{ |
@@ -3502,6 +3502,38 @@ struct saa7134_board saa7134_boards[] = { | |||
3502 | .amux = TV, | 3502 | .amux = TV, |
3503 | }, | 3503 | }, |
3504 | }, | 3504 | }, |
3505 | [SAA7134_BOARD_10MOONSTVMASTER3] = { | ||
3506 | /* Tony Wan <aloha_cn@hotmail.com> */ | ||
3507 | .name = "10MOONS TM300 TV Card", | ||
3508 | .audio_clock = 0x00200000, | ||
3509 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
3510 | .radio_type = UNSET, | ||
3511 | .tuner_addr = ADDR_UNSET, | ||
3512 | .radio_addr = ADDR_UNSET, | ||
3513 | .gpiomask = 0x7000, | ||
3514 | .inputs = {{ | ||
3515 | .name = name_tv, | ||
3516 | .vmux = 1, | ||
3517 | .amux = LINE2, | ||
3518 | .gpio = 0x0000, | ||
3519 | .tv = 1, | ||
3520 | },{ | ||
3521 | .name = name_comp1, | ||
3522 | .vmux = 3, | ||
3523 | .amux = LINE1, | ||
3524 | .gpio = 0x2000, | ||
3525 | },{ | ||
3526 | .name = name_svideo, | ||
3527 | .vmux = 8, | ||
3528 | .amux = LINE1, | ||
3529 | .gpio = 0x2000, | ||
3530 | }}, | ||
3531 | .mute = { | ||
3532 | .name = name_mute, | ||
3533 | .amux = LINE2, | ||
3534 | .gpio = 0x3000, | ||
3535 | }, | ||
3536 | }, | ||
3505 | }; | 3537 | }; |
3506 | 3538 | ||
3507 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); | 3539 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); |
@@ -4219,6 +4251,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
4219 | .subdevice = 0x2003, /* OEM cardbus */ | 4251 | .subdevice = 0x2003, /* OEM cardbus */ |
4220 | .driver_data = SAA7134_BOARD_SABRENT_TV_PCB05, | 4252 | .driver_data = SAA7134_BOARD_SABRENT_TV_PCB05, |
4221 | },{ | 4253 | },{ |
4254 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
4255 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | ||
4256 | .subvendor = PCI_VENDOR_ID_PHILIPS, | ||
4257 | .subdevice = 0x2304, | ||
4258 | .driver_data = SAA7134_BOARD_10MOONSTVMASTER3, | ||
4259 | },{ | ||
4222 | /* --- boards without eeprom + subsystem ID --- */ | 4260 | /* --- boards without eeprom + subsystem ID --- */ |
4223 | .vendor = PCI_VENDOR_ID_PHILIPS, | 4261 | .vendor = PCI_VENDOR_ID_PHILIPS, |
4224 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 4262 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
@@ -4330,6 +4368,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
4330 | case SAA7134_BOARD_AVERMEDIA_A16AR: | 4368 | case SAA7134_BOARD_AVERMEDIA_A16AR: |
4331 | case SAA7134_BOARD_ENCORE_ENLTV: | 4369 | case SAA7134_BOARD_ENCORE_ENLTV: |
4332 | case SAA7134_BOARD_ENCORE_ENLTV_FM: | 4370 | case SAA7134_BOARD_ENCORE_ENLTV_FM: |
4371 | case SAA7134_BOARD_10MOONSTVMASTER3: | ||
4333 | dev->has_remote = SAA7134_REMOTE_GPIO; | 4372 | dev->has_remote = SAA7134_REMOTE_GPIO; |
4334 | break; | 4373 | break; |
4335 | case SAA7134_BOARD_FLYDVBS_LR300: | 4374 | case SAA7134_BOARD_FLYDVBS_LR300: |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index e0eec80088c7..1f6bd3300715 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -175,18 +175,6 @@ static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe, | |||
175 | return mt352_pinnacle_init(fe); | 175 | return mt352_pinnacle_init(fe); |
176 | } | 176 | } |
177 | 177 | ||
178 | static int mt352_aver777_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) | ||
179 | { | ||
180 | if (buf_len < 5) | ||
181 | return -EINVAL; | ||
182 | |||
183 | pllbuf[0] = 0x61; | ||
184 | dvb_pll_configure(&dvb_pll_philips_td1316, pllbuf+1, | ||
185 | params->frequency, | ||
186 | params->u.ofdm.bandwidth); | ||
187 | return 5; | ||
188 | } | ||
189 | |||
190 | static struct mt352_config pinnacle_300i = { | 178 | static struct mt352_config pinnacle_300i = { |
191 | .demod_address = 0x3c >> 1, | 179 | .demod_address = 0x3c >> 1, |
192 | .adc_clock = 20333, | 180 | .adc_clock = 20333, |
@@ -444,135 +432,6 @@ static struct tda1004x_config philips_europa_config = { | |||
444 | 432 | ||
445 | /* ------------------------------------------------------------------ */ | 433 | /* ------------------------------------------------------------------ */ |
446 | 434 | ||
447 | static int philips_fmd1216_tuner_init(struct dvb_frontend *fe) | ||
448 | { | ||
449 | struct saa7134_dev *dev = fe->dvb->priv; | ||
450 | struct tda1004x_state *state = fe->demodulator_priv; | ||
451 | u8 addr = state->config->tuner_address; | ||
452 | /* this message is to set up ATC and ALC */ | ||
453 | static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; | ||
454 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; | ||
455 | |||
456 | if (fe->ops.i2c_gate_ctrl) | ||
457 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
458 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) | ||
459 | return -EIO; | ||
460 | msleep(1); | ||
461 | |||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | static int philips_fmd1216_tuner_sleep(struct dvb_frontend *fe) | ||
466 | { | ||
467 | struct saa7134_dev *dev = fe->dvb->priv; | ||
468 | struct tda1004x_state *state = fe->demodulator_priv; | ||
469 | u8 addr = state->config->tuner_address; | ||
470 | /* this message actually turns the tuner back to analog mode */ | ||
471 | u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 }; | ||
472 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) }; | ||
473 | |||
474 | if (fe->ops.i2c_gate_ctrl) | ||
475 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
476 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | ||
477 | msleep(1); | ||
478 | fmd1216_init[2] = 0x86; | ||
479 | fmd1216_init[3] = 0x54; | ||
480 | if (fe->ops.i2c_gate_ctrl) | ||
481 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
482 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | ||
483 | msleep(1); | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static int philips_fmd1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
488 | { | ||
489 | struct saa7134_dev *dev = fe->dvb->priv; | ||
490 | struct tda1004x_state *state = fe->demodulator_priv; | ||
491 | u8 addr = state->config->tuner_address; | ||
492 | u8 tuner_buf[4]; | ||
493 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len = | ||
494 | sizeof(tuner_buf) }; | ||
495 | int tuner_frequency = 0; | ||
496 | int divider = 0; | ||
497 | u8 band, mode, cp; | ||
498 | |||
499 | /* determine charge pump */ | ||
500 | tuner_frequency = params->frequency + 36130000; | ||
501 | if (tuner_frequency < 87000000) | ||
502 | return -EINVAL; | ||
503 | /* low band */ | ||
504 | else if (tuner_frequency < 180000000) { | ||
505 | band = 1; | ||
506 | mode = 7; | ||
507 | cp = 0; | ||
508 | } else if (tuner_frequency < 195000000) { | ||
509 | band = 1; | ||
510 | mode = 6; | ||
511 | cp = 1; | ||
512 | /* mid band */ | ||
513 | } else if (tuner_frequency < 366000000) { | ||
514 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) { | ||
515 | band = 10; | ||
516 | } else { | ||
517 | band = 2; | ||
518 | } | ||
519 | mode = 7; | ||
520 | cp = 0; | ||
521 | } else if (tuner_frequency < 478000000) { | ||
522 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) { | ||
523 | band = 10; | ||
524 | } else { | ||
525 | band = 2; | ||
526 | } | ||
527 | mode = 6; | ||
528 | cp = 1; | ||
529 | /* high band */ | ||
530 | } else if (tuner_frequency < 662000000) { | ||
531 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) { | ||
532 | band = 12; | ||
533 | } else { | ||
534 | band = 4; | ||
535 | } | ||
536 | mode = 7; | ||
537 | cp = 0; | ||
538 | } else if (tuner_frequency < 840000000) { | ||
539 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) { | ||
540 | band = 12; | ||
541 | } else { | ||
542 | band = 4; | ||
543 | } | ||
544 | mode = 6; | ||
545 | cp = 1; | ||
546 | } else { | ||
547 | if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) { | ||
548 | band = 12; | ||
549 | } else { | ||
550 | band = 4; | ||
551 | } | ||
552 | mode = 7; | ||
553 | cp = 1; | ||
554 | |||
555 | } | ||
556 | /* calculate divisor */ | ||
557 | /* ((36166000 + Finput) / 166666) rounded! */ | ||
558 | divider = (tuner_frequency + 83333) / 166667; | ||
559 | |||
560 | /* setup tuner buffer */ | ||
561 | tuner_buf[0] = (divider >> 8) & 0x7f; | ||
562 | tuner_buf[1] = divider & 0xff; | ||
563 | tuner_buf[2] = 0x80 | (cp << 6) | (mode << 3) | 4; | ||
564 | tuner_buf[3] = 0x40 | band; | ||
565 | |||
566 | if (fe->ops.i2c_gate_ctrl) | ||
567 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
568 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) { | ||
569 | wprintk("could not write to tuner at addr: 0x%02x\n", | ||
570 | addr << 1); | ||
571 | return -EIO; | ||
572 | } | ||
573 | return 0; | ||
574 | } | ||
575 | |||
576 | static struct tda1004x_config medion_cardbus = { | 435 | static struct tda1004x_config medion_cardbus = { |
577 | .demod_address = 0x08, | 436 | .demod_address = 0x08, |
578 | .invert = 1, | 437 | .invert = 1, |
@@ -958,18 +817,8 @@ static struct nxt200x_config avertvhda180 = { | |||
958 | .demod_address = 0x0a, | 817 | .demod_address = 0x0a, |
959 | }; | 818 | }; |
960 | 819 | ||
961 | static int nxt200x_set_pll_input(u8 *buf, int input) | ||
962 | { | ||
963 | if (input) | ||
964 | buf[3] |= 0x08; | ||
965 | else | ||
966 | buf[3] &= ~0x08; | ||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | static struct nxt200x_config kworldatsc110 = { | 820 | static struct nxt200x_config kworldatsc110 = { |
971 | .demod_address = 0x0a, | 821 | .demod_address = 0x0a, |
972 | .set_pll_input = nxt200x_set_pll_input, | ||
973 | }; | 822 | }; |
974 | 823 | ||
975 | /* ================================================================== | 824 | /* ================================================================== |
@@ -1005,7 +854,8 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1005 | dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, | 854 | dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777, |
1006 | &dev->i2c_adap); | 855 | &dev->i2c_adap); |
1007 | if (dev->dvb.frontend) { | 856 | if (dev->dvb.frontend) { |
1008 | dev->dvb.frontend->ops.tuner_ops.calc_regs = mt352_aver777_tuner_calc_regs; | 857 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
858 | NULL, DVB_PLL_PHILIPS_TD1316); | ||
1009 | } | 859 | } |
1010 | break; | 860 | break; |
1011 | case SAA7134_BOARD_MD7134: | 861 | case SAA7134_BOARD_MD7134: |
@@ -1013,9 +863,8 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1013 | &medion_cardbus, | 863 | &medion_cardbus, |
1014 | &dev->i2c_adap); | 864 | &dev->i2c_adap); |
1015 | if (dev->dvb.frontend) { | 865 | if (dev->dvb.frontend) { |
1016 | dev->dvb.frontend->ops.tuner_ops.init = philips_fmd1216_tuner_init; | 866 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, medion_cardbus.tuner_address, |
1017 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_fmd1216_tuner_sleep; | 867 | &dev->i2c_adap, DVB_PLL_FMD1216ME); |
1018 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_fmd1216_tuner_set_params; | ||
1019 | } | 868 | } |
1020 | break; | 869 | break; |
1021 | case SAA7134_BOARD_PHILIPS_TOUGH: | 870 | case SAA7134_BOARD_PHILIPS_TOUGH: |
@@ -1113,7 +962,7 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1113 | &dev->i2c_adap); | 962 | &dev->i2c_adap); |
1114 | if (dev->dvb.frontend) { | 963 | if (dev->dvb.frontend) { |
1115 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 964 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
1116 | NULL, &dvb_pll_tdhu2); | 965 | NULL, DVB_PLL_TDHU2); |
1117 | } | 966 | } |
1118 | break; | 967 | break; |
1119 | case SAA7134_BOARD_KWORLD_ATSC110: | 968 | case SAA7134_BOARD_KWORLD_ATSC110: |
@@ -1121,7 +970,7 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1121 | &dev->i2c_adap); | 970 | &dev->i2c_adap); |
1122 | if (dev->dvb.frontend) { | 971 | if (dev->dvb.frontend) { |
1123 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 972 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
1124 | NULL, &dvb_pll_tuv1236d); | 973 | NULL, DVB_PLL_TUV1236D); |
1125 | } | 974 | } |
1126 | break; | 975 | break; |
1127 | case SAA7134_BOARD_FLYDVBS_LR300: | 976 | case SAA7134_BOARD_FLYDVBS_LR300: |
@@ -1144,9 +993,9 @@ static int dvb_init(struct saa7134_dev *dev) | |||
1144 | if (dev->dvb.frontend) { | 993 | if (dev->dvb.frontend) { |
1145 | dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; | 994 | dev->original_demod_sleep = dev->dvb.frontend->ops.sleep; |
1146 | dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; | 995 | dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep; |
1147 | dev->dvb.frontend->ops.tuner_ops.init = philips_fmd1216_tuner_init; | 996 | |
1148 | dev->dvb.frontend->ops.tuner_ops.sleep = philips_fmd1216_tuner_sleep; | 997 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, medion_cardbus.tuner_address, |
1149 | dev->dvb.frontend->ops.tuner_ops.set_params = philips_fmd1216_tuner_set_params; | 998 | &dev->i2c_adap, DVB_PLL_FMD1216ME); |
1150 | } | 999 | } |
1151 | break; | 1000 | break; |
1152 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: | 1001 | case SAA7134_BOARD_VIDEOMATE_DVBT_200A: |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index f521603482ca..fc260ec8fdc2 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -96,6 +96,10 @@ static int ts_open(struct inode *inode, struct file *file) | |||
96 | if (dev->empress_users) | 96 | if (dev->empress_users) |
97 | goto done_up; | 97 | goto done_up; |
98 | 98 | ||
99 | /* Unmute audio */ | ||
100 | saa_writeb(SAA7134_AUDIO_MUTE_CTRL, | ||
101 | saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); | ||
102 | |||
99 | dev->empress_users++; | 103 | dev->empress_users++; |
100 | file->private_data = dev; | 104 | file->private_data = dev; |
101 | err = 0; | 105 | err = 0; |
@@ -121,6 +125,10 @@ static int ts_release(struct inode *inode, struct file *file) | |||
121 | /* stop the encoder */ | 125 | /* stop the encoder */ |
122 | ts_reset_encoder(dev); | 126 | ts_reset_encoder(dev); |
123 | 127 | ||
128 | /* Mute audio */ | ||
129 | saa_writeb(SAA7134_AUDIO_MUTE_CTRL, | ||
130 | saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); | ||
131 | |||
124 | mutex_unlock(&dev->empress_tsq.lock); | 132 | mutex_unlock(&dev->empress_tsq.lock); |
125 | return 0; | 133 | return 0; |
126 | } | 134 | } |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index c0de37e3f5c6..1b6dfd801cc1 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -153,21 +153,18 @@ void saa7134_input_irq(struct saa7134_dev *dev) | |||
153 | 153 | ||
154 | static void saa7134_input_timer(unsigned long data) | 154 | static void saa7134_input_timer(unsigned long data) |
155 | { | 155 | { |
156 | struct saa7134_dev *dev = (struct saa7134_dev*)data; | 156 | struct saa7134_dev *dev = (struct saa7134_dev *)data; |
157 | struct card_ir *ir = dev->remote; | 157 | struct card_ir *ir = dev->remote; |
158 | unsigned long timeout; | ||
159 | 158 | ||
160 | build_key(dev); | 159 | build_key(dev); |
161 | timeout = jiffies + (ir->polling * HZ / 1000); | 160 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); |
162 | mod_timer(&ir->timer, timeout); | ||
163 | } | 161 | } |
164 | 162 | ||
165 | static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) | 163 | static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir) |
166 | { | 164 | { |
167 | if (ir->polling) { | 165 | if (ir->polling) { |
168 | init_timer(&ir->timer); | 166 | setup_timer(&ir->timer, saa7134_input_timer, |
169 | ir->timer.function = saa7134_input_timer; | 167 | (unsigned long)dev); |
170 | ir->timer.data = (unsigned long)dev; | ||
171 | ir->timer.expires = jiffies + HZ; | 168 | ir->timer.expires = jiffies + HZ; |
172 | add_timer(&ir->timer); | 169 | add_timer(&ir->timer); |
173 | } else if (ir->rc5_gpio) { | 170 | } else if (ir->rc5_gpio) { |
@@ -314,6 +311,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
314 | mask_keycode = 0x003F00; | 311 | mask_keycode = 0x003F00; |
315 | mask_keyup = 0x040000; | 312 | mask_keyup = 0x040000; |
316 | break; | 313 | break; |
314 | case SAA7134_BOARD_FLYDVBS_LR300: | ||
317 | case SAA7134_BOARD_FLYDVBT_LR301: | 315 | case SAA7134_BOARD_FLYDVBT_LR301: |
318 | case SAA7134_BOARD_FLYDVBTDUO: | 316 | case SAA7134_BOARD_FLYDVBTDUO: |
319 | ir_codes = ir_codes_flydvb; | 317 | ir_codes = ir_codes_flydvb; |
@@ -333,6 +331,12 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
333 | mask_keyup = 0x040000; | 331 | mask_keyup = 0x040000; |
334 | polling = 50; // ms | 332 | polling = 50; // ms |
335 | break; | 333 | break; |
334 | case SAA7134_BOARD_10MOONSTVMASTER3: | ||
335 | ir_codes = ir_codes_encore_enltv; | ||
336 | mask_keycode = 0x5f80000; | ||
337 | mask_keyup = 0x8000000; | ||
338 | polling = 50; //ms | ||
339 | break; | ||
336 | } | 340 | } |
337 | if (NULL == ir_codes) { | 341 | if (NULL == ir_codes) { |
338 | printk("%s: Oops: IR config error [card=%d]\n", | 342 | printk("%s: Oops: IR config error [card=%d]\n", |
@@ -374,7 +378,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
374 | input_dev->id.vendor = dev->pci->vendor; | 378 | input_dev->id.vendor = dev->pci->vendor; |
375 | input_dev->id.product = dev->pci->device; | 379 | input_dev->id.product = dev->pci->device; |
376 | } | 380 | } |
377 | input_dev->cdev.dev = &dev->pci->dev; | 381 | input_dev->dev.parent = &dev->pci->dev; |
378 | 382 | ||
379 | dev->remote = ir; | 383 | dev->remote = ir; |
380 | saa7134_ir_start(dev, ir); | 384 | saa7134_ir_start(dev, ir); |
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index 30395d6b5f14..18b4817b4aac 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/kthread.h> | ||
28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
30 | #include <asm/div64.h> | 31 | #include <asm/div64.h> |
@@ -341,10 +342,8 @@ static void tvaudio_setmode(struct saa7134_dev *dev, | |||
341 | 342 | ||
342 | static int tvaudio_sleep(struct saa7134_dev *dev, int timeout) | 343 | static int tvaudio_sleep(struct saa7134_dev *dev, int timeout) |
343 | { | 344 | { |
344 | DECLARE_WAITQUEUE(wait, current); | 345 | if (dev->thread.scan1 == dev->thread.scan2 && |
345 | 346 | !kthread_should_stop()) { | |
346 | add_wait_queue(&dev->thread.wq, &wait); | ||
347 | if (dev->thread.scan1 == dev->thread.scan2 && !dev->thread.shutdown) { | ||
348 | if (timeout < 0) { | 347 | if (timeout < 0) { |
349 | set_current_state(TASK_INTERRUPTIBLE); | 348 | set_current_state(TASK_INTERRUPTIBLE); |
350 | schedule(); | 349 | schedule(); |
@@ -353,7 +352,6 @@ static int tvaudio_sleep(struct saa7134_dev *dev, int timeout) | |||
353 | (msecs_to_jiffies(timeout)); | 352 | (msecs_to_jiffies(timeout)); |
354 | } | 353 | } |
355 | } | 354 | } |
356 | remove_wait_queue(&dev->thread.wq, &wait); | ||
357 | return dev->thread.scan1 != dev->thread.scan2; | 355 | return dev->thread.scan1 != dev->thread.scan2; |
358 | } | 356 | } |
359 | 357 | ||
@@ -505,11 +503,10 @@ static int tvaudio_thread(void *data) | |||
505 | unsigned int i, audio, nscan; | 503 | unsigned int i, audio, nscan; |
506 | int max1,max2,carrier,rx,mode,lastmode,default_carrier; | 504 | int max1,max2,carrier,rx,mode,lastmode,default_carrier; |
507 | 505 | ||
508 | daemonize("%s", dev->name); | ||
509 | allow_signal(SIGTERM); | 506 | allow_signal(SIGTERM); |
510 | for (;;) { | 507 | for (;;) { |
511 | tvaudio_sleep(dev,-1); | 508 | tvaudio_sleep(dev,-1); |
512 | if (dev->thread.shutdown || signal_pending(current)) | 509 | if (kthread_should_stop() || signal_pending(current)) |
513 | goto done; | 510 | goto done; |
514 | 511 | ||
515 | restart: | 512 | restart: |
@@ -618,7 +615,7 @@ static int tvaudio_thread(void *data) | |||
618 | for (;;) { | 615 | for (;;) { |
619 | if (tvaudio_sleep(dev,5000)) | 616 | if (tvaudio_sleep(dev,5000)) |
620 | goto restart; | 617 | goto restart; |
621 | if (dev->thread.shutdown || signal_pending(current)) | 618 | if (kthread_should_stop() || signal_pending(current)) |
622 | break; | 619 | break; |
623 | if (UNSET == dev->thread.mode) { | 620 | if (UNSET == dev->thread.mode) { |
624 | rx = tvaudio_getstereo(dev,&tvaudio[i]); | 621 | rx = tvaudio_getstereo(dev,&tvaudio[i]); |
@@ -634,7 +631,6 @@ static int tvaudio_thread(void *data) | |||
634 | } | 631 | } |
635 | 632 | ||
636 | done: | 633 | done: |
637 | complete_and_exit(&dev->thread.exit, 0); | ||
638 | return 0; | 634 | return 0; |
639 | } | 635 | } |
640 | 636 | ||
@@ -782,7 +778,6 @@ static int tvaudio_thread_ddep(void *data) | |||
782 | struct saa7134_dev *dev = data; | 778 | struct saa7134_dev *dev = data; |
783 | u32 value, norms, clock; | 779 | u32 value, norms, clock; |
784 | 780 | ||
785 | daemonize("%s", dev->name); | ||
786 | allow_signal(SIGTERM); | 781 | allow_signal(SIGTERM); |
787 | 782 | ||
788 | clock = saa7134_boards[dev->board].audio_clock; | 783 | clock = saa7134_boards[dev->board].audio_clock; |
@@ -796,7 +791,7 @@ static int tvaudio_thread_ddep(void *data) | |||
796 | 791 | ||
797 | for (;;) { | 792 | for (;;) { |
798 | tvaudio_sleep(dev,-1); | 793 | tvaudio_sleep(dev,-1); |
799 | if (dev->thread.shutdown || signal_pending(current)) | 794 | if (kthread_should_stop() || signal_pending(current)) |
800 | goto done; | 795 | goto done; |
801 | 796 | ||
802 | restart: | 797 | restart: |
@@ -876,7 +871,6 @@ static int tvaudio_thread_ddep(void *data) | |||
876 | } | 871 | } |
877 | 872 | ||
878 | done: | 873 | done: |
879 | complete_and_exit(&dev->thread.exit, 0); | ||
880 | return 0; | 874 | return 0; |
881 | } | 875 | } |
882 | 876 | ||
@@ -973,7 +967,6 @@ int saa7134_tvaudio_getstereo(struct saa7134_dev *dev) | |||
973 | 967 | ||
974 | int saa7134_tvaudio_init2(struct saa7134_dev *dev) | 968 | int saa7134_tvaudio_init2(struct saa7134_dev *dev) |
975 | { | 969 | { |
976 | DECLARE_MUTEX_LOCKED(sem); | ||
977 | int (*my_thread)(void *data) = NULL; | 970 | int (*my_thread)(void *data) = NULL; |
978 | 971 | ||
979 | switch (dev->pci->device) { | 972 | switch (dev->pci->device) { |
@@ -986,15 +979,15 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev) | |||
986 | break; | 979 | break; |
987 | } | 980 | } |
988 | 981 | ||
989 | dev->thread.pid = -1; | 982 | dev->thread.thread = NULL; |
990 | if (my_thread) { | 983 | if (my_thread) { |
991 | /* start tvaudio thread */ | 984 | /* start tvaudio thread */ |
992 | init_waitqueue_head(&dev->thread.wq); | 985 | dev->thread.thread = kthread_run(my_thread, dev, "%s", dev->name); |
993 | init_completion(&dev->thread.exit); | 986 | if (IS_ERR(dev->thread.thread)) { |
994 | dev->thread.pid = kernel_thread(my_thread,dev,0); | ||
995 | if (dev->thread.pid < 0) | ||
996 | printk(KERN_WARNING "%s: kernel_thread() failed\n", | 987 | printk(KERN_WARNING "%s: kernel_thread() failed\n", |
997 | dev->name); | 988 | dev->name); |
989 | /* XXX: missing error handling here */ | ||
990 | } | ||
998 | saa7134_tvaudio_do_scan(dev); | 991 | saa7134_tvaudio_do_scan(dev); |
999 | } | 992 | } |
1000 | 993 | ||
@@ -1005,11 +998,9 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev) | |||
1005 | int saa7134_tvaudio_fini(struct saa7134_dev *dev) | 998 | int saa7134_tvaudio_fini(struct saa7134_dev *dev) |
1006 | { | 999 | { |
1007 | /* shutdown tvaudio thread */ | 1000 | /* shutdown tvaudio thread */ |
1008 | if (dev->thread.pid > 0) { | 1001 | if (dev->thread.thread) |
1009 | dev->thread.shutdown = 1; | 1002 | kthread_stop(dev->thread.thread); |
1010 | wake_up_interruptible(&dev->thread.wq); | 1003 | |
1011 | wait_for_completion(&dev->thread.exit); | ||
1012 | } | ||
1013 | saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */ | 1004 | saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */ |
1014 | return 0; | 1005 | return 0; |
1015 | } | 1006 | } |
@@ -1020,10 +1011,10 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev) | |||
1020 | dprintk("sound IF not in use, skipping scan\n"); | 1011 | dprintk("sound IF not in use, skipping scan\n"); |
1021 | dev->automute = 0; | 1012 | dev->automute = 0; |
1022 | saa7134_tvaudio_setmute(dev); | 1013 | saa7134_tvaudio_setmute(dev); |
1023 | } else if (dev->thread.pid >= 0) { | 1014 | } else if (dev->thread.thread) { |
1024 | dev->thread.mode = UNSET; | 1015 | dev->thread.mode = UNSET; |
1025 | dev->thread.scan2++; | 1016 | dev->thread.scan2++; |
1026 | wake_up_interruptible(&dev->thread.wq); | 1017 | wake_up_process(dev->thread.thread); |
1027 | } else { | 1018 | } else { |
1028 | dev->automute = 0; | 1019 | dev->automute = 0; |
1029 | saa7134_tvaudio_setmute(dev); | 1020 | saa7134_tvaudio_setmute(dev); |
@@ -1040,4 +1031,3 @@ EXPORT_SYMBOL(saa7134_tvaudio_setmute); | |||
1040 | * c-basic-offset: 8 | 1031 | * c-basic-offset: 8 |
1041 | * End: | 1032 | * End: |
1042 | */ | 1033 | */ |
1043 | |||
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 15623b27ad2e..d32a856192d7 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -238,6 +238,7 @@ struct saa7134_format { | |||
238 | #define SAA7134_BOARD_ECS_TVP3XP_4CB6 113 | 238 | #define SAA7134_BOARD_ECS_TVP3XP_4CB6 113 |
239 | #define SAA7134_BOARD_KWORLD_DVBT_210 114 | 239 | #define SAA7134_BOARD_KWORLD_DVBT_210 114 |
240 | #define SAA7134_BOARD_SABRENT_TV_PCB05 115 | 240 | #define SAA7134_BOARD_SABRENT_TV_PCB05 115 |
241 | #define SAA7134_BOARD_10MOONSTVMASTER3 116 | ||
241 | 242 | ||
242 | #define SAA7134_MAXBOARDS 8 | 243 | #define SAA7134_MAXBOARDS 8 |
243 | #define SAA7134_INPUT_MAX 8 | 244 | #define SAA7134_INPUT_MAX 8 |
@@ -327,10 +328,7 @@ struct saa7134_pgtable { | |||
327 | 328 | ||
328 | /* tvaudio thread status */ | 329 | /* tvaudio thread status */ |
329 | struct saa7134_thread { | 330 | struct saa7134_thread { |
330 | pid_t pid; | 331 | struct task_struct *thread; |
331 | struct completion exit; | ||
332 | wait_queue_head_t wq; | ||
333 | unsigned int shutdown; | ||
334 | unsigned int scan1; | 332 | unsigned int scan1; |
335 | unsigned int scan2; | 333 | unsigned int scan2; |
336 | unsigned int mode; | 334 | unsigned int mode; |
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 339592e7722d..66cc92c0ea66 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c | |||
@@ -34,23 +34,23 @@ | |||
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/mm.h> | 35 | #include <linux/mm.h> |
36 | #include <linux/signal.h> | 36 | #include <linux/signal.h> |
37 | #include <linux/types.h> | ||
38 | #include <linux/i2c.h> | ||
37 | #include <asm/io.h> | 39 | #include <asm/io.h> |
38 | #include <asm/pgtable.h> | 40 | #include <asm/pgtable.h> |
39 | #include <asm/page.h> | 41 | #include <asm/page.h> |
40 | #include <linux/types.h> | 42 | #include <asm/uaccess.h> |
41 | 43 | ||
42 | #include <linux/videodev.h> | 44 | #include <linux/videodev.h> |
43 | #include <asm/uaccess.h> | 45 | #include <linux/video_encoder.h> |
44 | 46 | ||
45 | MODULE_DESCRIPTION("Philips SAA7185 video encoder driver"); | 47 | MODULE_DESCRIPTION("Philips SAA7185 video encoder driver"); |
46 | MODULE_AUTHOR("Dave Perks"); | 48 | MODULE_AUTHOR("Dave Perks"); |
47 | MODULE_LICENSE("GPL"); | 49 | MODULE_LICENSE("GPL"); |
48 | 50 | ||
49 | #include <linux/i2c.h> | ||
50 | 51 | ||
51 | #define I2C_NAME(s) (s)->name | 52 | #define I2C_NAME(s) (s)->name |
52 | 53 | ||
53 | #include <linux/video_encoder.h> | ||
54 | 54 | ||
55 | static int debug = 0; | 55 | static int debug = 0; |
56 | module_param(debug, int, 0); | 56 | module_param(debug, int, 0); |
diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/media/video/sn9c102/sn9c102.h index 11fcb49f5b99..2e3c3de793a7 100644 --- a/drivers/media/video/sn9c102/sn9c102.h +++ b/drivers/media/video/sn9c102/sn9c102.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/string.h> | 37 | #include <linux/string.h> |
38 | #include <linux/stddef.h> | 38 | #include <linux/stddef.h> |
39 | #include <linux/kref.h> | ||
39 | 40 | ||
40 | #include "sn9c102_config.h" | 41 | #include "sn9c102_config.h" |
41 | #include "sn9c102_sensor.h" | 42 | #include "sn9c102_sensor.h" |
@@ -94,7 +95,7 @@ struct sn9c102_module_param { | |||
94 | }; | 95 | }; |
95 | 96 | ||
96 | static DEFINE_MUTEX(sn9c102_sysfs_lock); | 97 | static DEFINE_MUTEX(sn9c102_sysfs_lock); |
97 | static DECLARE_RWSEM(sn9c102_disconnect); | 98 | static DECLARE_RWSEM(sn9c102_dev_lock); |
98 | 99 | ||
99 | struct sn9c102_device { | 100 | struct sn9c102_device { |
100 | struct video_device* v4ldev; | 101 | struct video_device* v4ldev; |
@@ -122,12 +123,14 @@ struct sn9c102_device { | |||
122 | 123 | ||
123 | struct sn9c102_module_param module_param; | 124 | struct sn9c102_module_param module_param; |
124 | 125 | ||
126 | struct kref kref; | ||
125 | enum sn9c102_dev_state state; | 127 | enum sn9c102_dev_state state; |
126 | u8 users; | 128 | u8 users; |
127 | 129 | ||
128 | struct mutex dev_mutex, fileop_mutex; | 130 | struct completion probe; |
131 | struct mutex open_mutex, fileop_mutex; | ||
129 | spinlock_t queue_lock; | 132 | spinlock_t queue_lock; |
130 | wait_queue_head_t open, wait_frame, wait_stream; | 133 | wait_queue_head_t wait_open, wait_frame, wait_stream; |
131 | }; | 134 | }; |
132 | 135 | ||
133 | /*****************************************************************************/ | 136 | /*****************************************************************************/ |
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 74a204f8ebc8..36d8a455e0ec 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
@@ -48,8 +48,8 @@ | |||
48 | #define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia" | 48 | #define SN9C102_MODULE_AUTHOR "(C) 2004-2007 Luca Risolia" |
49 | #define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" | 49 | #define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" |
50 | #define SN9C102_MODULE_LICENSE "GPL" | 50 | #define SN9C102_MODULE_LICENSE "GPL" |
51 | #define SN9C102_MODULE_VERSION "1:1.44" | 51 | #define SN9C102_MODULE_VERSION "1:1.47" |
52 | #define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 44) | 52 | #define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 47) |
53 | 53 | ||
54 | /*****************************************************************************/ | 54 | /*****************************************************************************/ |
55 | 55 | ||
@@ -64,9 +64,10 @@ MODULE_LICENSE(SN9C102_MODULE_LICENSE); | |||
64 | static short video_nr[] = {[0 ... SN9C102_MAX_DEVICES-1] = -1}; | 64 | static short video_nr[] = {[0 ... SN9C102_MAX_DEVICES-1] = -1}; |
65 | module_param_array(video_nr, short, NULL, 0444); | 65 | module_param_array(video_nr, short, NULL, 0444); |
66 | MODULE_PARM_DESC(video_nr, | 66 | MODULE_PARM_DESC(video_nr, |
67 | "\n<-1|n[,...]> Specify V4L2 minor mode number." | 67 | " <-1|n[,...]>" |
68 | "\n -1 = use next available (default)" | 68 | "\nSpecify V4L2 minor mode number." |
69 | "\n n = use minor number n (integer >= 0)" | 69 | "\n-1 = use next available (default)" |
70 | "\n n = use minor number n (integer >= 0)" | ||
70 | "\nYou can specify up to "__MODULE_STRING(SN9C102_MAX_DEVICES) | 71 | "\nYou can specify up to "__MODULE_STRING(SN9C102_MAX_DEVICES) |
71 | " cameras this way." | 72 | " cameras this way." |
72 | "\nFor example:" | 73 | "\nFor example:" |
@@ -79,13 +80,14 @@ static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] = | |||
79 | SN9C102_FORCE_MUNMAP}; | 80 | SN9C102_FORCE_MUNMAP}; |
80 | module_param_array(force_munmap, bool, NULL, 0444); | 81 | module_param_array(force_munmap, bool, NULL, 0444); |
81 | MODULE_PARM_DESC(force_munmap, | 82 | MODULE_PARM_DESC(force_munmap, |
82 | "\n<0|1[,...]> Force the application to unmap previously" | 83 | " <0|1[,...]>" |
84 | "\nForce the application to unmap previously" | ||
83 | "\nmapped buffer memory before calling any VIDIOC_S_CROP or" | 85 | "\nmapped buffer memory before calling any VIDIOC_S_CROP or" |
84 | "\nVIDIOC_S_FMT ioctl's. Not all the applications support" | 86 | "\nVIDIOC_S_FMT ioctl's. Not all the applications support" |
85 | "\nthis feature. This parameter is specific for each" | 87 | "\nthis feature. This parameter is specific for each" |
86 | "\ndetected camera." | 88 | "\ndetected camera." |
87 | "\n 0 = do not force memory unmapping" | 89 | "\n0 = do not force memory unmapping" |
88 | "\n 1 = force memory unmapping (save memory)" | 90 | "\n1 = force memory unmapping (save memory)" |
89 | "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." | 91 | "\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"." |
90 | "\n"); | 92 | "\n"); |
91 | 93 | ||
@@ -93,7 +95,8 @@ static unsigned int frame_timeout[] = {[0 ... SN9C102_MAX_DEVICES-1] = | |||
93 | SN9C102_FRAME_TIMEOUT}; | 95 | SN9C102_FRAME_TIMEOUT}; |
94 | module_param_array(frame_timeout, uint, NULL, 0644); | 96 | module_param_array(frame_timeout, uint, NULL, 0644); |
95 | MODULE_PARM_DESC(frame_timeout, | 97 | MODULE_PARM_DESC(frame_timeout, |
96 | "\n<0|n[,...]> Timeout for a video frame in seconds before" | 98 | " <0|n[,...]>" |
99 | "\nTimeout for a video frame in seconds before" | ||
97 | "\nreturning an I/O error; 0 for infinity." | 100 | "\nreturning an I/O error; 0 for infinity." |
98 | "\nThis parameter is specific for each detected camera." | 101 | "\nThis parameter is specific for each detected camera." |
99 | "\nDefault value is "__MODULE_STRING(SN9C102_FRAME_TIMEOUT)"." | 102 | "\nDefault value is "__MODULE_STRING(SN9C102_FRAME_TIMEOUT)"." |
@@ -103,7 +106,8 @@ MODULE_PARM_DESC(frame_timeout, | |||
103 | static unsigned short debug = SN9C102_DEBUG_LEVEL; | 106 | static unsigned short debug = SN9C102_DEBUG_LEVEL; |
104 | module_param(debug, ushort, 0644); | 107 | module_param(debug, ushort, 0644); |
105 | MODULE_PARM_DESC(debug, | 108 | MODULE_PARM_DESC(debug, |
106 | "\n<n> Debugging information level, from 0 to 3:" | 109 | " <n>" |
110 | "\nDebugging information level, from 0 to 3:" | ||
107 | "\n0 = none (use carefully)" | 111 | "\n0 = none (use carefully)" |
108 | "\n1 = critical errors" | 112 | "\n1 = critical errors" |
109 | "\n2 = significant informations" | 113 | "\n2 = significant informations" |
@@ -1616,7 +1620,8 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1616 | int err = 0; | 1620 | int err = 0; |
1617 | 1621 | ||
1618 | if (!(cam->state & DEV_INITIALIZED)) { | 1622 | if (!(cam->state & DEV_INITIALIZED)) { |
1619 | init_waitqueue_head(&cam->open); | 1623 | mutex_init(&cam->open_mutex); |
1624 | init_waitqueue_head(&cam->wait_open); | ||
1620 | qctrl = s->qctrl; | 1625 | qctrl = s->qctrl; |
1621 | rect = &(s->cropcap.defrect); | 1626 | rect = &(s->cropcap.defrect); |
1622 | } else { /* use current values */ | 1627 | } else { /* use current values */ |
@@ -1706,21 +1711,27 @@ static int sn9c102_init(struct sn9c102_device* cam) | |||
1706 | return 0; | 1711 | return 0; |
1707 | } | 1712 | } |
1708 | 1713 | ||
1714 | /*****************************************************************************/ | ||
1709 | 1715 | ||
1710 | static void sn9c102_release_resources(struct sn9c102_device* cam) | 1716 | static void sn9c102_release_resources(struct kref *kref) |
1711 | { | 1717 | { |
1718 | struct sn9c102_device *cam; | ||
1719 | |||
1712 | mutex_lock(&sn9c102_sysfs_lock); | 1720 | mutex_lock(&sn9c102_sysfs_lock); |
1713 | 1721 | ||
1722 | cam = container_of(kref, struct sn9c102_device, kref); | ||
1723 | |||
1714 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); | 1724 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); |
1715 | video_set_drvdata(cam->v4ldev, NULL); | 1725 | video_set_drvdata(cam->v4ldev, NULL); |
1716 | video_unregister_device(cam->v4ldev); | 1726 | video_unregister_device(cam->v4ldev); |
1727 | usb_put_dev(cam->usbdev); | ||
1728 | kfree(cam->control_buffer); | ||
1729 | kfree(cam); | ||
1717 | 1730 | ||
1718 | mutex_unlock(&sn9c102_sysfs_lock); | 1731 | mutex_unlock(&sn9c102_sysfs_lock); |
1719 | 1732 | ||
1720 | kfree(cam->control_buffer); | ||
1721 | } | 1733 | } |
1722 | 1734 | ||
1723 | /*****************************************************************************/ | ||
1724 | 1735 | ||
1725 | static int sn9c102_open(struct inode* inode, struct file* filp) | 1736 | static int sn9c102_open(struct inode* inode, struct file* filp) |
1726 | { | 1737 | { |
@@ -1728,43 +1739,78 @@ static int sn9c102_open(struct inode* inode, struct file* filp) | |||
1728 | int err = 0; | 1739 | int err = 0; |
1729 | 1740 | ||
1730 | /* | 1741 | /* |
1731 | This is the only safe way to prevent race conditions with | 1742 | A read_trylock() in open() is the only safe way to prevent race |
1732 | disconnect | 1743 | conditions with disconnect(), one close() and multiple (not |
1744 | necessarily simultaneous) attempts to open(). For example, it | ||
1745 | prevents from waiting for a second access, while the device | ||
1746 | structure is being deallocated, after a possible disconnect() and | ||
1747 | during a following close() holding the write lock: given that, after | ||
1748 | this deallocation, no access will be possible anymore, using the | ||
1749 | non-trylock version would have let open() gain the access to the | ||
1750 | device structure improperly. | ||
1751 | For this reason the lock must also not be per-device. | ||
1733 | */ | 1752 | */ |
1734 | if (!down_read_trylock(&sn9c102_disconnect)) | 1753 | if (!down_read_trylock(&sn9c102_dev_lock)) |
1735 | return -ERESTARTSYS; | 1754 | return -ERESTARTSYS; |
1736 | 1755 | ||
1737 | cam = video_get_drvdata(video_devdata(filp)); | 1756 | cam = video_get_drvdata(video_devdata(filp)); |
1738 | 1757 | ||
1739 | if (mutex_lock_interruptible(&cam->dev_mutex)) { | 1758 | if (wait_for_completion_interruptible(&cam->probe)) { |
1740 | up_read(&sn9c102_disconnect); | 1759 | up_read(&sn9c102_dev_lock); |
1760 | return -ERESTARTSYS; | ||
1761 | } | ||
1762 | |||
1763 | kref_get(&cam->kref); | ||
1764 | |||
1765 | /* | ||
1766 | Make sure to isolate all the simultaneous opens. | ||
1767 | */ | ||
1768 | if (mutex_lock_interruptible(&cam->open_mutex)) { | ||
1769 | kref_put(&cam->kref, sn9c102_release_resources); | ||
1770 | up_read(&sn9c102_dev_lock); | ||
1741 | return -ERESTARTSYS; | 1771 | return -ERESTARTSYS; |
1742 | } | 1772 | } |
1743 | 1773 | ||
1774 | if (cam->state & DEV_DISCONNECTED) { | ||
1775 | DBG(1, "Device not present"); | ||
1776 | err = -ENODEV; | ||
1777 | goto out; | ||
1778 | } | ||
1779 | |||
1744 | if (cam->users) { | 1780 | if (cam->users) { |
1745 | DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor); | 1781 | DBG(2, "Device /dev/video%d is already in use", |
1782 | cam->v4ldev->minor); | ||
1746 | DBG(3, "Simultaneous opens are not supported"); | 1783 | DBG(3, "Simultaneous opens are not supported"); |
1784 | /* | ||
1785 | open() must follow the open flags and should block | ||
1786 | eventually while the device is in use. | ||
1787 | */ | ||
1747 | if ((filp->f_flags & O_NONBLOCK) || | 1788 | if ((filp->f_flags & O_NONBLOCK) || |
1748 | (filp->f_flags & O_NDELAY)) { | 1789 | (filp->f_flags & O_NDELAY)) { |
1749 | err = -EWOULDBLOCK; | 1790 | err = -EWOULDBLOCK; |
1750 | goto out; | 1791 | goto out; |
1751 | } | 1792 | } |
1752 | mutex_unlock(&cam->dev_mutex); | 1793 | DBG(2, "A blocking open() has been requested. Wait for the " |
1753 | err = wait_event_interruptible_exclusive(cam->open, | 1794 | "device to be released..."); |
1754 | cam->state & DEV_DISCONNECTED | 1795 | up_read(&sn9c102_dev_lock); |
1796 | /* | ||
1797 | We will not release the "open_mutex" lock, so that only one | ||
1798 | process can be in the wait queue below. This way the process | ||
1799 | will be sleeping while holding the lock, without loosing its | ||
1800 | priority after any wake_up(). | ||
1801 | */ | ||
1802 | err = wait_event_interruptible_exclusive(cam->wait_open, | ||
1803 | (cam->state & DEV_DISCONNECTED) | ||
1755 | || !cam->users); | 1804 | || !cam->users); |
1756 | if (err) { | 1805 | down_read(&sn9c102_dev_lock); |
1757 | up_read(&sn9c102_disconnect); | 1806 | if (err) |
1758 | return err; | 1807 | goto out; |
1759 | } | ||
1760 | if (cam->state & DEV_DISCONNECTED) { | 1808 | if (cam->state & DEV_DISCONNECTED) { |
1761 | up_read(&sn9c102_disconnect); | 1809 | err = -ENODEV; |
1762 | return -ENODEV; | 1810 | goto out; |
1763 | } | 1811 | } |
1764 | mutex_lock(&cam->dev_mutex); | ||
1765 | } | 1812 | } |
1766 | 1813 | ||
1767 | |||
1768 | if (cam->state & DEV_MISCONFIGURED) { | 1814 | if (cam->state & DEV_MISCONFIGURED) { |
1769 | err = sn9c102_init(cam); | 1815 | err = sn9c102_init(cam); |
1770 | if (err) { | 1816 | if (err) { |
@@ -1789,36 +1835,33 @@ static int sn9c102_open(struct inode* inode, struct file* filp) | |||
1789 | DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); | 1835 | DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); |
1790 | 1836 | ||
1791 | out: | 1837 | out: |
1792 | mutex_unlock(&cam->dev_mutex); | 1838 | mutex_unlock(&cam->open_mutex); |
1793 | up_read(&sn9c102_disconnect); | 1839 | if (err) |
1840 | kref_put(&cam->kref, sn9c102_release_resources); | ||
1841 | |||
1842 | up_read(&sn9c102_dev_lock); | ||
1794 | return err; | 1843 | return err; |
1795 | } | 1844 | } |
1796 | 1845 | ||
1797 | 1846 | ||
1798 | static int sn9c102_release(struct inode* inode, struct file* filp) | 1847 | static int sn9c102_release(struct inode* inode, struct file* filp) |
1799 | { | 1848 | { |
1800 | struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); | 1849 | struct sn9c102_device* cam; |
1801 | 1850 | ||
1802 | mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */ | 1851 | down_write(&sn9c102_dev_lock); |
1803 | 1852 | ||
1804 | sn9c102_stop_transfer(cam); | 1853 | cam = video_get_drvdata(video_devdata(filp)); |
1805 | 1854 | ||
1855 | sn9c102_stop_transfer(cam); | ||
1806 | sn9c102_release_buffers(cam); | 1856 | sn9c102_release_buffers(cam); |
1807 | |||
1808 | if (cam->state & DEV_DISCONNECTED) { | ||
1809 | sn9c102_release_resources(cam); | ||
1810 | usb_put_dev(cam->usbdev); | ||
1811 | mutex_unlock(&cam->dev_mutex); | ||
1812 | kfree(cam); | ||
1813 | return 0; | ||
1814 | } | ||
1815 | |||
1816 | cam->users--; | 1857 | cam->users--; |
1817 | wake_up_interruptible_nr(&cam->open, 1); | 1858 | wake_up_interruptible_nr(&cam->wait_open, 1); |
1818 | 1859 | ||
1819 | DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); | 1860 | DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); |
1820 | 1861 | ||
1821 | mutex_unlock(&cam->dev_mutex); | 1862 | kref_put(&cam->kref, sn9c102_release_resources); |
1863 | |||
1864 | up_write(&sn9c102_dev_lock); | ||
1822 | 1865 | ||
1823 | return 0; | 1866 | return 0; |
1824 | } | 1867 | } |
@@ -2085,7 +2128,6 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) | |||
2085 | 2128 | ||
2086 | vma->vm_ops = &sn9c102_vm_ops; | 2129 | vma->vm_ops = &sn9c102_vm_ops; |
2087 | vma->vm_private_data = &cam->frame[i]; | 2130 | vma->vm_private_data = &cam->frame[i]; |
2088 | |||
2089 | sn9c102_vm_open(vma); | 2131 | sn9c102_vm_open(vma); |
2090 | 2132 | ||
2091 | mutex_unlock(&cam->fileop_mutex); | 2133 | mutex_unlock(&cam->fileop_mutex); |
@@ -3215,8 +3257,6 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3215 | goto fail; | 3257 | goto fail; |
3216 | } | 3258 | } |
3217 | 3259 | ||
3218 | mutex_init(&cam->dev_mutex); | ||
3219 | |||
3220 | r = sn9c102_read_reg(cam, 0x00); | 3260 | r = sn9c102_read_reg(cam, 0x00); |
3221 | if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) { | 3261 | if (r < 0 || (r != 0x10 && r != 0x11 && r != 0x12)) { |
3222 | DBG(1, "Sorry, this is not a SN9C1xx-based camera " | 3262 | DBG(1, "Sorry, this is not a SN9C1xx-based camera " |
@@ -3282,7 +3322,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3282 | cam->v4ldev->release = video_device_release; | 3322 | cam->v4ldev->release = video_device_release; |
3283 | video_set_drvdata(cam->v4ldev, cam); | 3323 | video_set_drvdata(cam->v4ldev, cam); |
3284 | 3324 | ||
3285 | mutex_lock(&cam->dev_mutex); | 3325 | init_completion(&cam->probe); |
3286 | 3326 | ||
3287 | err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, | 3327 | err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, |
3288 | video_nr[dev_nr]); | 3328 | video_nr[dev_nr]); |
@@ -3292,7 +3332,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3292 | DBG(1, "Free /dev/videoX node not found"); | 3332 | DBG(1, "Free /dev/videoX node not found"); |
3293 | video_nr[dev_nr] = -1; | 3333 | video_nr[dev_nr] = -1; |
3294 | dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; | 3334 | dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; |
3295 | mutex_unlock(&cam->dev_mutex); | 3335 | complete_all(&cam->probe); |
3296 | goto fail; | 3336 | goto fail; |
3297 | } | 3337 | } |
3298 | 3338 | ||
@@ -3318,8 +3358,10 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
3318 | #endif | 3358 | #endif |
3319 | 3359 | ||
3320 | usb_set_intfdata(intf, cam); | 3360 | usb_set_intfdata(intf, cam); |
3361 | kref_init(&cam->kref); | ||
3362 | usb_get_dev(cam->usbdev); | ||
3321 | 3363 | ||
3322 | mutex_unlock(&cam->dev_mutex); | 3364 | complete_all(&cam->probe); |
3323 | 3365 | ||
3324 | return 0; | 3366 | return 0; |
3325 | 3367 | ||
@@ -3336,40 +3378,31 @@ fail: | |||
3336 | 3378 | ||
3337 | static void sn9c102_usb_disconnect(struct usb_interface* intf) | 3379 | static void sn9c102_usb_disconnect(struct usb_interface* intf) |
3338 | { | 3380 | { |
3339 | struct sn9c102_device* cam = usb_get_intfdata(intf); | 3381 | struct sn9c102_device* cam; |
3340 | |||
3341 | if (!cam) | ||
3342 | return; | ||
3343 | 3382 | ||
3344 | down_write(&sn9c102_disconnect); | 3383 | down_write(&sn9c102_dev_lock); |
3345 | 3384 | ||
3346 | mutex_lock(&cam->dev_mutex); | 3385 | cam = usb_get_intfdata(intf); |
3347 | 3386 | ||
3348 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); | 3387 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); |
3349 | 3388 | ||
3350 | wake_up_interruptible_all(&cam->open); | ||
3351 | |||
3352 | if (cam->users) { | 3389 | if (cam->users) { |
3353 | DBG(2, "Device /dev/video%d is open! Deregistration and " | 3390 | DBG(2, "Device /dev/video%d is open! Deregistration and " |
3354 | "memory deallocation are deferred on close.", | 3391 | "memory deallocation are deferred.", |
3355 | cam->v4ldev->minor); | 3392 | cam->v4ldev->minor); |
3356 | cam->state |= DEV_MISCONFIGURED; | 3393 | cam->state |= DEV_MISCONFIGURED; |
3357 | sn9c102_stop_transfer(cam); | 3394 | sn9c102_stop_transfer(cam); |
3358 | cam->state |= DEV_DISCONNECTED; | 3395 | cam->state |= DEV_DISCONNECTED; |
3359 | wake_up_interruptible(&cam->wait_frame); | 3396 | wake_up_interruptible(&cam->wait_frame); |
3360 | wake_up(&cam->wait_stream); | 3397 | wake_up(&cam->wait_stream); |
3361 | usb_get_dev(cam->usbdev); | 3398 | } else |
3362 | } else { | ||
3363 | cam->state |= DEV_DISCONNECTED; | 3399 | cam->state |= DEV_DISCONNECTED; |
3364 | sn9c102_release_resources(cam); | ||
3365 | } | ||
3366 | 3400 | ||
3367 | mutex_unlock(&cam->dev_mutex); | 3401 | wake_up_interruptible_all(&cam->wait_open); |
3368 | 3402 | ||
3369 | if (!cam->users) | 3403 | kref_put(&cam->kref, sn9c102_release_resources); |
3370 | kfree(cam); | ||
3371 | 3404 | ||
3372 | up_write(&sn9c102_disconnect); | 3405 | up_write(&sn9c102_dev_lock); |
3373 | } | 3406 | } |
3374 | 3407 | ||
3375 | 3408 | ||
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7630.c b/drivers/media/video/sn9c102/sn9c102_ov7630.c index e6832347894f..e4856fd77982 100644 --- a/drivers/media/video/sn9c102/sn9c102_ov7630.c +++ b/drivers/media/video/sn9c102/sn9c102_ov7630.c | |||
@@ -104,6 +104,145 @@ static int ov7630_init(struct sn9c102_device* cam) | |||
104 | err += sn9c102_i2c_write(cam, 0x74, 0x21); | 104 | err += sn9c102_i2c_write(cam, 0x74, 0x21); |
105 | err += sn9c102_i2c_write(cam, 0x7d, 0xf7); | 105 | err += sn9c102_i2c_write(cam, 0x7d, 0xf7); |
106 | break; | 106 | break; |
107 | case BRIDGE_SN9C105: | ||
108 | case BRIDGE_SN9C120: | ||
109 | err = sn9c102_write_const_regs(cam, {0x40, 0x02}, {0x00, 0x03}, | ||
110 | {0x1a, 0x04}, {0x03, 0x10}, | ||
111 | {0x0a, 0x14}, {0xe2, 0x17}, | ||
112 | {0x0b, 0x18}, {0x00, 0x19}, | ||
113 | {0x1d, 0x1a}, {0x10, 0x1b}, | ||
114 | {0x02, 0x1c}, {0x03, 0x1d}, | ||
115 | {0x0f, 0x1e}, {0x0c, 0x1f}, | ||
116 | {0x00, 0x20}, {0x24, 0x21}, | ||
117 | {0x3b, 0x22}, {0x47, 0x23}, | ||
118 | {0x60, 0x24}, {0x71, 0x25}, | ||
119 | {0x80, 0x26}, {0x8f, 0x27}, | ||
120 | {0x9d, 0x28}, {0xaa, 0x29}, | ||
121 | {0xb8, 0x2a}, {0xc4, 0x2b}, | ||
122 | {0xd1, 0x2c}, {0xdd, 0x2d}, | ||
123 | {0xe8, 0x2e}, {0xf4, 0x2f}, | ||
124 | {0xff, 0x30}, {0x00, 0x3f}, | ||
125 | {0xc7, 0x40}, {0x01, 0x41}, | ||
126 | {0x44, 0x42}, {0x00, 0x43}, | ||
127 | {0x44, 0x44}, {0x00, 0x45}, | ||
128 | {0x44, 0x46}, {0x00, 0x47}, | ||
129 | {0xc7, 0x48}, {0x01, 0x49}, | ||
130 | {0xc7, 0x4a}, {0x01, 0x4b}, | ||
131 | {0xc7, 0x4c}, {0x01, 0x4d}, | ||
132 | {0x44, 0x4e}, {0x00, 0x4f}, | ||
133 | {0x44, 0x50}, {0x00, 0x51}, | ||
134 | {0x44, 0x52}, {0x00, 0x53}, | ||
135 | {0xc7, 0x54}, {0x01, 0x55}, | ||
136 | {0xc7, 0x56}, {0x01, 0x57}, | ||
137 | {0xc7, 0x58}, {0x01, 0x59}, | ||
138 | {0x44, 0x5a}, {0x00, 0x5b}, | ||
139 | {0x44, 0x5c}, {0x00, 0x5d}, | ||
140 | {0x44, 0x5e}, {0x00, 0x5f}, | ||
141 | {0xc7, 0x60}, {0x01, 0x61}, | ||
142 | {0xc7, 0x62}, {0x01, 0x63}, | ||
143 | {0xc7, 0x64}, {0x01, 0x65}, | ||
144 | {0x44, 0x66}, {0x00, 0x67}, | ||
145 | {0x44, 0x68}, {0x00, 0x69}, | ||
146 | {0x44, 0x6a}, {0x00, 0x6b}, | ||
147 | {0xc7, 0x6c}, {0x01, 0x6d}, | ||
148 | {0xc7, 0x6e}, {0x01, 0x6f}, | ||
149 | {0xc7, 0x70}, {0x01, 0x71}, | ||
150 | {0x44, 0x72}, {0x00, 0x73}, | ||
151 | {0x44, 0x74}, {0x00, 0x75}, | ||
152 | {0x44, 0x76}, {0x00, 0x77}, | ||
153 | {0xc7, 0x78}, {0x01, 0x79}, | ||
154 | {0xc7, 0x7a}, {0x01, 0x7b}, | ||
155 | {0xc7, 0x7c}, {0x01, 0x7d}, | ||
156 | {0x44, 0x7e}, {0x00, 0x7f}, | ||
157 | {0x17, 0x84}, {0x00, 0x85}, | ||
158 | {0x2e, 0x86}, {0x00, 0x87}, | ||
159 | {0x09, 0x88}, {0x00, 0x89}, | ||
160 | {0xe8, 0x8a}, {0x0f, 0x8b}, | ||
161 | {0xda, 0x8c}, {0x0f, 0x8d}, | ||
162 | {0x40, 0x8e}, {0x00, 0x8f}, | ||
163 | {0x37, 0x90}, {0x00, 0x91}, | ||
164 | {0xcf, 0x92}, {0x0f, 0x93}, | ||
165 | {0xfa, 0x94}, {0x0f, 0x95}, | ||
166 | {0x00, 0x96}, {0x00, 0x97}, | ||
167 | {0x00, 0x98}, {0x66, 0x99}, | ||
168 | {0x00, 0x9a}, {0x40, 0x9b}, | ||
169 | {0x20, 0x9c}, {0x00, 0x9d}, | ||
170 | {0x00, 0x9e}, {0x00, 0x9f}, | ||
171 | {0x2d, 0xc0}, {0x2d, 0xc1}, | ||
172 | {0x3a, 0xc2}, {0x00, 0xc3}, | ||
173 | {0x04, 0xc4}, {0x3f, 0xc5}, | ||
174 | {0x00, 0xc6}, {0x00, 0xc7}, | ||
175 | {0x50, 0xc8}, {0x3c, 0xc9}, | ||
176 | {0x28, 0xca}, {0xd8, 0xcb}, | ||
177 | {0x14, 0xcc}, {0xec, 0xcd}, | ||
178 | {0x32, 0xce}, {0xdd, 0xcf}, | ||
179 | {0x32, 0xd0}, {0xdd, 0xd1}, | ||
180 | {0x6a, 0xd2}, {0x50, 0xd3}, | ||
181 | {0x60, 0xd4}, {0x00, 0xd5}, | ||
182 | {0x00, 0xd6}); | ||
183 | |||
184 | err += sn9c102_i2c_write(cam, 0x12, 0x80); | ||
185 | err += sn9c102_i2c_write(cam, 0x12, 0x48); | ||
186 | err += sn9c102_i2c_write(cam, 0x01, 0x80); | ||
187 | err += sn9c102_i2c_write(cam, 0x02, 0x80); | ||
188 | err += sn9c102_i2c_write(cam, 0x03, 0x80); | ||
189 | err += sn9c102_i2c_write(cam, 0x04, 0x10); | ||
190 | err += sn9c102_i2c_write(cam, 0x05, 0x20); | ||
191 | err += sn9c102_i2c_write(cam, 0x06, 0x80); | ||
192 | err += sn9c102_i2c_write(cam, 0x11, 0x00); | ||
193 | err += sn9c102_i2c_write(cam, 0x0c, 0x20); | ||
194 | err += sn9c102_i2c_write(cam, 0x0d, 0x20); | ||
195 | err += sn9c102_i2c_write(cam, 0x15, 0x80); | ||
196 | err += sn9c102_i2c_write(cam, 0x16, 0x03); | ||
197 | err += sn9c102_i2c_write(cam, 0x17, 0x1b); | ||
198 | err += sn9c102_i2c_write(cam, 0x18, 0xbd); | ||
199 | err += sn9c102_i2c_write(cam, 0x19, 0x05); | ||
200 | err += sn9c102_i2c_write(cam, 0x1a, 0xf6); | ||
201 | err += sn9c102_i2c_write(cam, 0x1b, 0x04); | ||
202 | err += sn9c102_i2c_write(cam, 0x21, 0x1b); | ||
203 | err += sn9c102_i2c_write(cam, 0x22, 0x00); | ||
204 | err += sn9c102_i2c_write(cam, 0x23, 0xde); | ||
205 | err += sn9c102_i2c_write(cam, 0x24, 0x10); | ||
206 | err += sn9c102_i2c_write(cam, 0x25, 0x8a); | ||
207 | err += sn9c102_i2c_write(cam, 0x26, 0xa0); | ||
208 | err += sn9c102_i2c_write(cam, 0x27, 0xca); | ||
209 | err += sn9c102_i2c_write(cam, 0x28, 0xa2); | ||
210 | err += sn9c102_i2c_write(cam, 0x29, 0x74); | ||
211 | err += sn9c102_i2c_write(cam, 0x2a, 0x88); | ||
212 | err += sn9c102_i2c_write(cam, 0x2b, 0x34); | ||
213 | err += sn9c102_i2c_write(cam, 0x2c, 0x88); | ||
214 | err += sn9c102_i2c_write(cam, 0x2e, 0x00); | ||
215 | err += sn9c102_i2c_write(cam, 0x2f, 0x00); | ||
216 | err += sn9c102_i2c_write(cam, 0x30, 0x00); | ||
217 | err += sn9c102_i2c_write(cam, 0x32, 0xc2); | ||
218 | err += sn9c102_i2c_write(cam, 0x33, 0x08); | ||
219 | err += sn9c102_i2c_write(cam, 0x4c, 0x40); | ||
220 | err += sn9c102_i2c_write(cam, 0x4d, 0xf3); | ||
221 | err += sn9c102_i2c_write(cam, 0x60, 0x05); | ||
222 | err += sn9c102_i2c_write(cam, 0x61, 0x40); | ||
223 | err += sn9c102_i2c_write(cam, 0x62, 0x12); | ||
224 | err += sn9c102_i2c_write(cam, 0x63, 0x57); | ||
225 | err += sn9c102_i2c_write(cam, 0x64, 0x73); | ||
226 | err += sn9c102_i2c_write(cam, 0x65, 0x00); | ||
227 | err += sn9c102_i2c_write(cam, 0x66, 0x55); | ||
228 | err += sn9c102_i2c_write(cam, 0x67, 0x01); | ||
229 | err += sn9c102_i2c_write(cam, 0x68, 0xac); | ||
230 | err += sn9c102_i2c_write(cam, 0x69, 0x38); | ||
231 | err += sn9c102_i2c_write(cam, 0x6f, 0x1f); | ||
232 | err += sn9c102_i2c_write(cam, 0x70, 0x01); | ||
233 | err += sn9c102_i2c_write(cam, 0x71, 0x00); | ||
234 | err += sn9c102_i2c_write(cam, 0x72, 0x10); | ||
235 | err += sn9c102_i2c_write(cam, 0x73, 0x50); | ||
236 | err += sn9c102_i2c_write(cam, 0x74, 0x20); | ||
237 | err += sn9c102_i2c_write(cam, 0x76, 0x01); | ||
238 | err += sn9c102_i2c_write(cam, 0x77, 0xf3); | ||
239 | err += sn9c102_i2c_write(cam, 0x78, 0x90); | ||
240 | err += sn9c102_i2c_write(cam, 0x79, 0x98); | ||
241 | err += sn9c102_i2c_write(cam, 0x7a, 0x98); | ||
242 | err += sn9c102_i2c_write(cam, 0x7b, 0x00); | ||
243 | err += sn9c102_i2c_write(cam, 0x7c, 0x38); | ||
244 | err += sn9c102_i2c_write(cam, 0x7d, 0xff); | ||
245 | break; | ||
107 | default: | 246 | default: |
108 | break; | 247 | break; |
109 | } | 248 | } |
@@ -115,6 +254,7 @@ static int ov7630_init(struct sn9c102_device* cam) | |||
115 | static int ov7630_get_ctrl(struct sn9c102_device* cam, | 254 | static int ov7630_get_ctrl(struct sn9c102_device* cam, |
116 | struct v4l2_control* ctrl) | 255 | struct v4l2_control* ctrl) |
117 | { | 256 | { |
257 | enum sn9c102_bridge bridge = sn9c102_get_bridge(cam); | ||
118 | int err = 0; | 258 | int err = 0; |
119 | 259 | ||
120 | switch (ctrl->id) { | 260 | switch (ctrl->id) { |
@@ -123,13 +263,20 @@ static int ov7630_get_ctrl(struct sn9c102_device* cam, | |||
123 | return -EIO; | 263 | return -EIO; |
124 | break; | 264 | break; |
125 | case V4L2_CID_RED_BALANCE: | 265 | case V4L2_CID_RED_BALANCE: |
126 | ctrl->value = sn9c102_pread_reg(cam, 0x07); | 266 | if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120) |
267 | ctrl->value = sn9c102_pread_reg(cam, 0x05); | ||
268 | else | ||
269 | ctrl->value = sn9c102_pread_reg(cam, 0x07); | ||
127 | break; | 270 | break; |
128 | case V4L2_CID_BLUE_BALANCE: | 271 | case V4L2_CID_BLUE_BALANCE: |
129 | ctrl->value = sn9c102_pread_reg(cam, 0x06); | 272 | ctrl->value = sn9c102_pread_reg(cam, 0x06); |
130 | break; | 273 | break; |
131 | case SN9C102_V4L2_CID_GREEN_BALANCE: | 274 | case SN9C102_V4L2_CID_GREEN_BALANCE: |
132 | ctrl->value = sn9c102_pread_reg(cam, 0x05); | 275 | if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120) |
276 | ctrl->value = sn9c102_pread_reg(cam, 0x07); | ||
277 | else | ||
278 | ctrl->value = sn9c102_pread_reg(cam, 0x05); | ||
279 | break; | ||
133 | break; | 280 | break; |
134 | case V4L2_CID_GAIN: | 281 | case V4L2_CID_GAIN: |
135 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0) | 282 | if ((ctrl->value = sn9c102_i2c_read(cam, 0x00)) < 0) |
@@ -177,6 +324,7 @@ static int ov7630_get_ctrl(struct sn9c102_device* cam, | |||
177 | static int ov7630_set_ctrl(struct sn9c102_device* cam, | 324 | static int ov7630_set_ctrl(struct sn9c102_device* cam, |
178 | const struct v4l2_control* ctrl) | 325 | const struct v4l2_control* ctrl) |
179 | { | 326 | { |
327 | enum sn9c102_bridge bridge = sn9c102_get_bridge(cam); | ||
180 | int err = 0; | 328 | int err = 0; |
181 | 329 | ||
182 | switch (ctrl->id) { | 330 | switch (ctrl->id) { |
@@ -184,13 +332,19 @@ static int ov7630_set_ctrl(struct sn9c102_device* cam, | |||
184 | err += sn9c102_i2c_write(cam, 0x10, ctrl->value); | 332 | err += sn9c102_i2c_write(cam, 0x10, ctrl->value); |
185 | break; | 333 | break; |
186 | case V4L2_CID_RED_BALANCE: | 334 | case V4L2_CID_RED_BALANCE: |
187 | err += sn9c102_write_reg(cam, ctrl->value, 0x07); | 335 | if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120) |
336 | err += sn9c102_write_reg(cam, ctrl->value, 0x05); | ||
337 | else | ||
338 | err += sn9c102_write_reg(cam, ctrl->value, 0x07); | ||
188 | break; | 339 | break; |
189 | case V4L2_CID_BLUE_BALANCE: | 340 | case V4L2_CID_BLUE_BALANCE: |
190 | err += sn9c102_write_reg(cam, ctrl->value, 0x06); | 341 | err += sn9c102_write_reg(cam, ctrl->value, 0x06); |
191 | break; | 342 | break; |
192 | case SN9C102_V4L2_CID_GREEN_BALANCE: | 343 | case SN9C102_V4L2_CID_GREEN_BALANCE: |
193 | err += sn9c102_write_reg(cam, ctrl->value, 0x05); | 344 | if (bridge == BRIDGE_SN9C105 || bridge == BRIDGE_SN9C120) |
345 | err += sn9c102_write_reg(cam, ctrl->value, 0x07); | ||
346 | else | ||
347 | err += sn9c102_write_reg(cam, ctrl->value, 0x05); | ||
194 | break; | 348 | break; |
195 | case V4L2_CID_GAIN: | 349 | case V4L2_CID_GAIN: |
196 | err += sn9c102_i2c_write(cam, 0x00, ctrl->value); | 350 | err += sn9c102_i2c_write(cam, 0x00, ctrl->value); |
@@ -227,8 +381,21 @@ static int ov7630_set_crop(struct sn9c102_device* cam, | |||
227 | { | 381 | { |
228 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); | 382 | struct sn9c102_sensor* s = sn9c102_get_sensor(cam); |
229 | int err = 0; | 383 | int err = 0; |
230 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1, | 384 | u8 h_start = 0, v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; |
231 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; | 385 | |
386 | switch (sn9c102_get_bridge(cam)) { | ||
387 | case BRIDGE_SN9C101: | ||
388 | case BRIDGE_SN9C102: | ||
389 | case BRIDGE_SN9C103: | ||
390 | h_start = (u8)(rect->left - s->cropcap.bounds.left) + 1; | ||
391 | break; | ||
392 | case BRIDGE_SN9C105: | ||
393 | case BRIDGE_SN9C120: | ||
394 | h_start = (u8)(rect->left - s->cropcap.bounds.left) + 4; | ||
395 | break; | ||
396 | default: | ||
397 | break; | ||
398 | } | ||
232 | 399 | ||
233 | err += sn9c102_write_reg(cam, h_start, 0x12); | 400 | err += sn9c102_write_reg(cam, h_start, 0x12); |
234 | err += sn9c102_write_reg(cam, v_start, 0x13); | 401 | err += sn9c102_write_reg(cam, v_start, 0x13); |
@@ -242,10 +409,28 @@ static int ov7630_set_pix_format(struct sn9c102_device* cam, | |||
242 | { | 409 | { |
243 | int err = 0; | 410 | int err = 0; |
244 | 411 | ||
245 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) | 412 | switch (sn9c102_get_bridge(cam)) { |
246 | err += sn9c102_write_reg(cam, 0x20, 0x19); | 413 | case BRIDGE_SN9C101: |
247 | else | 414 | case BRIDGE_SN9C102: |
248 | err += sn9c102_write_reg(cam, 0x50, 0x19); | 415 | case BRIDGE_SN9C103: |
416 | if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) | ||
417 | err += sn9c102_write_reg(cam, 0x50, 0x19); | ||
418 | else | ||
419 | err += sn9c102_write_reg(cam, 0x20, 0x19); | ||
420 | break; | ||
421 | case BRIDGE_SN9C105: | ||
422 | case BRIDGE_SN9C120: | ||
423 | if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8) { | ||
424 | err += sn9c102_write_reg(cam, 0xe5, 0x17); | ||
425 | err += sn9c102_i2c_write(cam, 0x11, 0x04); | ||
426 | } else { | ||
427 | err += sn9c102_write_reg(cam, 0xe2, 0x17); | ||
428 | err += sn9c102_i2c_write(cam, 0x11, 0x02); | ||
429 | } | ||
430 | break; | ||
431 | default: | ||
432 | break; | ||
433 | } | ||
249 | 434 | ||
250 | return err; | 435 | return err; |
251 | } | 436 | } |
@@ -254,7 +439,8 @@ static int ov7630_set_pix_format(struct sn9c102_device* cam, | |||
254 | static const struct sn9c102_sensor ov7630 = { | 439 | static const struct sn9c102_sensor ov7630 = { |
255 | .name = "OV7630", | 440 | .name = "OV7630", |
256 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | 441 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", |
257 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103, | 442 | .supported_bridge = BRIDGE_SN9C101 | BRIDGE_SN9C102 | BRIDGE_SN9C103 | |
443 | BRIDGE_SN9C105 | BRIDGE_SN9C120, | ||
258 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, | 444 | .sysfs_ops = SN9C102_I2C_READ | SN9C102_I2C_WRITE, |
259 | .frequency = SN9C102_I2C_100KHZ, | 445 | .frequency = SN9C102_I2C_100KHZ, |
260 | .interface = SN9C102_I2C_2WIRES, | 446 | .interface = SN9C102_I2C_2WIRES, |
@@ -417,6 +603,12 @@ int sn9c102_probe_ov7630(struct sn9c102_device* cam) | |||
417 | err += sn9c102_write_const_regs(cam, {0x01, 0x01}, | 603 | err += sn9c102_write_const_regs(cam, {0x01, 0x01}, |
418 | {0x00, 0x01}); | 604 | {0x00, 0x01}); |
419 | break; | 605 | break; |
606 | case BRIDGE_SN9C105: | ||
607 | case BRIDGE_SN9C120: | ||
608 | err = sn9c102_write_const_regs(cam, {0x01, 0xf1}, {0x00, 0xf1}, | ||
609 | {0x29, 0x01}, {0x74, 0x02}, | ||
610 | {0x0e, 0x01}, {0x44, 0x01}); | ||
611 | break; | ||
420 | default: | 612 | default: |
421 | break; | 613 | break; |
422 | } | 614 | } |
diff --git a/drivers/media/video/sn9c102/sn9c102_ov7660.c b/drivers/media/video/sn9c102/sn9c102_ov7660.c index 4b6474048a72..8aae416ba8ec 100644 --- a/drivers/media/video/sn9c102/sn9c102_ov7660.c +++ b/drivers/media/video/sn9c102/sn9c102_ov7660.c | |||
@@ -41,65 +41,65 @@ static int ov7660_init(struct sn9c102_device* cam) | |||
41 | {0xbb, 0x2a}, {0xc7, 0x2b}, | 41 | {0xbb, 0x2a}, {0xc7, 0x2b}, |
42 | {0xd3, 0x2c}, {0xde, 0x2d}, | 42 | {0xd3, 0x2c}, {0xde, 0x2d}, |
43 | {0xea, 0x2e}, {0xf4, 0x2f}, | 43 | {0xea, 0x2e}, {0xf4, 0x2f}, |
44 | {0xff, 0x30}, {0x00, 0x3F}, | 44 | {0xff, 0x30}, {0x00, 0x3f}, |
45 | {0xC7, 0x40}, {0x01, 0x41}, | 45 | {0xc7, 0x40}, {0x01, 0x41}, |
46 | {0x44, 0x42}, {0x00, 0x43}, | 46 | {0x44, 0x42}, {0x00, 0x43}, |
47 | {0x44, 0x44}, {0x00, 0x45}, | 47 | {0x44, 0x44}, {0x00, 0x45}, |
48 | {0x44, 0x46}, {0x00, 0x47}, | 48 | {0x44, 0x46}, {0x00, 0x47}, |
49 | {0xC7, 0x48}, {0x01, 0x49}, | 49 | {0xc7, 0x48}, {0x01, 0x49}, |
50 | {0xC7, 0x4A}, {0x01, 0x4B}, | 50 | {0xc7, 0x4a}, {0x01, 0x4b}, |
51 | {0xC7, 0x4C}, {0x01, 0x4D}, | 51 | {0xc7, 0x4c}, {0x01, 0x4d}, |
52 | {0x44, 0x4E}, {0x00, 0x4F}, | 52 | {0x44, 0x4e}, {0x00, 0x4f}, |
53 | {0x44, 0x50}, {0x00, 0x51}, | 53 | {0x44, 0x50}, {0x00, 0x51}, |
54 | {0x44, 0x52}, {0x00, 0x53}, | 54 | {0x44, 0x52}, {0x00, 0x53}, |
55 | {0xC7, 0x54}, {0x01, 0x55}, | 55 | {0xc7, 0x54}, {0x01, 0x55}, |
56 | {0xC7, 0x56}, {0x01, 0x57}, | 56 | {0xc7, 0x56}, {0x01, 0x57}, |
57 | {0xC7, 0x58}, {0x01, 0x59}, | 57 | {0xc7, 0x58}, {0x01, 0x59}, |
58 | {0x44, 0x5A}, {0x00, 0x5B}, | 58 | {0x44, 0x5a}, {0x00, 0x5b}, |
59 | {0x44, 0x5C}, {0x00, 0x5D}, | 59 | {0x44, 0x5c}, {0x00, 0x5d}, |
60 | {0x44, 0x5E}, {0x00, 0x5F}, | 60 | {0x44, 0x5e}, {0x00, 0x5f}, |
61 | {0xC7, 0x60}, {0x01, 0x61}, | 61 | {0xc7, 0x60}, {0x01, 0x61}, |
62 | {0xC7, 0x62}, {0x01, 0x63}, | 62 | {0xc7, 0x62}, {0x01, 0x63}, |
63 | {0xC7, 0x64}, {0x01, 0x65}, | 63 | {0xc7, 0x64}, {0x01, 0x65}, |
64 | {0x44, 0x66}, {0x00, 0x67}, | 64 | {0x44, 0x66}, {0x00, 0x67}, |
65 | {0x44, 0x68}, {0x00, 0x69}, | 65 | {0x44, 0x68}, {0x00, 0x69}, |
66 | {0x44, 0x6A}, {0x00, 0x6B}, | 66 | {0x44, 0x6a}, {0x00, 0x6b}, |
67 | {0xC7, 0x6C}, {0x01, 0x6D}, | 67 | {0xc7, 0x6c}, {0x01, 0x6d}, |
68 | {0xC7, 0x6E}, {0x01, 0x6F}, | 68 | {0xc7, 0x6e}, {0x01, 0x6f}, |
69 | {0xC7, 0x70}, {0x01, 0x71}, | 69 | {0xc7, 0x70}, {0x01, 0x71}, |
70 | {0x44, 0x72}, {0x00, 0x73}, | 70 | {0x44, 0x72}, {0x00, 0x73}, |
71 | {0x44, 0x74}, {0x00, 0x75}, | 71 | {0x44, 0x74}, {0x00, 0x75}, |
72 | {0x44, 0x76}, {0x00, 0x77}, | 72 | {0x44, 0x76}, {0x00, 0x77}, |
73 | {0xC7, 0x78}, {0x01, 0x79}, | 73 | {0xc7, 0x78}, {0x01, 0x79}, |
74 | {0xC7, 0x7A}, {0x01, 0x7B}, | 74 | {0xc7, 0x7a}, {0x01, 0x7b}, |
75 | {0xC7, 0x7C}, {0x01, 0x7D}, | 75 | {0xc7, 0x7c}, {0x01, 0x7d}, |
76 | {0x44, 0x7E}, {0x00, 0x7F}, | 76 | {0x44, 0x7e}, {0x00, 0x7f}, |
77 | {0x14, 0x84}, {0x00, 0x85}, | 77 | {0x14, 0x84}, {0x00, 0x85}, |
78 | {0x27, 0x86}, {0x00, 0x87}, | 78 | {0x27, 0x86}, {0x00, 0x87}, |
79 | {0x07, 0x88}, {0x00, 0x89}, | 79 | {0x07, 0x88}, {0x00, 0x89}, |
80 | {0xEC, 0x8A}, {0x0f, 0x8B}, | 80 | {0xec, 0x8a}, {0x0f, 0x8b}, |
81 | {0xD8, 0x8C}, {0x0f, 0x8D}, | 81 | {0xd8, 0x8c}, {0x0f, 0x8d}, |
82 | {0x3D, 0x8E}, {0x00, 0x8F}, | 82 | {0x3d, 0x8e}, {0x00, 0x8f}, |
83 | {0x3D, 0x90}, {0x00, 0x91}, | 83 | {0x3d, 0x90}, {0x00, 0x91}, |
84 | {0xCD, 0x92}, {0x0f, 0x93}, | 84 | {0xcd, 0x92}, {0x0f, 0x93}, |
85 | {0xf7, 0x94}, {0x0f, 0x95}, | 85 | {0xf7, 0x94}, {0x0f, 0x95}, |
86 | {0x0C, 0x96}, {0x00, 0x97}, | 86 | {0x0c, 0x96}, {0x00, 0x97}, |
87 | {0x00, 0x98}, {0x66, 0x99}, | 87 | {0x00, 0x98}, {0x66, 0x99}, |
88 | {0x05, 0x9A}, {0x00, 0x9B}, | 88 | {0x05, 0x9a}, {0x00, 0x9b}, |
89 | {0x04, 0x9C}, {0x00, 0x9D}, | 89 | {0x04, 0x9c}, {0x00, 0x9d}, |
90 | {0x08, 0x9E}, {0x00, 0x9F}, | 90 | {0x08, 0x9e}, {0x00, 0x9f}, |
91 | {0x2D, 0xC0}, {0x2D, 0xC1}, | 91 | {0x2d, 0xc0}, {0x2d, 0xc1}, |
92 | {0x3A, 0xC2}, {0x05, 0xC3}, | 92 | {0x3a, 0xc2}, {0x05, 0xc3}, |
93 | {0x04, 0xC4}, {0x3F, 0xC5}, | 93 | {0x04, 0xc4}, {0x3f, 0xc5}, |
94 | {0x00, 0xC6}, {0x00, 0xC7}, | 94 | {0x00, 0xc6}, {0x00, 0xc7}, |
95 | {0x50, 0xC8}, {0x3C, 0xC9}, | 95 | {0x50, 0xc8}, {0x3C, 0xc9}, |
96 | {0x28, 0xCA}, {0xD8, 0xCB}, | 96 | {0x28, 0xca}, {0xd8, 0xcb}, |
97 | {0x14, 0xCC}, {0xEC, 0xCD}, | 97 | {0x14, 0xcc}, {0xec, 0xcd}, |
98 | {0x32, 0xCE}, {0xDD, 0xCF}, | 98 | {0x32, 0xce}, {0xdd, 0xcf}, |
99 | {0x32, 0xD0}, {0xDD, 0xD1}, | 99 | {0x32, 0xd0}, {0xdd, 0xd1}, |
100 | {0x6A, 0xD2}, {0x50, 0xD3}, | 100 | {0x6a, 0xd2}, {0x50, 0xd3}, |
101 | {0x00, 0xD4}, {0x00, 0xD5}, | 101 | {0x00, 0xd4}, {0x00, 0xd5}, |
102 | {0x00, 0xD6}); | 102 | {0x00, 0xd6}); |
103 | 103 | ||
104 | err += sn9c102_i2c_write(cam, 0x12, 0x80); | 104 | err += sn9c102_i2c_write(cam, 0x12, 0x80); |
105 | err += sn9c102_i2c_write(cam, 0x11, 0x09); | 105 | err += sn9c102_i2c_write(cam, 0x11, 0x09); |
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 3e736be5de84..eb220461ac77 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
@@ -1321,7 +1321,7 @@ static int saa_ioctl(struct inode *inode, struct file *file, | |||
1321 | u32 format; | 1321 | u32 format; |
1322 | if (copy_from_user(&p, arg, sizeof(p))) | 1322 | if (copy_from_user(&p, arg, sizeof(p))) |
1323 | return -EFAULT; | 1323 | return -EFAULT; |
1324 | if (p.palette < sizeof(palette2fmt) / sizeof(u32)) { | 1324 | if (p.palette < ARRAY_SIZE(palette2fmt)) { |
1325 | format = palette2fmt[p.palette]; | 1325 | format = palette2fmt[p.palette]; |
1326 | saa->win.color_fmt = format; | 1326 | saa->win.color_fmt = format; |
1327 | saawrite(format | 0x60, | 1327 | saawrite(format | 0x60, |
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index bf3aa8d2d57e..4dc5bc714b95 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c | |||
@@ -715,8 +715,11 @@ static int stv680_start_stream (struct usb_stv *stv680) | |||
715 | stv680_video_irq, stv680); | 715 | stv680_video_irq, stv680); |
716 | stv680->urb[i] = urb; | 716 | stv680->urb[i] = urb; |
717 | err = usb_submit_urb (stv680->urb[i], GFP_KERNEL); | 717 | err = usb_submit_urb (stv680->urb[i], GFP_KERNEL); |
718 | if (err) | 718 | if (err) { |
719 | PDEBUG (0, "STV(e): urb burned down in start stream"); | 719 | PDEBUG (0, "STV(e): urb burned down with err " |
720 | "%d in start stream %d", err, i); | ||
721 | goto nomem_err; | ||
722 | } | ||
720 | } /* i STV680_NUMSBUF */ | 723 | } /* i STV680_NUMSBUF */ |
721 | 724 | ||
722 | stv680->framecount = 0; | 725 | stv680->framecount = 0; |
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index 1a1bef0e9c3d..59cff5a3c59e 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c | |||
@@ -21,7 +21,17 @@ | |||
21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/videodev.h> | 22 | #include <linux/videodev.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <media/tuner.h> | 24 | #include "tuner-driver.h" |
25 | |||
26 | /* ---------------------------------------------------------------------- */ | ||
27 | |||
28 | struct tda8290_priv { | ||
29 | unsigned char tda8290_easy_mode; | ||
30 | unsigned char tda827x_lpsel; | ||
31 | unsigned char tda827x_addr; | ||
32 | unsigned char tda827x_ver; | ||
33 | unsigned int sgIF; | ||
34 | }; | ||
25 | 35 | ||
26 | /* ---------------------------------------------------------------------- */ | 36 | /* ---------------------------------------------------------------------- */ |
27 | 37 | ||
@@ -76,7 +86,8 @@ static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
76 | u32 N; | 86 | u32 N; |
77 | int i; | 87 | int i; |
78 | struct tuner *t = i2c_get_clientdata(c); | 88 | struct tuner *t = i2c_get_clientdata(c); |
79 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0}; | 89 | struct tda8290_priv *priv = t->priv; |
90 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags = 0}; | ||
80 | 91 | ||
81 | if (t->mode == V4L2_TUNER_RADIO) | 92 | if (t->mode == V4L2_TUNER_RADIO) |
82 | freq = freq / 1000; | 93 | freq = freq / 1000; |
@@ -95,7 +106,7 @@ static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
95 | tuner_reg[1] = (unsigned char)(N>>8); | 106 | tuner_reg[1] = (unsigned char)(N>>8); |
96 | tuner_reg[2] = (unsigned char) N; | 107 | tuner_reg[2] = (unsigned char) N; |
97 | tuner_reg[3] = 0x40; | 108 | tuner_reg[3] = 0x40; |
98 | tuner_reg[4] = 0x52 + (t->tda827x_lpsel << 5); | 109 | tuner_reg[4] = 0x52 + (priv->tda827x_lpsel << 5); |
99 | tuner_reg[5] = (tda827x_analog[i].spd << 6) + (tda827x_analog[i].div1p5 <<5) + | 110 | tuner_reg[5] = (tda827x_analog[i].spd << 6) + (tda827x_analog[i].div1p5 <<5) + |
100 | (tda827x_analog[i].bs <<3) + tda827x_analog[i].bp; | 111 | (tda827x_analog[i].bs <<3) + tda827x_analog[i].bp; |
101 | tuner_reg[6] = 0x8f + (tda827x_analog[i].gc3 << 4); | 112 | tuner_reg[6] = 0x8f + (tda827x_analog[i].gc3 << 4); |
@@ -146,8 +157,9 @@ static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
146 | static void tda827x_agcf(struct i2c_client *c) | 157 | static void tda827x_agcf(struct i2c_client *c) |
147 | { | 158 | { |
148 | struct tuner *t = i2c_get_clientdata(c); | 159 | struct tuner *t = i2c_get_clientdata(c); |
160 | struct tda8290_priv *priv = t->priv; | ||
149 | unsigned char data[] = {0x80, 0x0c}; | 161 | unsigned char data[] = {0x80, 0x0c}; |
150 | struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data, | 162 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .buf = data, |
151 | .flags = 0, .len = 2}; | 163 | .flags = 0, .len = 2}; |
152 | i2c_transfer(c->adapter, &msg, 1); | 164 | i2c_transfer(c->adapter, &msg, 1); |
153 | } | 165 | } |
@@ -234,7 +246,8 @@ static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
234 | u32 N; | 246 | u32 N; |
235 | int i; | 247 | int i; |
236 | struct tuner *t = i2c_get_clientdata(c); | 248 | struct tuner *t = i2c_get_clientdata(c); |
237 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0, .buf = tuner_reg}; | 249 | struct tda8290_priv *priv = t->priv; |
250 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags = 0, .buf = tuner_reg}; | ||
238 | 251 | ||
239 | tda827xa_lna_gain( c, 1); | 252 | tda827xa_lna_gain( c, 1); |
240 | msleep(10); | 253 | msleep(10); |
@@ -271,7 +284,7 @@ static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
271 | tuner_reg[1] = 0xff; | 284 | tuner_reg[1] = 0xff; |
272 | tuner_reg[2] = 0xe0; | 285 | tuner_reg[2] = 0xe0; |
273 | tuner_reg[3] = 0; | 286 | tuner_reg[3] = 0; |
274 | tuner_reg[4] = 0x99 + (t->tda827x_lpsel << 1); | 287 | tuner_reg[4] = 0x99 + (priv->tda827x_lpsel << 1); |
275 | msg.len = 5; | 288 | msg.len = 5; |
276 | i2c_transfer(c->adapter, &msg, 1); | 289 | i2c_transfer(c->adapter, &msg, 1); |
277 | 290 | ||
@@ -311,15 +324,16 @@ static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
311 | i2c_transfer(c->adapter, &msg, 1); | 324 | i2c_transfer(c->adapter, &msg, 1); |
312 | 325 | ||
313 | tuner_reg[0] = 0xc0; | 326 | tuner_reg[0] = 0xc0; |
314 | tuner_reg[1] = 0x19 + (t->tda827x_lpsel << 1); | 327 | tuner_reg[1] = 0x19 + (priv->tda827x_lpsel << 1); |
315 | i2c_transfer(c->adapter, &msg, 1); | 328 | i2c_transfer(c->adapter, &msg, 1); |
316 | } | 329 | } |
317 | 330 | ||
318 | static void tda827xa_agcf(struct i2c_client *c) | 331 | static void tda827xa_agcf(struct i2c_client *c) |
319 | { | 332 | { |
320 | struct tuner *t = i2c_get_clientdata(c); | 333 | struct tuner *t = i2c_get_clientdata(c); |
334 | struct tda8290_priv *priv = t->priv; | ||
321 | unsigned char data[] = {0x80, 0x2c}; | 335 | unsigned char data[] = {0x80, 0x2c}; |
322 | struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data, | 336 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .buf = data, |
323 | .flags = 0, .len = 2}; | 337 | .flags = 0, .len = 2}; |
324 | i2c_transfer(c->adapter, &msg, 1); | 338 | i2c_transfer(c->adapter, &msg, 1); |
325 | } | 339 | } |
@@ -347,8 +361,9 @@ static void tda8290_i2c_bridge(struct i2c_client *c, int close) | |||
347 | static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | 361 | static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) |
348 | { | 362 | { |
349 | struct tuner *t = i2c_get_clientdata(c); | 363 | struct tuner *t = i2c_get_clientdata(c); |
364 | struct tda8290_priv *priv = t->priv; | ||
350 | unsigned char soft_reset[] = { 0x00, 0x00 }; | 365 | unsigned char soft_reset[] = { 0x00, 0x00 }; |
351 | unsigned char easy_mode[] = { 0x01, t->tda8290_easy_mode }; | 366 | unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode }; |
352 | unsigned char expert_mode[] = { 0x01, 0x80 }; | 367 | unsigned char expert_mode[] = { 0x01, 0x80 }; |
353 | unsigned char agc_out_on[] = { 0x02, 0x00 }; | 368 | unsigned char agc_out_on[] = { 0x02, 0x00 }; |
354 | unsigned char gainset_off[] = { 0x28, 0x14 }; | 369 | unsigned char gainset_off[] = { 0x28, 0x14 }; |
@@ -375,18 +390,18 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
375 | i2c_master_send(c, soft_reset, 2); | 390 | i2c_master_send(c, soft_reset, 2); |
376 | msleep(1); | 391 | msleep(1); |
377 | 392 | ||
378 | expert_mode[1] = t->tda8290_easy_mode + 0x80; | 393 | expert_mode[1] = priv->tda8290_easy_mode + 0x80; |
379 | i2c_master_send(c, expert_mode, 2); | 394 | i2c_master_send(c, expert_mode, 2); |
380 | i2c_master_send(c, gainset_off, 2); | 395 | i2c_master_send(c, gainset_off, 2); |
381 | i2c_master_send(c, if_agc_spd, 2); | 396 | i2c_master_send(c, if_agc_spd, 2); |
382 | if (t->tda8290_easy_mode & 0x60) | 397 | if (priv->tda8290_easy_mode & 0x60) |
383 | i2c_master_send(c, adc_head_9, 2); | 398 | i2c_master_send(c, adc_head_9, 2); |
384 | else | 399 | else |
385 | i2c_master_send(c, adc_head_6, 2); | 400 | i2c_master_send(c, adc_head_6, 2); |
386 | i2c_master_send(c, pll_bw_nom, 2); | 401 | i2c_master_send(c, pll_bw_nom, 2); |
387 | 402 | ||
388 | tda8290_i2c_bridge(c, 1); | 403 | tda8290_i2c_bridge(c, 1); |
389 | if (t->tda827x_ver != 0) | 404 | if (priv->tda827x_ver != 0) |
390 | tda827xa_tune(c, ifc, freq); | 405 | tda827xa_tune(c, ifc, freq); |
391 | else | 406 | else |
392 | tda827x_tune(c, ifc, freq); | 407 | tda827x_tune(c, ifc, freq); |
@@ -418,7 +433,7 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
418 | if ((agc_stat > 115) || !(pll_stat & 0x80)) { | 433 | if ((agc_stat > 115) || !(pll_stat & 0x80)) { |
419 | tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", | 434 | tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", |
420 | agc_stat, pll_stat & 0x80); | 435 | agc_stat, pll_stat & 0x80); |
421 | if (t->tda827x_ver != 0) | 436 | if (priv->tda827x_ver != 0) |
422 | tda827xa_agcf(c); | 437 | tda827xa_agcf(c); |
423 | else | 438 | else |
424 | tda827x_agcf(c); | 439 | tda827x_agcf(c); |
@@ -437,7 +452,7 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
437 | } | 452 | } |
438 | 453 | ||
439 | /* l/ l' deadlock? */ | 454 | /* l/ l' deadlock? */ |
440 | if(t->tda8290_easy_mode & 0x60) { | 455 | if(priv->tda8290_easy_mode & 0x60) { |
441 | i2c_master_send(c, &addr_adc_sat, 1); | 456 | i2c_master_send(c, &addr_adc_sat, 1); |
442 | i2c_master_recv(c, &adc_sat, 1); | 457 | i2c_master_recv(c, &adc_sat, 1); |
443 | i2c_master_send(c, &addr_pll_stat, 1); | 458 | i2c_master_send(c, &addr_pll_stat, 1); |
@@ -459,41 +474,42 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | |||
459 | 474 | ||
460 | static void set_audio(struct tuner *t) | 475 | static void set_audio(struct tuner *t) |
461 | { | 476 | { |
477 | struct tda8290_priv *priv = t->priv; | ||
462 | char* mode; | 478 | char* mode; |
463 | 479 | ||
464 | t->tda827x_lpsel = 0; | 480 | priv->tda827x_lpsel = 0; |
465 | if (t->std & V4L2_STD_MN) { | 481 | if (t->std & V4L2_STD_MN) { |
466 | t->sgIF = 92; | 482 | priv->sgIF = 92; |
467 | t->tda8290_easy_mode = 0x01; | 483 | priv->tda8290_easy_mode = 0x01; |
468 | t->tda827x_lpsel = 1; | 484 | priv->tda827x_lpsel = 1; |
469 | mode = "MN"; | 485 | mode = "MN"; |
470 | } else if (t->std & V4L2_STD_B) { | 486 | } else if (t->std & V4L2_STD_B) { |
471 | t->sgIF = 108; | 487 | priv->sgIF = 108; |
472 | t->tda8290_easy_mode = 0x02; | 488 | priv->tda8290_easy_mode = 0x02; |
473 | mode = "B"; | 489 | mode = "B"; |
474 | } else if (t->std & V4L2_STD_GH) { | 490 | } else if (t->std & V4L2_STD_GH) { |
475 | t->sgIF = 124; | 491 | priv->sgIF = 124; |
476 | t->tda8290_easy_mode = 0x04; | 492 | priv->tda8290_easy_mode = 0x04; |
477 | mode = "GH"; | 493 | mode = "GH"; |
478 | } else if (t->std & V4L2_STD_PAL_I) { | 494 | } else if (t->std & V4L2_STD_PAL_I) { |
479 | t->sgIF = 124; | 495 | priv->sgIF = 124; |
480 | t->tda8290_easy_mode = 0x08; | 496 | priv->tda8290_easy_mode = 0x08; |
481 | mode = "I"; | 497 | mode = "I"; |
482 | } else if (t->std & V4L2_STD_DK) { | 498 | } else if (t->std & V4L2_STD_DK) { |
483 | t->sgIF = 124; | 499 | priv->sgIF = 124; |
484 | t->tda8290_easy_mode = 0x10; | 500 | priv->tda8290_easy_mode = 0x10; |
485 | mode = "DK"; | 501 | mode = "DK"; |
486 | } else if (t->std & V4L2_STD_SECAM_L) { | 502 | } else if (t->std & V4L2_STD_SECAM_L) { |
487 | t->sgIF = 124; | 503 | priv->sgIF = 124; |
488 | t->tda8290_easy_mode = 0x20; | 504 | priv->tda8290_easy_mode = 0x20; |
489 | mode = "L"; | 505 | mode = "L"; |
490 | } else if (t->std & V4L2_STD_SECAM_LC) { | 506 | } else if (t->std & V4L2_STD_SECAM_LC) { |
491 | t->sgIF = 20; | 507 | priv->sgIF = 20; |
492 | t->tda8290_easy_mode = 0x40; | 508 | priv->tda8290_easy_mode = 0x40; |
493 | mode = "LC"; | 509 | mode = "LC"; |
494 | } else { | 510 | } else { |
495 | t->sgIF = 124; | 511 | priv->sgIF = 124; |
496 | t->tda8290_easy_mode = 0x10; | 512 | priv->tda8290_easy_mode = 0x10; |
497 | mode = "xx"; | 513 | mode = "xx"; |
498 | } | 514 | } |
499 | tuner_dbg("setting tda8290 to system %s\n", mode); | 515 | tuner_dbg("setting tda8290 to system %s\n", mode); |
@@ -502,9 +518,10 @@ static void set_audio(struct tuner *t) | |||
502 | static void set_tv_freq(struct i2c_client *c, unsigned int freq) | 518 | static void set_tv_freq(struct i2c_client *c, unsigned int freq) |
503 | { | 519 | { |
504 | struct tuner *t = i2c_get_clientdata(c); | 520 | struct tuner *t = i2c_get_clientdata(c); |
521 | struct tda8290_priv *priv = t->priv; | ||
505 | 522 | ||
506 | set_audio(t); | 523 | set_audio(t); |
507 | tda8290_tune(c, t->sgIF, freq); | 524 | tda8290_tune(c, priv->sgIF, freq); |
508 | } | 525 | } |
509 | 526 | ||
510 | static void set_radio_freq(struct i2c_client *c, unsigned int freq) | 527 | static void set_radio_freq(struct i2c_client *c, unsigned int freq) |
@@ -528,13 +545,14 @@ static int has_signal(struct i2c_client *c) | |||
528 | static void standby(struct i2c_client *c) | 545 | static void standby(struct i2c_client *c) |
529 | { | 546 | { |
530 | struct tuner *t = i2c_get_clientdata(c); | 547 | struct tuner *t = i2c_get_clientdata(c); |
548 | struct tda8290_priv *priv = t->priv; | ||
531 | unsigned char cb1[] = { 0x30, 0xD0 }; | 549 | unsigned char cb1[] = { 0x30, 0xD0 }; |
532 | unsigned char tda8290_standby[] = { 0x00, 0x02 }; | 550 | unsigned char tda8290_standby[] = { 0x00, 0x02 }; |
533 | unsigned char tda8290_agc_tri[] = { 0x02, 0x20 }; | 551 | unsigned char tda8290_agc_tri[] = { 0x02, 0x20 }; |
534 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; | 552 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; |
535 | 553 | ||
536 | tda8290_i2c_bridge(c, 1); | 554 | tda8290_i2c_bridge(c, 1); |
537 | if (t->tda827x_ver != 0) | 555 | if (priv->tda827x_ver != 0) |
538 | cb1[1] = 0x90; | 556 | cb1[1] = 0x90; |
539 | i2c_transfer(c->adapter, &msg, 1); | 557 | i2c_transfer(c->adapter, &msg, 1); |
540 | tda8290_i2c_bridge(c, 0); | 558 | tda8290_i2c_bridge(c, 0); |
@@ -560,13 +578,14 @@ static void tda8290_init_if(struct i2c_client *c) | |||
560 | static void tda8290_init_tuner(struct i2c_client *c) | 578 | static void tda8290_init_tuner(struct i2c_client *c) |
561 | { | 579 | { |
562 | struct tuner *t = i2c_get_clientdata(c); | 580 | struct tuner *t = i2c_get_clientdata(c); |
581 | struct tda8290_priv *priv = t->priv; | ||
563 | unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf, | 582 | unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf, |
564 | 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; | 583 | 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; |
565 | unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b, | 584 | unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b, |
566 | 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b }; | 585 | 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b }; |
567 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, | 586 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, |
568 | .buf=tda8275_init, .len = 14}; | 587 | .buf=tda8275_init, .len = 14}; |
569 | if (t->tda827x_ver != 0) | 588 | if (priv->tda827x_ver != 0) |
570 | msg.buf = tda8275a_init; | 589 | msg.buf = tda8275a_init; |
571 | 590 | ||
572 | tda8290_i2c_bridge(c, 1); | 591 | tda8290_i2c_bridge(c, 1); |
@@ -576,14 +595,36 @@ static void tda8290_init_tuner(struct i2c_client *c) | |||
576 | 595 | ||
577 | /*---------------------------------------------------------------------*/ | 596 | /*---------------------------------------------------------------------*/ |
578 | 597 | ||
598 | static void tda8290_release(struct i2c_client *c) | ||
599 | { | ||
600 | struct tuner *t = i2c_get_clientdata(c); | ||
601 | |||
602 | kfree(t->priv); | ||
603 | t->priv = NULL; | ||
604 | } | ||
605 | |||
606 | static struct tuner_operations tda8290_tuner_ops = { | ||
607 | .set_tv_freq = set_tv_freq, | ||
608 | .set_radio_freq = set_radio_freq, | ||
609 | .has_signal = has_signal, | ||
610 | .standby = standby, | ||
611 | .release = tda8290_release, | ||
612 | }; | ||
613 | |||
579 | int tda8290_init(struct i2c_client *c) | 614 | int tda8290_init(struct i2c_client *c) |
580 | { | 615 | { |
616 | struct tda8290_priv *priv = NULL; | ||
581 | struct tuner *t = i2c_get_clientdata(c); | 617 | struct tuner *t = i2c_get_clientdata(c); |
582 | u8 data; | 618 | u8 data; |
583 | int i, ret, tuners_found; | 619 | int i, ret, tuners_found; |
584 | u32 tuner_addrs; | 620 | u32 tuner_addrs; |
585 | struct i2c_msg msg = {.flags=I2C_M_RD, .buf=&data, .len = 1}; | 621 | struct i2c_msg msg = {.flags=I2C_M_RD, .buf=&data, .len = 1}; |
586 | 622 | ||
623 | priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL); | ||
624 | if (priv == NULL) | ||
625 | return -ENOMEM; | ||
626 | t->priv = priv; | ||
627 | |||
587 | tda8290_i2c_bridge(c, 1); | 628 | tda8290_i2c_bridge(c, 1); |
588 | /* probe for tuner chip */ | 629 | /* probe for tuner chip */ |
589 | tuners_found = 0; | 630 | tuners_found = 0; |
@@ -618,7 +659,7 @@ int tda8290_init(struct i2c_client *c) | |||
618 | tuner_addrs = tuner_addrs & 0xff; | 659 | tuner_addrs = tuner_addrs & 0xff; |
619 | tuner_info ("setting tuner address to %x\n", tuner_addrs); | 660 | tuner_info ("setting tuner address to %x\n", tuner_addrs); |
620 | } | 661 | } |
621 | t->tda827x_addr = tuner_addrs; | 662 | priv->tda827x_addr = tuner_addrs; |
622 | msg.addr = tuner_addrs; | 663 | msg.addr = tuner_addrs; |
623 | 664 | ||
624 | tda8290_i2c_bridge(c, 1); | 665 | tda8290_i2c_bridge(c, 1); |
@@ -627,18 +668,16 @@ int tda8290_init(struct i2c_client *c) | |||
627 | tuner_warn ("TDA827x access failed!\n"); | 668 | tuner_warn ("TDA827x access failed!\n"); |
628 | if ((data & 0x3c) == 0) { | 669 | if ((data & 0x3c) == 0) { |
629 | strlcpy(c->name, "tda8290+75", sizeof(c->name)); | 670 | strlcpy(c->name, "tda8290+75", sizeof(c->name)); |
630 | t->tda827x_ver = 0; | 671 | priv->tda827x_ver = 0; |
631 | } else { | 672 | } else { |
632 | strlcpy(c->name, "tda8290+75a", sizeof(c->name)); | 673 | strlcpy(c->name, "tda8290+75a", sizeof(c->name)); |
633 | t->tda827x_ver = 2; | 674 | priv->tda827x_ver = 2; |
634 | } | 675 | } |
635 | tuner_info("type set to %s\n", c->name); | 676 | tuner_info("type set to %s\n", c->name); |
636 | 677 | ||
637 | t->set_tv_freq = set_tv_freq; | 678 | memcpy(&t->ops, &tda8290_tuner_ops, sizeof(struct tuner_operations)); |
638 | t->set_radio_freq = set_radio_freq; | 679 | |
639 | t->has_signal = has_signal; | 680 | priv->tda827x_lpsel = 0; |
640 | t->standby = standby; | ||
641 | t->tda827x_lpsel = 0; | ||
642 | t->mode = V4L2_TUNER_ANALOG_TV; | 681 | t->mode = V4L2_TUNER_ANALOG_TV; |
643 | 682 | ||
644 | tda8290_init_tuner(c); | 683 | tda8290_init_tuner(c); |
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index fde576f1101c..a8f773274fe3 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <media/v4l2-common.h> | 12 | #include <media/v4l2-common.h> |
13 | #include <media/tuner.h> | 13 | #include <media/tuner.h> |
14 | #include "tuner-driver.h" | ||
14 | 15 | ||
15 | 16 | ||
16 | /* Chips: | 17 | /* Chips: |
@@ -29,6 +30,9 @@ | |||
29 | printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \ | 30 | printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \ |
30 | i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) | 31 | i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) |
31 | 32 | ||
33 | struct tda9887_priv { | ||
34 | unsigned char data[4]; | ||
35 | }; | ||
32 | 36 | ||
33 | /* ---------------------------------------------------------------------- */ | 37 | /* ---------------------------------------------------------------------- */ |
34 | 38 | ||
@@ -508,10 +512,11 @@ static int tda9887_status(struct tuner *t) | |||
508 | static void tda9887_configure(struct i2c_client *client) | 512 | static void tda9887_configure(struct i2c_client *client) |
509 | { | 513 | { |
510 | struct tuner *t = i2c_get_clientdata(client); | 514 | struct tuner *t = i2c_get_clientdata(client); |
515 | struct tda9887_priv *priv = t->priv; | ||
511 | int rc; | 516 | int rc; |
512 | 517 | ||
513 | memset(t->tda9887_data,0,sizeof(t->tda9887_data)); | 518 | memset(priv->data,0,sizeof(priv->data)); |
514 | tda9887_set_tvnorm(t,t->tda9887_data); | 519 | tda9887_set_tvnorm(t,priv->data); |
515 | 520 | ||
516 | /* A note on the port settings: | 521 | /* A note on the port settings: |
517 | These settings tend to depend on the specifics of the board. | 522 | These settings tend to depend on the specifics of the board. |
@@ -526,22 +531,22 @@ static void tda9887_configure(struct i2c_client *client) | |||
526 | the ports should be set to active (0), but, again, that may | 531 | the ports should be set to active (0), but, again, that may |
527 | differ depending on the precise hardware configuration. | 532 | differ depending on the precise hardware configuration. |
528 | */ | 533 | */ |
529 | t->tda9887_data[1] |= cOutputPort1Inactive; | 534 | priv->data[1] |= cOutputPort1Inactive; |
530 | t->tda9887_data[1] |= cOutputPort2Inactive; | 535 | priv->data[1] |= cOutputPort2Inactive; |
531 | 536 | ||
532 | tda9887_set_config(t,t->tda9887_data); | 537 | tda9887_set_config(t,priv->data); |
533 | tda9887_set_insmod(t,t->tda9887_data); | 538 | tda9887_set_insmod(t,priv->data); |
534 | 539 | ||
535 | if (t->mode == T_STANDBY) { | 540 | if (t->mode == T_STANDBY) { |
536 | t->tda9887_data[1] |= cForcedMuteAudioON; | 541 | priv->data[1] |= cForcedMuteAudioON; |
537 | } | 542 | } |
538 | 543 | ||
539 | tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", | 544 | tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", |
540 | t->tda9887_data[1],t->tda9887_data[2],t->tda9887_data[3]); | 545 | priv->data[1],priv->data[2],priv->data[3]); |
541 | if (tuner_debug > 1) | 546 | if (tuner_debug > 1) |
542 | dump_write_message(t, t->tda9887_data); | 547 | dump_write_message(t, priv->data); |
543 | 548 | ||
544 | if (4 != (rc = i2c_master_send(&t->i2c,t->tda9887_data,4))) | 549 | if (4 != (rc = i2c_master_send(&t->i2c,priv->data,4))) |
545 | tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc); | 550 | tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc); |
546 | 551 | ||
547 | if (tuner_debug > 2) { | 552 | if (tuner_debug > 2) { |
@@ -555,7 +560,8 @@ static void tda9887_configure(struct i2c_client *client) | |||
555 | static void tda9887_tuner_status(struct i2c_client *client) | 560 | static void tda9887_tuner_status(struct i2c_client *client) |
556 | { | 561 | { |
557 | struct tuner *t = i2c_get_clientdata(client); | 562 | struct tuner *t = i2c_get_clientdata(client); |
558 | tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->tda9887_data[1], t->tda9887_data[2], t->tda9887_data[3]); | 563 | struct tda9887_priv *priv = t->priv; |
564 | tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", priv->data[1], priv->data[2], priv->data[3]); | ||
559 | } | 565 | } |
560 | 566 | ||
561 | static int tda9887_get_afc(struct i2c_client *client) | 567 | static int tda9887_get_afc(struct i2c_client *client) |
@@ -586,20 +592,39 @@ static void tda9887_set_freq(struct i2c_client *client, unsigned int freq) | |||
586 | tda9887_configure(client); | 592 | tda9887_configure(client); |
587 | } | 593 | } |
588 | 594 | ||
595 | static void tda9887_release(struct i2c_client *c) | ||
596 | { | ||
597 | struct tuner *t = i2c_get_clientdata(c); | ||
598 | |||
599 | kfree(t->priv); | ||
600 | t->priv = NULL; | ||
601 | } | ||
602 | |||
603 | static struct tuner_operations tda9887_tuner_ops = { | ||
604 | .set_tv_freq = tda9887_set_freq, | ||
605 | .set_radio_freq = tda9887_set_freq, | ||
606 | .standby = tda9887_standby, | ||
607 | .tuner_status = tda9887_tuner_status, | ||
608 | .get_afc = tda9887_get_afc, | ||
609 | .release = tda9887_release, | ||
610 | }; | ||
611 | |||
589 | int tda9887_tuner_init(struct i2c_client *c) | 612 | int tda9887_tuner_init(struct i2c_client *c) |
590 | { | 613 | { |
614 | struct tda9887_priv *priv = NULL; | ||
591 | struct tuner *t = i2c_get_clientdata(c); | 615 | struct tuner *t = i2c_get_clientdata(c); |
592 | 616 | ||
617 | priv = kzalloc(sizeof(struct tda9887_priv), GFP_KERNEL); | ||
618 | if (priv == NULL) | ||
619 | return -ENOMEM; | ||
620 | t->priv = priv; | ||
621 | |||
593 | strlcpy(c->name, "tda9887", sizeof(c->name)); | 622 | strlcpy(c->name, "tda9887", sizeof(c->name)); |
594 | 623 | ||
595 | tda9887_info("tda988[5/6/7] found @ 0x%x (%s)\n", t->i2c.addr, | 624 | tda9887_info("tda988[5/6/7] found @ 0x%x (%s)\n", t->i2c.addr, |
596 | t->i2c.driver->driver.name); | 625 | t->i2c.driver->driver.name); |
597 | 626 | ||
598 | t->set_tv_freq = tda9887_set_freq; | 627 | memcpy(&t->ops, &tda9887_tuner_ops, sizeof(struct tuner_operations)); |
599 | t->set_radio_freq = tda9887_set_freq; | ||
600 | t->standby = tda9887_standby; | ||
601 | t->tuner_status = tda9887_tuner_status; | ||
602 | t->get_afc = tda9887_get_afc; | ||
603 | 628 | ||
604 | return 0; | 629 | return 0; |
605 | } | 630 | } |
diff --git a/drivers/media/video/tea5761.c b/drivers/media/video/tea5761.c new file mode 100644 index 000000000000..ae105c2cd0ac --- /dev/null +++ b/drivers/media/video/tea5761.c | |||
@@ -0,0 +1,243 @@ | |||
1 | /* | ||
2 | * For Philips TEA5761 FM Chip | ||
3 | * I2C address is allways 0x20 (0x10 at 7-bit mode). | ||
4 | * | ||
5 | * Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org) | ||
6 | * This code is placed under the terms of the GNUv2 General Public License | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/i2c.h> | ||
11 | #include <linux/videodev.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <media/tuner.h> | ||
14 | #include "tuner-driver.h" | ||
15 | |||
16 | #define PREFIX "TEA5761 " | ||
17 | |||
18 | /* from tuner-core.c */ | ||
19 | extern int tuner_debug; | ||
20 | |||
21 | /*****************************************************************************/ | ||
22 | |||
23 | /*************************** | ||
24 | * TEA5761HN I2C registers * | ||
25 | ***************************/ | ||
26 | |||
27 | /* INTREG - Read: bytes 0 and 1 / Write: byte 0 */ | ||
28 | |||
29 | /* first byte for reading */ | ||
30 | #define TEA5761_INTREG_IFFLAG 0x10 | ||
31 | #define TEA5761_INTREG_LEVFLAG 0x8 | ||
32 | #define TEA5761_INTREG_FRRFLAG 0x2 | ||
33 | #define TEA5761_INTREG_BLFLAG 0x1 | ||
34 | |||
35 | /* second byte for reading / byte for writing */ | ||
36 | #define TEA5761_INTREG_IFMSK 0x10 | ||
37 | #define TEA5761_INTREG_LEVMSK 0x8 | ||
38 | #define TEA5761_INTREG_FRMSK 0x2 | ||
39 | #define TEA5761_INTREG_BLMSK 0x1 | ||
40 | |||
41 | /* FRQSET - Read: bytes 2 and 3 / Write: byte 1 and 2 */ | ||
42 | |||
43 | /* First byte */ | ||
44 | #define TEA5761_FRQSET_SEARCH_UP 0x80 /* 1=Station search from botton to up */ | ||
45 | #define TEA5761_FRQSET_SEARCH_MODE 0x40 /* 1=Search mode */ | ||
46 | |||
47 | /* Bits 0-5 for divider MSB */ | ||
48 | |||
49 | /* Second byte */ | ||
50 | /* Bits 0-7 for divider LSB */ | ||
51 | |||
52 | /* TNCTRL - Read: bytes 4 and 5 / Write: Bytes 3 and 4 */ | ||
53 | |||
54 | /* first byte */ | ||
55 | |||
56 | #define TEA5761_TNCTRL_PUPD_0 0x40 /* Power UP/Power Down MSB */ | ||
57 | #define TEA5761_TNCTRL_BLIM 0X20 /* 1= Japan Frequencies, 0= European frequencies */ | ||
58 | #define TEA5761_TNCTRL_SWPM 0x10 /* 1= software port is FRRFLAG */ | ||
59 | #define TEA5761_TNCTRL_IFCTC 0x08 /* 1= IF count time 15.02 ms, 0= IF count time 2.02 ms */ | ||
60 | #define TEA5761_TNCTRL_AFM 0x04 | ||
61 | #define TEA5761_TNCTRL_SMUTE 0x02 /* 1= Soft mute */ | ||
62 | #define TEA5761_TNCTRL_SNC 0x01 | ||
63 | |||
64 | /* second byte */ | ||
65 | |||
66 | #define TEA5761_TNCTRL_MU 0x80 /* 1=Hard mute */ | ||
67 | #define TEA5761_TNCTRL_SSL_1 0x40 | ||
68 | #define TEA5761_TNCTRL_SSL_0 0x20 | ||
69 | #define TEA5761_TNCTRL_HLSI 0x10 | ||
70 | #define TEA5761_TNCTRL_MST 0x08 /* 1 = mono */ | ||
71 | #define TEA5761_TNCTRL_SWP 0x04 | ||
72 | #define TEA5761_TNCTRL_DTC 0x02 /* 1 = deemphasis 50 us, 0 = deemphasis 75 us */ | ||
73 | #define TEA5761_TNCTRL_AHLSI 0x01 | ||
74 | |||
75 | /* FRQCHECK - Read: bytes 6 and 7 */ | ||
76 | /* First byte */ | ||
77 | |||
78 | /* Bits 0-5 for divider MSB */ | ||
79 | |||
80 | /* Second byte */ | ||
81 | /* Bits 0-7 for divider LSB */ | ||
82 | |||
83 | /* TUNCHECK - Read: bytes 8 and 9 */ | ||
84 | |||
85 | /* First byte */ | ||
86 | #define TEA5761_TUNCHECK_IF_MASK 0x7e /* IF count */ | ||
87 | #define TEA5761_TUNCHECK_TUNTO 0x01 | ||
88 | |||
89 | /* Second byte */ | ||
90 | #define TEA5761_TUNCHECK_LEV_MASK 0xf0 /* Level Count */ | ||
91 | #define TEA5761_TUNCHECK_LD 0x08 | ||
92 | #define TEA5761_TUNCHECK_STEREO 0x04 | ||
93 | |||
94 | /* TESTREG - Read: bytes 10 and 11 / Write: bytes 5 and 6 */ | ||
95 | |||
96 | /* All zero = no test mode */ | ||
97 | |||
98 | /* MANID - Read: bytes 12 and 13 */ | ||
99 | |||
100 | /* First byte - should be 0x10 */ | ||
101 | #define TEA5767_MANID_VERSION_MASK 0xf0 /* Version = 1 */ | ||
102 | #define TEA5767_MANID_ID_MSB_MASK 0x0f /* Manufacurer ID - should be 0 */ | ||
103 | |||
104 | /* Second byte - Should be 0x2b */ | ||
105 | |||
106 | #define TEA5767_MANID_ID_LSB_MASK 0xfe /* Manufacturer ID - should be 0x15 */ | ||
107 | #define TEA5767_MANID_IDAV 0x01 /* 1 = Chip has ID, 0 = Chip has no ID */ | ||
108 | |||
109 | /* Chip ID - Read: bytes 14 and 15 */ | ||
110 | |||
111 | /* First byte - should be 0x57 */ | ||
112 | |||
113 | /* Second byte - should be 0x61 */ | ||
114 | |||
115 | /*****************************************************************************/ | ||
116 | |||
117 | static void set_tv_freq(struct i2c_client *c, unsigned int freq) | ||
118 | { | ||
119 | struct tuner *t = i2c_get_clientdata(c); | ||
120 | |||
121 | tuner_warn("This tuner doesn't support TV freq.\n"); | ||
122 | } | ||
123 | |||
124 | #define FREQ_OFFSET 0 /* for TEA5767, it is 700 to give the right freq */ | ||
125 | static void tea5761_status_dump(unsigned char *buffer) | ||
126 | { | ||
127 | unsigned int div, frq; | ||
128 | |||
129 | div = ((buffer[2] & 0x3f) << 8) | buffer[3]; | ||
130 | |||
131 | frq = 1000 * (div * 32768 / 1000 + FREQ_OFFSET + 225) / 4; /* Freq in KHz */ | ||
132 | |||
133 | printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n", | ||
134 | frq / 1000, frq % 1000, div); | ||
135 | } | ||
136 | |||
137 | /* Freq should be specifyed at 62.5 Hz */ | ||
138 | static void set_radio_freq(struct i2c_client *c, unsigned int frq) | ||
139 | { | ||
140 | struct tuner *t = i2c_get_clientdata(c); | ||
141 | unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 }; | ||
142 | unsigned div; | ||
143 | int rc; | ||
144 | |||
145 | tuner_dbg (PREFIX "radio freq counter %d\n", frq); | ||
146 | |||
147 | if (t->mode == T_STANDBY) { | ||
148 | tuner_dbg("TEA5761 set to standby mode\n"); | ||
149 | buffer[5] |= TEA5761_TNCTRL_MU; | ||
150 | } else { | ||
151 | buffer[4] |= TEA5761_TNCTRL_PUPD_0; | ||
152 | } | ||
153 | |||
154 | |||
155 | if (t->audmode == V4L2_TUNER_MODE_MONO) { | ||
156 | tuner_dbg("TEA5761 set to mono\n"); | ||
157 | buffer[5] |= TEA5761_TNCTRL_MST; | ||
158 | ; | ||
159 | } else { | ||
160 | tuner_dbg("TEA5761 set to stereo\n"); | ||
161 | } | ||
162 | |||
163 | div = (1000 * (frq * 4 / 16 + 700 + 225) ) >> 15; | ||
164 | buffer[1] = (div >> 8) & 0x3f; | ||
165 | buffer[2] = div & 0xff; | ||
166 | |||
167 | if (tuner_debug) | ||
168 | tea5761_status_dump(buffer); | ||
169 | |||
170 | if (7 != (rc = i2c_master_send(c, buffer, 7))) | ||
171 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | ||
172 | } | ||
173 | |||
174 | static int tea5761_signal(struct i2c_client *c) | ||
175 | { | ||
176 | unsigned char buffer[16]; | ||
177 | int rc; | ||
178 | struct tuner *t = i2c_get_clientdata(c); | ||
179 | |||
180 | memset(buffer, 0, sizeof(buffer)); | ||
181 | if (16 != (rc = i2c_master_recv(c, buffer, 16))) | ||
182 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | ||
183 | |||
184 | return ((buffer[9] & TEA5761_TUNCHECK_LEV_MASK) << (13 - 4)); | ||
185 | } | ||
186 | |||
187 | static int tea5761_stereo(struct i2c_client *c) | ||
188 | { | ||
189 | unsigned char buffer[16]; | ||
190 | int rc; | ||
191 | struct tuner *t = i2c_get_clientdata(c); | ||
192 | |||
193 | memset(buffer, 0, sizeof(buffer)); | ||
194 | if (16 != (rc = i2c_master_recv(c, buffer, 16))) | ||
195 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | ||
196 | |||
197 | rc = buffer[9] & TEA5761_TUNCHECK_STEREO; | ||
198 | |||
199 | tuner_dbg("TEA5761 radio ST GET = %02x\n", rc); | ||
200 | |||
201 | return (rc ? V4L2_TUNER_SUB_STEREO : 0); | ||
202 | } | ||
203 | |||
204 | int tea5761_autodetection(struct i2c_client *c) | ||
205 | { | ||
206 | unsigned char buffer[16]; | ||
207 | int rc; | ||
208 | struct tuner *t = i2c_get_clientdata(c); | ||
209 | |||
210 | if (16 != (rc = i2c_master_recv(c, buffer, 16))) { | ||
211 | tuner_warn("it is not a TEA5761. Received %i chars.\n", rc); | ||
212 | return EINVAL; | ||
213 | } | ||
214 | |||
215 | if (!((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061))) { | ||
216 | tuner_warn("Manufacturer ID= 0x%02x, Chip ID = %02x%02x. It is not a TEA5761\n",buffer[13],buffer[14],buffer[15]); | ||
217 | return EINVAL; | ||
218 | } | ||
219 | tuner_warn("TEA5761 detected.\n"); | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static struct tuner_operations tea5761_tuner_ops = { | ||
224 | .set_tv_freq = set_tv_freq, | ||
225 | .set_radio_freq = set_radio_freq, | ||
226 | .has_signal = tea5761_signal, | ||
227 | .is_stereo = tea5761_stereo, | ||
228 | }; | ||
229 | |||
230 | int tea5761_tuner_init(struct i2c_client *c) | ||
231 | { | ||
232 | struct tuner *t = i2c_get_clientdata(c); | ||
233 | |||
234 | if (tea5761_autodetection(c) == EINVAL) | ||
235 | return EINVAL; | ||
236 | |||
237 | tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5761HN FM Radio"); | ||
238 | strlcpy(c->name, "tea5761", sizeof(c->name)); | ||
239 | |||
240 | memcpy(&t->ops, &tea5761_tuner_ops, sizeof(struct tuner_operations)); | ||
241 | |||
242 | return (0); | ||
243 | } | ||
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c index d1c41781ccc4..4985d47a508f 100644 --- a/drivers/media/video/tea5767.c +++ b/drivers/media/video/tea5767.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
14 | #include <linux/videodev.h> | 14 | #include <linux/videodev.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <media/tuner.h> | 16 | #include "tuner-driver.h" |
17 | 17 | ||
18 | #define PREFIX "TEA5767 " | 18 | #define PREFIX "TEA5767 " |
19 | 19 | ||
@@ -343,6 +343,14 @@ int tea5767_autodetection(struct i2c_client *c) | |||
343 | return 0; | 343 | return 0; |
344 | } | 344 | } |
345 | 345 | ||
346 | static struct tuner_operations tea5767_tuner_ops = { | ||
347 | .set_tv_freq = set_tv_freq, | ||
348 | .set_radio_freq = set_radio_freq, | ||
349 | .has_signal = tea5767_signal, | ||
350 | .is_stereo = tea5767_stereo, | ||
351 | .standby = tea5767_standby, | ||
352 | }; | ||
353 | |||
346 | int tea5767_tuner_init(struct i2c_client *c) | 354 | int tea5767_tuner_init(struct i2c_client *c) |
347 | { | 355 | { |
348 | struct tuner *t = i2c_get_clientdata(c); | 356 | struct tuner *t = i2c_get_clientdata(c); |
@@ -350,11 +358,7 @@ int tea5767_tuner_init(struct i2c_client *c) | |||
350 | tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio"); | 358 | tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio"); |
351 | strlcpy(c->name, "tea5767", sizeof(c->name)); | 359 | strlcpy(c->name, "tea5767", sizeof(c->name)); |
352 | 360 | ||
353 | t->set_tv_freq = set_tv_freq; | 361 | memcpy(&t->ops, &tea5767_tuner_ops, sizeof(struct tuner_operations)); |
354 | t->set_radio_freq = set_radio_freq; | ||
355 | t->has_signal = tea5767_signal; | ||
356 | t->is_stereo = tea5767_stereo; | ||
357 | t->standby = tea5767_standby; | ||
358 | 362 | ||
359 | return (0); | 363 | return (0); |
360 | } | 364 | } |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 505591a7abe9..e646465464a1 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -20,11 +20,15 @@ | |||
20 | 20 | ||
21 | #include <media/tuner.h> | 21 | #include <media/tuner.h> |
22 | #include <media/v4l2-common.h> | 22 | #include <media/v4l2-common.h> |
23 | #include "tuner-driver.h" | ||
23 | 24 | ||
24 | #define UNSET (-1U) | 25 | #define UNSET (-1U) |
25 | 26 | ||
26 | /* standard i2c insmod options */ | 27 | /* standard i2c insmod options */ |
27 | static unsigned short normal_i2c[] = { | 28 | static unsigned short normal_i2c[] = { |
29 | #ifdef CONFIG_TUNER_TEA5761 | ||
30 | 0x10, | ||
31 | #endif | ||
28 | 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ | 32 | 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ |
29 | 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, | 33 | 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, |
30 | 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, | 34 | 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, |
@@ -77,7 +81,7 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
77 | tuner_warn ("tuner type not set\n"); | 81 | tuner_warn ("tuner type not set\n"); |
78 | return; | 82 | return; |
79 | } | 83 | } |
80 | if (NULL == t->set_tv_freq) { | 84 | if (NULL == t->ops.set_tv_freq) { |
81 | tuner_warn ("Tuner has no way to set tv freq\n"); | 85 | tuner_warn ("Tuner has no way to set tv freq\n"); |
82 | return; | 86 | return; |
83 | } | 87 | } |
@@ -92,7 +96,7 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
92 | else | 96 | else |
93 | freq = tv_range[1] * 16; | 97 | freq = tv_range[1] * 16; |
94 | } | 98 | } |
95 | t->set_tv_freq(c, freq); | 99 | t->ops.set_tv_freq(c, freq); |
96 | } | 100 | } |
97 | 101 | ||
98 | static void set_radio_freq(struct i2c_client *c, unsigned int freq) | 102 | static void set_radio_freq(struct i2c_client *c, unsigned int freq) |
@@ -103,7 +107,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
103 | tuner_warn ("tuner type not set\n"); | 107 | tuner_warn ("tuner type not set\n"); |
104 | return; | 108 | return; |
105 | } | 109 | } |
106 | if (NULL == t->set_radio_freq) { | 110 | if (NULL == t->ops.set_radio_freq) { |
107 | tuner_warn ("tuner has no way to set radio frequency\n"); | 111 | tuner_warn ("tuner has no way to set radio frequency\n"); |
108 | return; | 112 | return; |
109 | } | 113 | } |
@@ -119,7 +123,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
119 | freq = radio_range[1] * 16000; | 123 | freq = radio_range[1] * 16000; |
120 | } | 124 | } |
121 | 125 | ||
122 | t->set_radio_freq(c, freq); | 126 | t->ops.set_radio_freq(c, freq); |
123 | } | 127 | } |
124 | 128 | ||
125 | static void set_freq(struct i2c_client *c, unsigned long freq) | 129 | static void set_freq(struct i2c_client *c, unsigned long freq) |
@@ -174,6 +178,14 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
174 | return; | 178 | return; |
175 | } | 179 | } |
176 | 180 | ||
181 | /* discard private data, in case set_type() was previously called */ | ||
182 | if (t->ops.release) | ||
183 | t->ops.release(c); | ||
184 | else { | ||
185 | kfree(t->priv); | ||
186 | t->priv = NULL; | ||
187 | } | ||
188 | |||
177 | switch (t->type) { | 189 | switch (t->type) { |
178 | case TUNER_MT2032: | 190 | case TUNER_MT2032: |
179 | microtune_init(c); | 191 | microtune_init(c); |
@@ -189,6 +201,16 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
189 | } | 201 | } |
190 | t->mode_mask = T_RADIO; | 202 | t->mode_mask = T_RADIO; |
191 | break; | 203 | break; |
204 | #ifdef CONFIG_TUNER_TEA5761 | ||
205 | case TUNER_TEA5761: | ||
206 | if (tea5761_tuner_init(c) == EINVAL) { | ||
207 | t->type = TUNER_ABSENT; | ||
208 | t->mode_mask = T_UNINITIALIZED; | ||
209 | return; | ||
210 | } | ||
211 | t->mode_mask = T_RADIO; | ||
212 | break; | ||
213 | #endif | ||
192 | case TUNER_PHILIPS_FMD1216ME_MK3: | 214 | case TUNER_PHILIPS_FMD1216ME_MK3: |
193 | buffer[0] = 0x0b; | 215 | buffer[0] = 0x0b; |
194 | buffer[1] = 0xdc; | 216 | buffer[1] = 0xdc; |
@@ -408,11 +430,11 @@ static void tuner_status(struct i2c_client *client) | |||
408 | tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std); | 430 | tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std); |
409 | if (t->mode != V4L2_TUNER_RADIO) | 431 | if (t->mode != V4L2_TUNER_RADIO) |
410 | return; | 432 | return; |
411 | if (t->has_signal) { | 433 | if (t->ops.has_signal) { |
412 | tuner_info("Signal strength: %d\n", t->has_signal(client)); | 434 | tuner_info("Signal strength: %d\n", t->ops.has_signal(client)); |
413 | } | 435 | } |
414 | if (t->is_stereo) { | 436 | if (t->ops.is_stereo) { |
415 | tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no"); | 437 | tuner_info("Stereo: %s\n", t->ops.is_stereo(client) ? "yes" : "no"); |
416 | } | 438 | } |
417 | } | 439 | } |
418 | 440 | ||
@@ -437,10 +459,9 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
437 | memcpy(&t->i2c, &client_template, sizeof(struct i2c_client)); | 459 | memcpy(&t->i2c, &client_template, sizeof(struct i2c_client)); |
438 | i2c_set_clientdata(&t->i2c, t); | 460 | i2c_set_clientdata(&t->i2c, t); |
439 | t->type = UNSET; | 461 | t->type = UNSET; |
440 | t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ | ||
441 | t->audmode = V4L2_TUNER_MODE_STEREO; | 462 | t->audmode = V4L2_TUNER_MODE_STEREO; |
442 | t->mode_mask = T_UNINITIALIZED; | 463 | t->mode_mask = T_UNINITIALIZED; |
443 | t->tuner_status = tuner_status; | 464 | t->ops.tuner_status = tuner_status; |
444 | 465 | ||
445 | if (show_i2c) { | 466 | if (show_i2c) { |
446 | unsigned char buffer[16]; | 467 | unsigned char buffer[16]; |
@@ -460,6 +481,19 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
460 | /* autodetection code based on the i2c addr */ | 481 | /* autodetection code based on the i2c addr */ |
461 | if (!no_autodetect) { | 482 | if (!no_autodetect) { |
462 | switch (addr) { | 483 | switch (addr) { |
484 | #ifdef CONFIG_TUNER_TEA5761 | ||
485 | case 0x10: | ||
486 | if (tea5761_autodetection(&t->i2c) != EINVAL) { | ||
487 | t->type = TUNER_TEA5761; | ||
488 | t->mode_mask = T_RADIO; | ||
489 | t->mode = T_STANDBY; | ||
490 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ | ||
491 | default_mode_mask &= ~T_RADIO; | ||
492 | |||
493 | goto register_client; | ||
494 | } | ||
495 | break; | ||
496 | #endif | ||
463 | case 0x42: | 497 | case 0x42: |
464 | case 0x43: | 498 | case 0x43: |
465 | case 0x4a: | 499 | case 0x4a: |
@@ -533,6 +567,11 @@ static int tuner_detach(struct i2c_client *client) | |||
533 | return err; | 567 | return err; |
534 | } | 568 | } |
535 | 569 | ||
570 | if (t->ops.release) | ||
571 | t->ops.release(client); | ||
572 | else { | ||
573 | kfree(t->priv); | ||
574 | } | ||
536 | kfree(t); | 575 | kfree(t); |
537 | return 0; | 576 | return 0; |
538 | } | 577 | } |
@@ -553,8 +592,8 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, | |||
553 | 592 | ||
554 | if (check_mode(t, cmd) == EINVAL) { | 593 | if (check_mode(t, cmd) == EINVAL) { |
555 | t->mode = T_STANDBY; | 594 | t->mode = T_STANDBY; |
556 | if (t->standby) | 595 | if (t->ops.standby) |
557 | t->standby (client); | 596 | t->ops.standby (client); |
558 | return EINVAL; | 597 | return EINVAL; |
559 | } | 598 | } |
560 | return 0; | 599 | return 0; |
@@ -602,8 +641,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
602 | if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) | 641 | if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) |
603 | return 0; | 642 | return 0; |
604 | t->mode = T_STANDBY; | 643 | t->mode = T_STANDBY; |
605 | if (t->standby) | 644 | if (t->ops.standby) |
606 | t->standby (client); | 645 | t->ops.standby (client); |
607 | break; | 646 | break; |
608 | #ifdef CONFIG_VIDEO_V4L1 | 647 | #ifdef CONFIG_VIDEO_V4L1 |
609 | case VIDIOCSAUDIO: | 648 | case VIDIOCSAUDIO: |
@@ -662,10 +701,10 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
662 | return 0; | 701 | return 0; |
663 | 702 | ||
664 | if (V4L2_TUNER_RADIO == t->mode) { | 703 | if (V4L2_TUNER_RADIO == t->mode) { |
665 | if (t->has_signal) | 704 | if (t->ops.has_signal) |
666 | vt->signal = t->has_signal(client); | 705 | vt->signal = t->ops.has_signal(client); |
667 | if (t->is_stereo) { | 706 | if (t->ops.is_stereo) { |
668 | if (t->is_stereo(client)) | 707 | if (t->ops.is_stereo(client)) |
669 | vt->flags |= | 708 | vt->flags |= |
670 | VIDEO_TUNER_STEREO_ON; | 709 | VIDEO_TUNER_STEREO_ON; |
671 | else | 710 | else |
@@ -693,8 +732,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
693 | if (check_v4l2(t) == EINVAL) | 732 | if (check_v4l2(t) == EINVAL) |
694 | return 0; | 733 | return 0; |
695 | 734 | ||
696 | if (V4L2_TUNER_RADIO == t->mode && t->is_stereo) | 735 | if (V4L2_TUNER_RADIO == t->mode && t->ops.is_stereo) |
697 | va->mode = t->is_stereo(client) | 736 | va->mode = t->ops.is_stereo(client) |
698 | ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; | 737 | ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; |
699 | return 0; | 738 | return 0; |
700 | } | 739 | } |
@@ -759,8 +798,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
759 | switch_v4l2(); | 798 | switch_v4l2(); |
760 | 799 | ||
761 | tuner->type = t->mode; | 800 | tuner->type = t->mode; |
762 | if (t->get_afc) | 801 | if (t->ops.get_afc) |
763 | tuner->afc=t->get_afc(client); | 802 | tuner->afc=t->ops.get_afc(client); |
764 | if (t->mode == V4L2_TUNER_ANALOG_TV) | 803 | if (t->mode == V4L2_TUNER_ANALOG_TV) |
765 | tuner->capability |= V4L2_TUNER_CAP_NORM; | 804 | tuner->capability |= V4L2_TUNER_CAP_NORM; |
766 | if (t->mode != V4L2_TUNER_RADIO) { | 805 | if (t->mode != V4L2_TUNER_RADIO) { |
@@ -770,13 +809,13 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
770 | } | 809 | } |
771 | 810 | ||
772 | /* radio mode */ | 811 | /* radio mode */ |
773 | if (t->has_signal) | 812 | if (t->ops.has_signal) |
774 | tuner->signal = t->has_signal(client); | 813 | tuner->signal = t->ops.has_signal(client); |
775 | 814 | ||
776 | tuner->rxsubchans = | 815 | tuner->rxsubchans = |
777 | V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | 816 | V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; |
778 | if (t->is_stereo) { | 817 | if (t->ops.is_stereo) { |
779 | tuner->rxsubchans = t->is_stereo(client) ? | 818 | tuner->rxsubchans = t->ops.is_stereo(client) ? |
780 | V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; | 819 | V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; |
781 | } | 820 | } |
782 | 821 | ||
@@ -804,8 +843,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
804 | break; | 843 | break; |
805 | } | 844 | } |
806 | case VIDIOC_LOG_STATUS: | 845 | case VIDIOC_LOG_STATUS: |
807 | if (t->tuner_status) | 846 | if (t->ops.tuner_status) |
808 | t->tuner_status(client); | 847 | t->ops.tuner_status(client); |
809 | break; | 848 | break; |
810 | } | 849 | } |
811 | 850 | ||
diff --git a/drivers/media/video/tuner-driver.h b/drivers/media/video/tuner-driver.h new file mode 100644 index 000000000000..0334a9125077 --- /dev/null +++ b/drivers/media/video/tuner-driver.h | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | tuner-driver.h - interface for different tuners | ||
3 | |||
4 | Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de) | ||
5 | minor modifications by Ralph Metzler (rjkm@thp.uni-koeln.de) | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef __TUNER_HW_H__ | ||
23 | #define __TUNER_HW_H__ | ||
24 | |||
25 | #include <linux/videodev2.h> | ||
26 | #include <linux/i2c.h> | ||
27 | |||
28 | extern unsigned const int tuner_count; | ||
29 | |||
30 | struct tuner_operations { | ||
31 | void (*set_tv_freq)(struct i2c_client *c, unsigned int freq); | ||
32 | void (*set_radio_freq)(struct i2c_client *c, unsigned int freq); | ||
33 | int (*has_signal)(struct i2c_client *c); | ||
34 | int (*is_stereo)(struct i2c_client *c); | ||
35 | int (*get_afc)(struct i2c_client *c); | ||
36 | void (*tuner_status)(struct i2c_client *c); | ||
37 | void (*standby)(struct i2c_client *c); | ||
38 | void (*release)(struct i2c_client *c); | ||
39 | }; | ||
40 | |||
41 | struct tuner { | ||
42 | /* device */ | ||
43 | struct i2c_client i2c; | ||
44 | |||
45 | unsigned int type; /* chip type */ | ||
46 | |||
47 | unsigned int mode; | ||
48 | unsigned int mode_mask; /* Combination of allowable modes */ | ||
49 | |||
50 | unsigned int tv_freq; /* keep track of the current settings */ | ||
51 | unsigned int radio_freq; | ||
52 | u16 last_div; | ||
53 | unsigned int audmode; | ||
54 | v4l2_std_id std; | ||
55 | |||
56 | int using_v4l2; | ||
57 | void *priv; | ||
58 | |||
59 | /* used by tda9887 */ | ||
60 | unsigned int tda9887_config; | ||
61 | |||
62 | unsigned int config; | ||
63 | int (*tuner_callback) (void *dev, int command,int arg); | ||
64 | |||
65 | struct tuner_operations ops; | ||
66 | }; | ||
67 | |||
68 | /* ------------------------------------------------------------------------ */ | ||
69 | |||
70 | extern int default_tuner_init(struct i2c_client *c); | ||
71 | |||
72 | extern int tda9887_tuner_init(struct i2c_client *c); | ||
73 | |||
74 | extern int microtune_init(struct i2c_client *c); | ||
75 | |||
76 | extern int tda8290_init(struct i2c_client *c); | ||
77 | extern int tda8290_probe(struct i2c_client *c); | ||
78 | |||
79 | extern int tea5761_tuner_init(struct i2c_client *c); | ||
80 | extern int tea5761_autodetection(struct i2c_client *c); | ||
81 | |||
82 | extern int tea5767_autodetection(struct i2c_client *c); | ||
83 | extern int tea5767_tuner_init(struct i2c_client *c); | ||
84 | |||
85 | /* ------------------------------------------------------------------------ */ | ||
86 | |||
87 | #define tuner_warn(fmt, arg...) do {\ | ||
88 | printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \ | ||
89 | i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) | ||
90 | #define tuner_info(fmt, arg...) do {\ | ||
91 | printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \ | ||
92 | i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) | ||
93 | #define tuner_dbg(fmt, arg...) do {\ | ||
94 | extern int tuner_debug; \ | ||
95 | if (tuner_debug) \ | ||
96 | printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \ | ||
97 | i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) | ||
98 | |||
99 | #endif /* __TUNER_HW_H__ */ | ||
100 | |||
101 | /* | ||
102 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
103 | * --------------------------------------------------------------------------- | ||
104 | * Local variables: | ||
105 | * c-basic-offset: 8 | ||
106 | * End: | ||
107 | */ | ||
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index c40b92ce1fad..2d57e8bc0db3 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c | |||
@@ -8,6 +8,8 @@ | |||
8 | #include <linux/videodev.h> | 8 | #include <linux/videodev.h> |
9 | #include <media/tuner.h> | 9 | #include <media/tuner.h> |
10 | #include <media/v4l2-common.h> | 10 | #include <media/v4l2-common.h> |
11 | #include <media/tuner-types.h> | ||
12 | #include "tuner-driver.h" | ||
11 | 13 | ||
12 | static int offset = 0; | 14 | static int offset = 0; |
13 | module_param(offset, int, 0664); | 15 | module_param(offset, int, 0664); |
@@ -54,9 +56,9 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); | |||
54 | sound 2 33.16 - - | 56 | sound 2 33.16 - - |
55 | NICAM 33.05 33.05 39.80 | 57 | NICAM 33.05 33.05 39.80 |
56 | */ | 58 | */ |
57 | #define PHILIPS_MF_SET_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */ | 59 | #define PHILIPS_MF_SET_STD_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */ |
58 | #define PHILIPS_MF_SET_PAL_L 0x03 // France | 60 | #define PHILIPS_MF_SET_STD_L 0x03 /* Used on Secam France */ |
59 | #define PHILIPS_MF_SET_PAL_L2 0x02 // L' | 61 | #define PHILIPS_MF_SET_STD_LC 0x02 /* Used on SECAM L' */ |
60 | 62 | ||
61 | /* Control byte */ | 63 | /* Control byte */ |
62 | 64 | ||
@@ -207,11 +209,11 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
207 | /* 0x04 -> ??? PAL others / SECAM others ??? */ | 209 | /* 0x04 -> ??? PAL others / SECAM others ??? */ |
208 | cb &= ~0x03; | 210 | cb &= ~0x03; |
209 | if (t->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM | 211 | if (t->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM |
210 | cb |= PHILIPS_MF_SET_PAL_L; | 212 | cb |= PHILIPS_MF_SET_STD_L; |
211 | else if (t->std & V4L2_STD_SECAM_LC) | 213 | else if (t->std & V4L2_STD_SECAM_LC) |
212 | cb |= PHILIPS_MF_SET_PAL_L2; | 214 | cb |= PHILIPS_MF_SET_STD_LC; |
213 | else /* V4L2_STD_B|V4L2_STD_GH */ | 215 | else /* V4L2_STD_B|V4L2_STD_GH */ |
214 | cb |= PHILIPS_MF_SET_BG; | 216 | cb |= PHILIPS_MF_SET_STD_BG; |
215 | break; | 217 | break; |
216 | 218 | ||
217 | case TUNER_TEMIC_4046FM5: | 219 | case TUNER_TEMIC_4046FM5: |
@@ -479,6 +481,13 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
479 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | 481 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); |
480 | } | 482 | } |
481 | 483 | ||
484 | static struct tuner_operations simple_tuner_ops = { | ||
485 | .set_tv_freq = default_set_tv_freq, | ||
486 | .set_radio_freq = default_set_radio_freq, | ||
487 | .has_signal = tuner_signal, | ||
488 | .is_stereo = tuner_stereo, | ||
489 | }; | ||
490 | |||
482 | int default_tuner_init(struct i2c_client *c) | 491 | int default_tuner_init(struct i2c_client *c) |
483 | { | 492 | { |
484 | struct tuner *t = i2c_get_clientdata(c); | 493 | struct tuner *t = i2c_get_clientdata(c); |
@@ -487,11 +496,7 @@ int default_tuner_init(struct i2c_client *c) | |||
487 | t->type, tuners[t->type].name); | 496 | t->type, tuners[t->type].name); |
488 | strlcpy(c->name, tuners[t->type].name, sizeof(c->name)); | 497 | strlcpy(c->name, tuners[t->type].name, sizeof(c->name)); |
489 | 498 | ||
490 | t->set_tv_freq = default_set_tv_freq; | 499 | memcpy(&t->ops, &simple_tuner_ops, sizeof(struct tuner_operations)); |
491 | t->set_radio_freq = default_set_radio_freq; | ||
492 | t->has_signal = tuner_signal; | ||
493 | t->is_stereo = tuner_stereo; | ||
494 | t->standby = NULL; | ||
495 | 500 | ||
496 | return 0; | 501 | return 0; |
497 | } | 502 | } |
diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index 74c3e6f96f1a..417f642b4359 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c | |||
@@ -594,19 +594,19 @@ static struct tuner_params tuner_philips_pal_mk_params[] = { | |||
594 | }, | 594 | }, |
595 | }; | 595 | }; |
596 | 596 | ||
597 | /* ------------ TUNER_PHILIPS_ATSC - Philips ATSC ------------ */ | 597 | /* ---- TUNER_PHILIPS_ATSC - Philips FCV1236D (ATSC/NTSC) ---- */ |
598 | 598 | ||
599 | static struct tuner_range tuner_philips_atsc_ranges[] = { | 599 | static struct tuner_range tuner_philips_fcv1236d_ranges[] = { |
600 | { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, }, | 600 | { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, }, |
601 | { 16 * 454.00 /*MHz*/, 0x8e, 0x90, }, | 601 | { 16 * 451.25 /*MHz*/, 0x8e, 0x90, }, |
602 | { 16 * 999.99 , 0x8e, 0x30, }, | 602 | { 16 * 999.99 , 0x8e, 0x30, }, |
603 | }; | 603 | }; |
604 | 604 | ||
605 | static struct tuner_params tuner_philips_atsc_params[] = { | 605 | static struct tuner_params tuner_philips_fcv1236d_params[] = { |
606 | { | 606 | { |
607 | .type = TUNER_PARAM_TYPE_NTSC, | 607 | .type = TUNER_PARAM_TYPE_NTSC, |
608 | .ranges = tuner_philips_atsc_ranges, | 608 | .ranges = tuner_philips_fcv1236d_ranges, |
609 | .count = ARRAY_SIZE(tuner_philips_atsc_ranges), | 609 | .count = ARRAY_SIZE(tuner_philips_fcv1236d_ranges), |
610 | }, | 610 | }, |
611 | }; | 611 | }; |
612 | 612 | ||
@@ -1296,9 +1296,9 @@ struct tunertype tuners[] = { | |||
1296 | .count = ARRAY_SIZE(tuner_philips_pal_mk_params), | 1296 | .count = ARRAY_SIZE(tuner_philips_pal_mk_params), |
1297 | }, | 1297 | }, |
1298 | [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */ | 1298 | [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */ |
1299 | .name = "Philips 1236D ATSC/NTSC dual in", | 1299 | .name = "Philips FCV1236D ATSC/NTSC dual in", |
1300 | .params = tuner_philips_atsc_params, | 1300 | .params = tuner_philips_fcv1236d_params, |
1301 | .count = ARRAY_SIZE(tuner_philips_atsc_params), | 1301 | .count = ARRAY_SIZE(tuner_philips_fcv1236d_params), |
1302 | }, | 1302 | }, |
1303 | [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */ | 1303 | [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */ |
1304 | .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", | 1304 | .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", |
@@ -1463,6 +1463,10 @@ struct tunertype tuners[] = { | |||
1463 | .name = "Philips TDA988[5,6,7] IF PLL Demodulator", | 1463 | .name = "Philips TDA988[5,6,7] IF PLL Demodulator", |
1464 | /* see tda9887.c for details */ | 1464 | /* see tda9887.c for details */ |
1465 | }, | 1465 | }, |
1466 | [TUNER_TEA5761] = { /* Philips RADIO */ | ||
1467 | .name = "Philips TEA5761 FM Radio", | ||
1468 | /* see tea5767.c for details */ | ||
1469 | }, | ||
1466 | }; | 1470 | }; |
1467 | 1471 | ||
1468 | unsigned const int tuner_count = ARRAY_SIZE(tuners); | 1472 | unsigned const int tuner_count = ARRAY_SIZE(tuners); |
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index a1136da74ba8..fdc3def437b1 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -183,7 +183,7 @@ hauppauge_tuner[] = | |||
183 | { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"}, | 183 | { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"}, |
184 | { TUNER_ABSENT, "Thompson DTT757"}, | 184 | { TUNER_ABSENT, "Thompson DTT757"}, |
185 | /* 80-89 */ | 185 | /* 80-89 */ |
186 | { TUNER_ABSENT, "Philips FQ1216LME MK3"}, | 186 | { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216LME MK3"}, |
187 | { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"}, | 187 | { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"}, |
188 | { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, | 188 | { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, |
189 | { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, | 189 | { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, |
@@ -490,7 +490,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
490 | to indicate 4052 mux was removed in favor of using MSP | 490 | to indicate 4052 mux was removed in favor of using MSP |
491 | inputs directly. */ | 491 | inputs directly. */ |
492 | audioic = eeprom_data[i+2] & 0x7f; | 492 | audioic = eeprom_data[i+2] & 0x7f; |
493 | if (audioic < sizeof(audioIC)/sizeof(*audioIC)) | 493 | if (audioic < ARRAY_SIZE(audioIC)) |
494 | tvee->audio_processor = audioIC[audioic].id; | 494 | tvee->audio_processor = audioIC[audioic].id; |
495 | else | 495 | else |
496 | tvee->audio_processor = AUDIO_CHIP_UNKNOWN; | 496 | tvee->audio_processor = AUDIO_CHIP_UNKNOWN; |
@@ -523,7 +523,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
523 | to indicate 4052 mux was removed in favor of using MSP | 523 | to indicate 4052 mux was removed in favor of using MSP |
524 | inputs directly. */ | 524 | inputs directly. */ |
525 | audioic = eeprom_data[i+1] & 0x7f; | 525 | audioic = eeprom_data[i+1] & 0x7f; |
526 | if (audioic < sizeof(audioIC)/sizeof(*audioIC)) | 526 | if (audioic < ARRAY_SIZE(audioIC)) |
527 | tvee->audio_processor = audioIC[audioic].id; | 527 | tvee->audio_processor = audioIC[audioic].id; |
528 | else | 528 | else |
529 | tvee->audio_processor = AUDIO_CHIP_UNKNOWN; | 529 | tvee->audio_processor = AUDIO_CHIP_UNKNOWN; |
@@ -678,7 +678,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
678 | tveeprom_info("audio processor is unknown (no idx)\n"); | 678 | tveeprom_info("audio processor is unknown (no idx)\n"); |
679 | tvee->audio_processor=AUDIO_CHIP_UNKNOWN; | 679 | tvee->audio_processor=AUDIO_CHIP_UNKNOWN; |
680 | } else { | 680 | } else { |
681 | if (audioic < sizeof(audioIC)/sizeof(*audioIC)) | 681 | if (audioic < ARRAY_SIZE(audioIC)) |
682 | tveeprom_info("audio processor is %s (idx %d)\n", | 682 | tveeprom_info("audio processor is %s (idx %d)\n", |
683 | audioIC[audioic].name,audioic); | 683 | audioIC[audioic].name,audioic); |
684 | else | 684 | else |
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index d5ec05f56adf..e2f1c972754b 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
@@ -1006,7 +1006,7 @@ static int tvp5150_command(struct i2c_client *c, | |||
1006 | { | 1006 | { |
1007 | struct v4l2_control *ctrl = arg; | 1007 | struct v4l2_control *ctrl = arg; |
1008 | u8 i, n; | 1008 | u8 i, n; |
1009 | n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]); | 1009 | n = ARRAY_SIZE(tvp5150_qctrl); |
1010 | for (i = 0; i < n; i++) | 1010 | for (i = 0; i < n; i++) |
1011 | if (ctrl->id == tvp5150_qctrl[i].id) { | 1011 | if (ctrl->id == tvp5150_qctrl[i].id) { |
1012 | if (ctrl->value < | 1012 | if (ctrl->value < |
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c index abe214619092..491505d6fdee 100644 --- a/drivers/media/video/usbvideo/konicawc.c +++ b/drivers/media/video/usbvideo/konicawc.c | |||
@@ -236,7 +236,7 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev | |||
236 | input_dev->name = "Konicawc snapshot button"; | 236 | input_dev->name = "Konicawc snapshot button"; |
237 | input_dev->phys = cam->input_physname; | 237 | input_dev->phys = cam->input_physname; |
238 | usb_to_input_id(dev, &input_dev->id); | 238 | usb_to_input_id(dev, &input_dev->id); |
239 | input_dev->cdev.dev = &dev->dev; | 239 | input_dev->dev.parent = &dev->dev; |
240 | 240 | ||
241 | input_dev->evbit[0] = BIT(EV_KEY); | 241 | input_dev->evbit[0] = BIT(EV_KEY); |
242 | input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); | 242 | input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); |
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c index ec0ff2247f06..dd1a6d6bbc9e 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/drivers/media/video/usbvideo/quickcam_messenger.c | |||
@@ -100,7 +100,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev) | |||
100 | input_dev->name = "QCM button"; | 100 | input_dev->name = "QCM button"; |
101 | input_dev->phys = cam->input_physname; | 101 | input_dev->phys = cam->input_physname; |
102 | usb_to_input_id(dev, &input_dev->id); | 102 | usb_to_input_id(dev, &input_dev->id); |
103 | input_dev->cdev.dev = &dev->dev; | 103 | input_dev->dev.parent = &dev->dev; |
104 | 104 | ||
105 | input_dev->evbit[0] = BIT(EV_KEY); | 105 | input_dev->evbit[0] = BIT(EV_KEY); |
106 | input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); | 106 | input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); |
@@ -439,7 +439,7 @@ static int qcm_sensor_init(struct uvd *uvd) | |||
439 | int ret; | 439 | int ret; |
440 | int i; | 440 | int i; |
441 | 441 | ||
442 | for (i=0; i < sizeof(regval_table)/sizeof(regval_table[0]) ; i++) { | 442 | for (i=0; i < ARRAY_SIZE(regval_table) ; i++) { |
443 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, | 443 | CHECK_RET(ret, qcm_stv_setb(uvd->dev, |
444 | regval_table[i].reg, | 444 | regval_table[i].reg, |
445 | regval_table[i].val)); | 445 | regval_table[i].val)); |
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index 982b115193f8..2d9c0dd3b733 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c | |||
@@ -42,7 +42,6 @@ | |||
42 | #include <linux/usb.h> | 42 | #include <linux/usb.h> |
43 | #include <linux/vmalloc.h> | 43 | #include <linux/vmalloc.h> |
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/proc_fs.h> | ||
46 | #include <linux/mutex.h> | 45 | #include <linux/mutex.h> |
47 | #include "usbvideo.h" | 46 | #include "usbvideo.h" |
48 | 47 | ||
@@ -417,11 +416,6 @@ struct vicam_camera { | |||
417 | u8 open_count; | 416 | u8 open_count; |
418 | u8 bulkEndpoint; | 417 | u8 bulkEndpoint; |
419 | int needsDummyRead; | 418 | int needsDummyRead; |
420 | |||
421 | #if defined(CONFIG_VIDEO_PROC_FS) | ||
422 | struct proc_dir_entry *proc_dir; | ||
423 | #endif | ||
424 | |||
425 | }; | 419 | }; |
426 | 420 | ||
427 | static int vicam_probe( struct usb_interface *intf, const struct usb_device_id *id); | 421 | static int vicam_probe( struct usb_interface *intf, const struct usb_device_id *id); |
@@ -1065,175 +1059,6 @@ vicam_mmap(struct file *file, struct vm_area_struct *vma) | |||
1065 | return 0; | 1059 | return 0; |
1066 | } | 1060 | } |
1067 | 1061 | ||
1068 | #if defined(CONFIG_VIDEO_PROC_FS) | ||
1069 | |||
1070 | static struct proc_dir_entry *vicam_proc_root = NULL; | ||
1071 | |||
1072 | static int vicam_read_helper(char *page, char **start, off_t off, | ||
1073 | int count, int *eof, int value) | ||
1074 | { | ||
1075 | char *out = page; | ||
1076 | int len; | ||
1077 | |||
1078 | out += sprintf(out, "%d",value); | ||
1079 | |||
1080 | len = out - page; | ||
1081 | len -= off; | ||
1082 | if (len < count) { | ||
1083 | *eof = 1; | ||
1084 | if (len <= 0) | ||
1085 | return 0; | ||
1086 | } else | ||
1087 | len = count; | ||
1088 | |||
1089 | *start = page + off; | ||
1090 | return len; | ||
1091 | } | ||
1092 | |||
1093 | static int vicam_read_proc_shutter(char *page, char **start, off_t off, | ||
1094 | int count, int *eof, void *data) | ||
1095 | { | ||
1096 | return vicam_read_helper(page,start,off,count,eof, | ||
1097 | ((struct vicam_camera *)data)->shutter_speed); | ||
1098 | } | ||
1099 | |||
1100 | static int vicam_read_proc_gain(char *page, char **start, off_t off, | ||
1101 | int count, int *eof, void *data) | ||
1102 | { | ||
1103 | return vicam_read_helper(page,start,off,count,eof, | ||
1104 | ((struct vicam_camera *)data)->gain); | ||
1105 | } | ||
1106 | |||
1107 | static int | ||
1108 | vicam_write_proc_shutter(struct file *file, const char *buffer, | ||
1109 | unsigned long count, void *data) | ||
1110 | { | ||
1111 | u16 stmp; | ||
1112 | char kbuf[8]; | ||
1113 | struct vicam_camera *cam = (struct vicam_camera *) data; | ||
1114 | |||
1115 | if (count > 6) | ||
1116 | return -EINVAL; | ||
1117 | |||
1118 | if (copy_from_user(kbuf, buffer, count)) | ||
1119 | return -EFAULT; | ||
1120 | |||
1121 | stmp = (u16) simple_strtoul(kbuf, NULL, 10); | ||
1122 | if (stmp < 4 || stmp > 32000) | ||
1123 | return -EINVAL; | ||
1124 | |||
1125 | cam->shutter_speed = stmp; | ||
1126 | |||
1127 | return count; | ||
1128 | } | ||
1129 | |||
1130 | static int | ||
1131 | vicam_write_proc_gain(struct file *file, const char *buffer, | ||
1132 | unsigned long count, void *data) | ||
1133 | { | ||
1134 | u16 gtmp; | ||
1135 | char kbuf[8]; | ||
1136 | |||
1137 | struct vicam_camera *cam = (struct vicam_camera *) data; | ||
1138 | |||
1139 | if (count > 4) | ||
1140 | return -EINVAL; | ||
1141 | |||
1142 | if (copy_from_user(kbuf, buffer, count)) | ||
1143 | return -EFAULT; | ||
1144 | |||
1145 | gtmp = (u16) simple_strtoul(kbuf, NULL, 10); | ||
1146 | if (gtmp > 255) | ||
1147 | return -EINVAL; | ||
1148 | cam->gain = gtmp; | ||
1149 | |||
1150 | return count; | ||
1151 | } | ||
1152 | |||
1153 | static void | ||
1154 | vicam_create_proc_root(void) | ||
1155 | { | ||
1156 | vicam_proc_root = proc_mkdir("video/vicam", NULL); | ||
1157 | |||
1158 | if (vicam_proc_root) | ||
1159 | vicam_proc_root->owner = THIS_MODULE; | ||
1160 | else | ||
1161 | printk(KERN_ERR | ||
1162 | "could not create /proc entry for vicam!"); | ||
1163 | } | ||
1164 | |||
1165 | static void | ||
1166 | vicam_destroy_proc_root(void) | ||
1167 | { | ||
1168 | if (vicam_proc_root) | ||
1169 | remove_proc_entry("video/vicam", 0); | ||
1170 | } | ||
1171 | |||
1172 | static void | ||
1173 | vicam_create_proc_entry(struct vicam_camera *cam) | ||
1174 | { | ||
1175 | char name[64]; | ||
1176 | struct proc_dir_entry *ent; | ||
1177 | |||
1178 | DBG(KERN_INFO "vicam: creating proc entry\n"); | ||
1179 | |||
1180 | if (!vicam_proc_root || !cam) { | ||
1181 | printk(KERN_INFO | ||
1182 | "vicam: could not create proc entry, %s pointer is null.\n", | ||
1183 | (!cam ? "camera" : "root")); | ||
1184 | return; | ||
1185 | } | ||
1186 | |||
1187 | sprintf(name, "video%d", cam->vdev.minor); | ||
1188 | |||
1189 | cam->proc_dir = proc_mkdir(name, vicam_proc_root); | ||
1190 | |||
1191 | if ( !cam->proc_dir ) | ||
1192 | return; // FIXME: We should probably return an error here | ||
1193 | |||
1194 | ent = create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR, | ||
1195 | cam->proc_dir); | ||
1196 | if (ent) { | ||
1197 | ent->data = cam; | ||
1198 | ent->read_proc = vicam_read_proc_shutter; | ||
1199 | ent->write_proc = vicam_write_proc_shutter; | ||
1200 | ent->size = 64; | ||
1201 | } | ||
1202 | |||
1203 | ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR, | ||
1204 | cam->proc_dir); | ||
1205 | if (ent) { | ||
1206 | ent->data = cam; | ||
1207 | ent->read_proc = vicam_read_proc_gain; | ||
1208 | ent->write_proc = vicam_write_proc_gain; | ||
1209 | ent->size = 64; | ||
1210 | } | ||
1211 | } | ||
1212 | |||
1213 | static void | ||
1214 | vicam_destroy_proc_entry(void *ptr) | ||
1215 | { | ||
1216 | struct vicam_camera *cam = (struct vicam_camera *) ptr; | ||
1217 | char name[16]; | ||
1218 | |||
1219 | if ( !cam->proc_dir ) | ||
1220 | return; | ||
1221 | |||
1222 | sprintf(name, "video%d", cam->vdev.minor); | ||
1223 | remove_proc_entry("shutter", cam->proc_dir); | ||
1224 | remove_proc_entry("gain", cam->proc_dir); | ||
1225 | remove_proc_entry(name,vicam_proc_root); | ||
1226 | cam->proc_dir = NULL; | ||
1227 | |||
1228 | } | ||
1229 | |||
1230 | #else | ||
1231 | static inline void vicam_create_proc_root(void) { } | ||
1232 | static inline void vicam_destroy_proc_root(void) { } | ||
1233 | static inline void vicam_create_proc_entry(struct vicam_camera *cam) { } | ||
1234 | static inline void vicam_destroy_proc_entry(void *ptr) { } | ||
1235 | #endif | ||
1236 | |||
1237 | static const struct file_operations vicam_fops = { | 1062 | static const struct file_operations vicam_fops = { |
1238 | .owner = THIS_MODULE, | 1063 | .owner = THIS_MODULE, |
1239 | .open = vicam_open, | 1064 | .open = vicam_open, |
@@ -1330,8 +1155,6 @@ vicam_probe( struct usb_interface *intf, const struct usb_device_id *id) | |||
1330 | return -EIO; | 1155 | return -EIO; |
1331 | } | 1156 | } |
1332 | 1157 | ||
1333 | vicam_create_proc_entry(cam); | ||
1334 | |||
1335 | printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",cam->vdev.minor); | 1158 | printk(KERN_INFO "ViCam webcam driver now controlling video device %d\n",cam->vdev.minor); |
1336 | 1159 | ||
1337 | usb_set_intfdata (intf, cam); | 1160 | usb_set_intfdata (intf, cam); |
@@ -1363,8 +1186,6 @@ vicam_disconnect(struct usb_interface *intf) | |||
1363 | 1186 | ||
1364 | cam->udev = NULL; | 1187 | cam->udev = NULL; |
1365 | 1188 | ||
1366 | vicam_destroy_proc_entry(cam); | ||
1367 | |||
1368 | /* the only thing left to do is synchronize with | 1189 | /* the only thing left to do is synchronize with |
1369 | * our close/release function on who should release | 1190 | * our close/release function on who should release |
1370 | * the camera memory. if there are any users using the | 1191 | * the camera memory. if there are any users using the |
@@ -1390,7 +1211,6 @@ usb_vicam_init(void) | |||
1390 | { | 1211 | { |
1391 | int retval; | 1212 | int retval; |
1392 | DBG(KERN_INFO "ViCam-based WebCam driver startup\n"); | 1213 | DBG(KERN_INFO "ViCam-based WebCam driver startup\n"); |
1393 | vicam_create_proc_root(); | ||
1394 | retval = usb_register(&vicam_driver); | 1214 | retval = usb_register(&vicam_driver); |
1395 | if (retval) | 1215 | if (retval) |
1396 | printk(KERN_WARNING "usb_register failed!\n"); | 1216 | printk(KERN_WARNING "usb_register failed!\n"); |
@@ -1404,7 +1224,6 @@ usb_vicam_exit(void) | |||
1404 | "ViCam-based WebCam driver shutdown\n"); | 1224 | "ViCam-based WebCam driver shutdown\n"); |
1405 | 1225 | ||
1406 | usb_deregister(&vicam_driver); | 1226 | usb_deregister(&vicam_driver); |
1407 | vicam_destroy_proc_root(); | ||
1408 | } | 1227 | } |
1409 | 1228 | ||
1410 | module_init(usb_vicam_init); | 1229 | module_init(usb_vicam_init); |
diff --git a/drivers/media/video/usbvision/usbvision-cards.c b/drivers/media/video/usbvision/usbvision-cards.c index 51ab265d566a..380564cd3317 100644 --- a/drivers/media/video/usbvision/usbvision-cards.c +++ b/drivers/media/video/usbvision/usbvision-cards.c | |||
@@ -79,7 +79,7 @@ struct usbvision_device_data_st usbvision_device_data[] = { | |||
79 | .Interface = -1, | 79 | .Interface = -1, |
80 | .Codec = CODEC_SAA7113, | 80 | .Codec = CODEC_SAA7113, |
81 | .VideoChannels = 2, | 81 | .VideoChannels = 2, |
82 | .VideoNorm = V4L2_STD_PAL, | 82 | .VideoNorm = V4L2_STD_NTSC, |
83 | .AudioChannels = 1, | 83 | .AudioChannels = 1, |
84 | .Radio = 0, | 84 | .Radio = 0, |
85 | .vbi = 1, | 85 | .vbi = 1, |
@@ -311,8 +311,8 @@ struct usbvision_device_data_st usbvision_device_data[] = { | |||
311 | .vbi = 1, | 311 | .vbi = 1, |
312 | .Tuner = 1, | 312 | .Tuner = 1, |
313 | .TunerType = TUNER_PHILIPS_SECAM, | 313 | .TunerType = TUNER_PHILIPS_SECAM, |
314 | .X_Offset = -1, | 314 | .X_Offset = 0x80, |
315 | .Y_Offset = -1, | 315 | .Y_Offset = 0x16, |
316 | .ModelString = "Hauppauge WinTV USB (PAL/SECAM L)", | 316 | .ModelString = "Hauppauge WinTV USB (PAL/SECAM L)", |
317 | }, | 317 | }, |
318 | [HPG_WINTV_PAL_D_K] = { | 318 | [HPG_WINTV_PAL_D_K] = { |
@@ -586,7 +586,7 @@ struct usbvision_device_data_st usbvision_device_data[] = { | |||
586 | .Radio = 0, | 586 | .Radio = 0, |
587 | .vbi = 1, | 587 | .vbi = 1, |
588 | .Tuner = 1, | 588 | .Tuner = 1, |
589 | .TunerType = TUNER_PHILIPS_PAL, | 589 | .TunerType = TUNER_LG_PAL_NEW_TAPC, |
590 | .X_Offset = 0, | 590 | .X_Offset = 0, |
591 | .Y_Offset = 3, | 591 | .Y_Offset = 3, |
592 | .Dvi_yuv_override = 1, | 592 | .Dvi_yuv_override = 1, |
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index 7df071eb0a3b..5b1e346df206 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c | |||
@@ -1742,7 +1742,7 @@ static int usbvision_set_video_format(struct usb_usbvision *usbvision, int forma | |||
1742 | format = ISOC_MODE_YUV420; | 1742 | format = ISOC_MODE_YUV420; |
1743 | } | 1743 | } |
1744 | value[0] = 0x0A; //TODO: See the effect of the filter | 1744 | value[0] = 0x0A; //TODO: See the effect of the filter |
1745 | value[1] = format; | 1745 | value[1] = format; // Sets the VO_MODE register which follows FILT_CONT |
1746 | rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1), | 1746 | rc = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1), |
1747 | USBVISION_OP_CODE, | 1747 | USBVISION_OP_CODE, |
1748 | USB_DIR_OUT | USB_TYPE_VENDOR | | 1748 | USB_DIR_OUT | USB_TYPE_VENDOR | |
@@ -1831,10 +1831,10 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width, | |||
1831 | frameRate = FRAMERATE_MAX; | 1831 | frameRate = FRAMERATE_MAX; |
1832 | } | 1832 | } |
1833 | 1833 | ||
1834 | if (usbvision->tvnorm->id & V4L2_STD_625_50) { | 1834 | if (usbvision->tvnormId & V4L2_STD_625_50) { |
1835 | frameDrop = frameRate * 32 / 25 - 1; | 1835 | frameDrop = frameRate * 32 / 25 - 1; |
1836 | } | 1836 | } |
1837 | else if (usbvision->tvnorm->id & V4L2_STD_525_60) { | 1837 | else if (usbvision->tvnormId & V4L2_STD_525_60) { |
1838 | frameDrop = frameRate * 32 / 30 - 1; | 1838 | frameDrop = frameRate * 32 / 30 - 1; |
1839 | } | 1839 | } |
1840 | 1840 | ||
@@ -2067,7 +2067,7 @@ int usbvision_set_input(struct usb_usbvision *usbvision) | |||
2067 | } | 2067 | } |
2068 | 2068 | ||
2069 | 2069 | ||
2070 | if (usbvision->tvnorm->id & V4L2_STD_PAL) { | 2070 | if (usbvision->tvnormId & V4L2_STD_PAL) { |
2071 | value[0] = 0xC0; | 2071 | value[0] = 0xC0; |
2072 | value[1] = 0x02; //0x02C0 -> 704 Input video line length | 2072 | value[1] = 0x02; //0x02C0 -> 704 Input video line length |
2073 | value[2] = 0x20; | 2073 | value[2] = 0x20; |
@@ -2076,7 +2076,7 @@ int usbvision_set_input(struct usb_usbvision *usbvision) | |||
2076 | value[5] = 0x00; //0x0060 -> 96 Input video h offset | 2076 | value[5] = 0x00; //0x0060 -> 96 Input video h offset |
2077 | value[6] = 0x16; | 2077 | value[6] = 0x16; |
2078 | value[7] = 0x00; //0x0016 -> 22 Input video v offset | 2078 | value[7] = 0x00; //0x0016 -> 22 Input video v offset |
2079 | } else if (usbvision->tvnorm->id & V4L2_STD_SECAM) { | 2079 | } else if (usbvision->tvnormId & V4L2_STD_SECAM) { |
2080 | value[0] = 0xC0; | 2080 | value[0] = 0xC0; |
2081 | value[1] = 0x02; //0x02C0 -> 704 Input video line length | 2081 | value[1] = 0x02; //0x02C0 -> 704 Input video line length |
2082 | value[2] = 0x20; | 2082 | value[2] = 0x20; |
@@ -2537,7 +2537,9 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) | |||
2537 | 2537 | ||
2538 | int usbvision_muxsel(struct usb_usbvision *usbvision, int channel) | 2538 | int usbvision_muxsel(struct usb_usbvision *usbvision, int channel) |
2539 | { | 2539 | { |
2540 | int mode[4]; | 2540 | /* inputs #0 and #3 are constant for every SAA711x. */ |
2541 | /* inputs #1 and #2 are variable for SAA7111 and SAA7113 */ | ||
2542 | int mode[4]= {SAA7115_COMPOSITE0, 0, 0, SAA7115_COMPOSITE3}; | ||
2541 | int audio[]= {1, 0, 0, 0}; | 2543 | int audio[]= {1, 0, 0, 0}; |
2542 | struct v4l2_routing route; | 2544 | struct v4l2_routing route; |
2543 | //channel 0 is TV with audiochannel 1 (tuner mono) | 2545 | //channel 0 is TV with audiochannel 1 (tuner mono) |
@@ -2547,10 +2549,6 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel) | |||
2547 | 2549 | ||
2548 | RESTRICT_TO_RANGE(channel, 0, usbvision->video_inputs); | 2550 | RESTRICT_TO_RANGE(channel, 0, usbvision->video_inputs); |
2549 | usbvision->ctl_input = channel; | 2551 | usbvision->ctl_input = channel; |
2550 | route.input = SAA7115_COMPOSITE1; | ||
2551 | route.output = 0; | ||
2552 | call_i2c_clients(usbvision, VIDIOC_INT_S_VIDEO_ROUTING,&route); | ||
2553 | call_i2c_clients(usbvision, VIDIOC_S_INPUT, &usbvision->ctl_input); | ||
2554 | 2552 | ||
2555 | // set the new channel | 2553 | // set the new channel |
2556 | // Regular USB TV Tuners -> channel: 0 = Television, 1 = Composite, 2 = S-Video | 2554 | // Regular USB TV Tuners -> channel: 0 = Television, 1 = Composite, 2 = S-Video |
@@ -2558,28 +2556,27 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel) | |||
2558 | 2556 | ||
2559 | switch (usbvision_device_data[usbvision->DevModel].Codec) { | 2557 | switch (usbvision_device_data[usbvision->DevModel].Codec) { |
2560 | case CODEC_SAA7113: | 2558 | case CODEC_SAA7113: |
2561 | if (SwitchSVideoInput) { // To handle problems with S-Video Input for some devices. Use SwitchSVideoInput parameter when loading the module. | 2559 | mode[1] = SAA7115_COMPOSITE2; |
2562 | mode[2] = 1; | 2560 | if (SwitchSVideoInput) { |
2561 | /* To handle problems with S-Video Input for | ||
2562 | * some devices. Use SwitchSVideoInput | ||
2563 | * parameter when loading the module.*/ | ||
2564 | mode[2] = SAA7115_COMPOSITE1; | ||
2563 | } | 2565 | } |
2564 | else { | 2566 | else { |
2565 | mode[2] = 7; | 2567 | mode[2] = SAA7115_SVIDEO1; |
2566 | } | ||
2567 | if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) { | ||
2568 | mode[0] = 0; mode[1] = 2; mode[3] = 3; // Special for four input devices | ||
2569 | } | ||
2570 | else { | ||
2571 | mode[0] = 0; mode[1] = 2; //modes for regular saa7113 devices | ||
2572 | } | 2568 | } |
2573 | break; | 2569 | break; |
2574 | case CODEC_SAA7111: | 2570 | case CODEC_SAA7111: |
2575 | mode[0] = 0; mode[1] = 1; mode[2] = 7; //modes for saa7111 | ||
2576 | break; | ||
2577 | default: | 2571 | default: |
2578 | mode[0] = 0; mode[1] = 1; mode[2] = 7; //default modes | 2572 | /* modes for saa7111 */ |
2573 | mode[1] = SAA7115_COMPOSITE1; | ||
2574 | mode[2] = SAA7115_SVIDEO1; | ||
2575 | break; | ||
2579 | } | 2576 | } |
2580 | route.input = mode[channel]; | 2577 | route.input = mode[channel]; |
2578 | route.output = 0; | ||
2581 | call_i2c_clients(usbvision, VIDIOC_INT_S_VIDEO_ROUTING,&route); | 2579 | call_i2c_clients(usbvision, VIDIOC_INT_S_VIDEO_ROUTING,&route); |
2582 | usbvision->channel = channel; | ||
2583 | usbvision_set_audio(usbvision, audio[channel]); | 2580 | usbvision_set_audio(usbvision, audio[channel]); |
2584 | return 0; | 2581 | return 0; |
2585 | } | 2582 | } |
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index aa3258bbb4af..868b6886fe7f 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -36,7 +36,8 @@ | |||
36 | * - use submit_urb for all setup packets | 36 | * - use submit_urb for all setup packets |
37 | * - Fix memory settings for nt1004. It is 4 times as big as the | 37 | * - Fix memory settings for nt1004. It is 4 times as big as the |
38 | * nt1003 memory. | 38 | * nt1003 memory. |
39 | * - Add audio on endpoint 3 for nt1004 chip. Seems impossible, needs a codec interface. Which one? | 39 | * - Add audio on endpoint 3 for nt1004 chip. |
40 | * Seems impossible, needs a codec interface. Which one? | ||
40 | * - Clean up the driver. | 41 | * - Clean up the driver. |
41 | * - optimization for performance. | 42 | * - optimization for performance. |
42 | * - Add Videotext capability (VBI). Working on it..... | 43 | * - Add Videotext capability (VBI). Working on it..... |
@@ -77,7 +78,8 @@ | |||
77 | #include "usbvision.h" | 78 | #include "usbvision.h" |
78 | #include "usbvision-cards.h" | 79 | #include "usbvision-cards.h" |
79 | 80 | ||
80 | #define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>, Dwaine Garden <DwaineGarden@rogers.com>" | 81 | #define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>,\ |
82 | Dwaine Garden <DwaineGarden@rogers.com>" | ||
81 | #define DRIVER_NAME "usbvision" | 83 | #define DRIVER_NAME "usbvision" |
82 | #define DRIVER_ALIAS "USBVision" | 84 | #define DRIVER_ALIAS "USBVision" |
83 | #define DRIVER_DESC "USBVision USB Video Device Driver for Linux" | 85 | #define DRIVER_DESC "USBVision USB Video Device Driver for Linux" |
@@ -85,20 +87,25 @@ | |||
85 | #define USBVISION_DRIVER_VERSION_MAJOR 0 | 87 | #define USBVISION_DRIVER_VERSION_MAJOR 0 |
86 | #define USBVISION_DRIVER_VERSION_MINOR 9 | 88 | #define USBVISION_DRIVER_VERSION_MINOR 9 |
87 | #define USBVISION_DRIVER_VERSION_PATCHLEVEL 9 | 89 | #define USBVISION_DRIVER_VERSION_PATCHLEVEL 9 |
88 | #define USBVISION_DRIVER_VERSION KERNEL_VERSION(USBVISION_DRIVER_VERSION_MAJOR,USBVISION_DRIVER_VERSION_MINOR,USBVISION_DRIVER_VERSION_PATCHLEVEL) | 90 | #define USBVISION_DRIVER_VERSION KERNEL_VERSION(USBVISION_DRIVER_VERSION_MAJOR,\ |
89 | #define USBVISION_VERSION_STRING __stringify(USBVISION_DRIVER_VERSION_MAJOR) "." __stringify(USBVISION_DRIVER_VERSION_MINOR) "." __stringify(USBVISION_DRIVER_VERSION_PATCHLEVEL) | 91 | USBVISION_DRIVER_VERSION_MINOR,\ |
92 | USBVISION_DRIVER_VERSION_PATCHLEVEL) | ||
93 | #define USBVISION_VERSION_STRING __stringify(USBVISION_DRIVER_VERSION_MAJOR)\ | ||
94 | "." __stringify(USBVISION_DRIVER_VERSION_MINOR)\ | ||
95 | "." __stringify(USBVISION_DRIVER_VERSION_PATCHLEVEL) | ||
90 | 96 | ||
91 | #define ENABLE_HEXDUMP 0 /* Enable if you need it */ | 97 | #define ENABLE_HEXDUMP 0 /* Enable if you need it */ |
92 | 98 | ||
93 | 99 | ||
94 | #ifdef USBVISION_DEBUG | 100 | #ifdef USBVISION_DEBUG |
95 | #define PDEBUG(level, fmt, args...) \ | 101 | #define PDEBUG(level, fmt, args...) \ |
96 | if (video_debug & (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , ## args) | 102 | if (video_debug & (level)) \ |
103 | info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ ,\ | ||
104 | ## args) | ||
97 | #else | 105 | #else |
98 | #define PDEBUG(level, fmt, args...) do {} while(0) | 106 | #define PDEBUG(level, fmt, args...) do {} while(0) |
99 | #endif | 107 | #endif |
100 | 108 | ||
101 | #define DBG_IOCTL 1<<0 | ||
102 | #define DBG_IO 1<<1 | 109 | #define DBG_IO 1<<1 |
103 | #define DBG_PROBE 1<<2 | 110 | #define DBG_PROBE 1<<2 |
104 | #define DBG_MMAP 1<<3 | 111 | #define DBG_MMAP 1<<3 |
@@ -108,7 +115,8 @@ | |||
108 | #define goto2next(str) while(*str!=' ') str++; while(*str==' ') str++; | 115 | #define goto2next(str) while(*str!=' ') str++; while(*str==' ') str++; |
109 | 116 | ||
110 | 117 | ||
111 | static int usbvision_nr = 0; // sequential number of usbvision device | 118 | /* sequential number of usbvision device */ |
119 | static int usbvision_nr = 0; | ||
112 | 120 | ||
113 | static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = { | 121 | static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = { |
114 | { 1, 1, 8, V4L2_PIX_FMT_GREY , "GREY" }, | 122 | { 1, 1, 8, V4L2_PIX_FMT_GREY , "GREY" }, |
@@ -121,55 +129,32 @@ static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = { | |||
121 | { 1, 2, 16, V4L2_PIX_FMT_YUV422P , "YUV422P" } | 129 | { 1, 2, 16, V4L2_PIX_FMT_YUV422P , "YUV422P" } |
122 | }; | 130 | }; |
123 | 131 | ||
124 | /* supported tv norms */ | 132 | /* Function prototypes */ |
125 | static struct usbvision_tvnorm tvnorms[] = { | ||
126 | { | ||
127 | .name = "PAL", | ||
128 | .id = V4L2_STD_PAL, | ||
129 | }, { | ||
130 | .name = "NTSC", | ||
131 | .id = V4L2_STD_NTSC, | ||
132 | }, { | ||
133 | .name = "SECAM", | ||
134 | .id = V4L2_STD_SECAM, | ||
135 | }, { | ||
136 | .name = "PAL-M", | ||
137 | .id = V4L2_STD_PAL_M, | ||
138 | } | ||
139 | }; | ||
140 | |||
141 | #define TVNORMS ARRAY_SIZE(tvnorms) | ||
142 | |||
143 | // Function prototypes | ||
144 | static void usbvision_release(struct usb_usbvision *usbvision); | 133 | static void usbvision_release(struct usb_usbvision *usbvision); |
145 | 134 | ||
146 | // Default initalization of device driver parameters | 135 | /* Default initalization of device driver parameters */ |
147 | static int isocMode = ISOC_MODE_COMPRESS; // Set the default format for ISOC endpoint | 136 | /* Set the default format for ISOC endpoint */ |
148 | static int video_debug = 0; // Set the default Debug Mode of the device driver | 137 | static int isocMode = ISOC_MODE_COMPRESS; |
149 | static int PowerOnAtOpen = 1; // Set the default device to power on at startup | 138 | /* Set the default Debug Mode of the device driver */ |
150 | static int video_nr = -1; // Sequential Number of Video Device | 139 | static int video_debug = 0; |
151 | static int radio_nr = -1; // Sequential Number of Radio Device | 140 | /* Set the default device to power on at startup */ |
152 | static int vbi_nr = -1; // Sequential Number of VBI Device | 141 | static int PowerOnAtOpen = 1; |
153 | 142 | /* Sequential Number of Video Device */ | |
154 | // Grab parameters for the device driver | 143 | static int video_nr = -1; |
155 | 144 | /* Sequential Number of Radio Device */ | |
156 | #if defined(module_param) // Showing parameters under SYSFS | 145 | static int radio_nr = -1; |
146 | /* Sequential Number of VBI Device */ | ||
147 | static int vbi_nr = -1; | ||
148 | |||
149 | /* Grab parameters for the device driver */ | ||
150 | |||
151 | /* Showing parameters under SYSFS */ | ||
157 | module_param(isocMode, int, 0444); | 152 | module_param(isocMode, int, 0444); |
158 | module_param(video_debug, int, 0444); | 153 | module_param(video_debug, int, 0444); |
159 | module_param(PowerOnAtOpen, int, 0444); | 154 | module_param(PowerOnAtOpen, int, 0444); |
160 | module_param(video_nr, int, 0444); | 155 | module_param(video_nr, int, 0444); |
161 | module_param(radio_nr, int, 0444); | 156 | module_param(radio_nr, int, 0444); |
162 | module_param(vbi_nr, int, 0444); | 157 | module_param(vbi_nr, int, 0444); |
163 | #else // Old Style | ||
164 | MODULE_PARAM(isocMode, "i"); | ||
165 | MODULE_PARM(video_debug, "i"); // Grab the Debug Mode of the device driver | ||
166 | MODULE_PARM(adjustCompression, "i"); // Grab the compression to be adaptive | ||
167 | MODULE_PARM(PowerOnAtOpen, "i"); // Grab the device to power on at startup | ||
168 | MODULE_PARM(SwitchSVideoInput, "i"); // To help people with Black and White output with using s-video input. Some cables and input device are wired differently. | ||
169 | MODULE_PARM(video_nr, "i"); // video_nr option allows to specify a certain /dev/videoX device (like /dev/video0 or /dev/video1 ...) | ||
170 | MODULE_PARM(radio_nr, "i"); // radio_nr option allows to specify a certain /dev/radioX device (like /dev/radio0 or /dev/radio1 ...) | ||
171 | MODULE_PARM(vbi_nr, "i"); // vbi_nr option allows to specify a certain /dev/vbiX device (like /dev/vbi0 or /dev/vbi1 ...) | ||
172 | #endif | ||
173 | 158 | ||
174 | MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)"); | 159 | MODULE_PARM_DESC(isocMode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)"); |
175 | MODULE_PARM_DESC(video_debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)"); | 160 | MODULE_PARM_DESC(video_debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)"); |
@@ -187,19 +172,21 @@ MODULE_VERSION(USBVISION_VERSION_STRING); | |||
187 | MODULE_ALIAS(DRIVER_ALIAS); | 172 | MODULE_ALIAS(DRIVER_ALIAS); |
188 | 173 | ||
189 | 174 | ||
190 | /****************************************************************************************/ | 175 | /*****************************************************************************/ |
191 | /* SYSFS Code - Copied from the stv680.c usb module. */ | 176 | /* SYSFS Code - Copied from the stv680.c usb module. */ |
192 | /* Device information is located at /sys/class/video4linux/video0 */ | 177 | /* Device information is located at /sys/class/video4linux/video0 */ |
193 | /* Device parameters information is located at /sys/module/usbvision */ | 178 | /* Device parameters information is located at /sys/module/usbvision */ |
194 | /* Device USB Information is located at /sys/bus/usb/drivers/USBVision Video Grabber */ | 179 | /* Device USB Information is located at */ |
195 | /****************************************************************************************/ | 180 | /* /sys/bus/usb/drivers/USBVision Video Grabber */ |
181 | /*****************************************************************************/ | ||
196 | 182 | ||
197 | 183 | ||
198 | #define YES_NO(x) ((x) ? "Yes" : "No") | 184 | #define YES_NO(x) ((x) ? "Yes" : "No") |
199 | 185 | ||
200 | static inline struct usb_usbvision *cd_to_usbvision(struct class_device *cd) | 186 | static inline struct usb_usbvision *cd_to_usbvision(struct class_device *cd) |
201 | { | 187 | { |
202 | struct video_device *vdev = container_of(cd, struct video_device, class_dev); | 188 | struct video_device *vdev = |
189 | container_of(cd, struct video_device, class_dev); | ||
203 | return video_get_drvdata(vdev); | 190 | return video_get_drvdata(vdev); |
204 | } | 191 | } |
205 | 192 | ||
@@ -211,15 +198,18 @@ static CLASS_DEVICE_ATTR(version, S_IRUGO, show_version, NULL); | |||
211 | 198 | ||
212 | static ssize_t show_model(struct class_device *cd, char *buf) | 199 | static ssize_t show_model(struct class_device *cd, char *buf) |
213 | { | 200 | { |
214 | struct video_device *vdev = container_of(cd, struct video_device, class_dev); | 201 | struct video_device *vdev = |
202 | container_of(cd, struct video_device, class_dev); | ||
215 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 203 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
216 | return sprintf(buf, "%s\n", usbvision_device_data[usbvision->DevModel].ModelString); | 204 | return sprintf(buf, "%s\n", |
205 | usbvision_device_data[usbvision->DevModel].ModelString); | ||
217 | } | 206 | } |
218 | static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL); | 207 | static CLASS_DEVICE_ATTR(model, S_IRUGO, show_model, NULL); |
219 | 208 | ||
220 | static ssize_t show_hue(struct class_device *cd, char *buf) | 209 | static ssize_t show_hue(struct class_device *cd, char *buf) |
221 | { | 210 | { |
222 | struct video_device *vdev = container_of(cd, struct video_device, class_dev); | 211 | struct video_device *vdev = |
212 | container_of(cd, struct video_device, class_dev); | ||
223 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 213 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
224 | struct v4l2_control ctrl; | 214 | struct v4l2_control ctrl; |
225 | ctrl.id = V4L2_CID_HUE; | 215 | ctrl.id = V4L2_CID_HUE; |
@@ -232,7 +222,8 @@ static CLASS_DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL); | |||
232 | 222 | ||
233 | static ssize_t show_contrast(struct class_device *cd, char *buf) | 223 | static ssize_t show_contrast(struct class_device *cd, char *buf) |
234 | { | 224 | { |
235 | struct video_device *vdev = container_of(cd, struct video_device, class_dev); | 225 | struct video_device *vdev = |
226 | container_of(cd, struct video_device, class_dev); | ||
236 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 227 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
237 | struct v4l2_control ctrl; | 228 | struct v4l2_control ctrl; |
238 | ctrl.id = V4L2_CID_CONTRAST; | 229 | ctrl.id = V4L2_CID_CONTRAST; |
@@ -245,7 +236,8 @@ static CLASS_DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL); | |||
245 | 236 | ||
246 | static ssize_t show_brightness(struct class_device *cd, char *buf) | 237 | static ssize_t show_brightness(struct class_device *cd, char *buf) |
247 | { | 238 | { |
248 | struct video_device *vdev = container_of(cd, struct video_device, class_dev); | 239 | struct video_device *vdev = |
240 | container_of(cd, struct video_device, class_dev); | ||
249 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 241 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
250 | struct v4l2_control ctrl; | 242 | struct v4l2_control ctrl; |
251 | ctrl.id = V4L2_CID_BRIGHTNESS; | 243 | ctrl.id = V4L2_CID_BRIGHTNESS; |
@@ -258,7 +250,8 @@ static CLASS_DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL); | |||
258 | 250 | ||
259 | static ssize_t show_saturation(struct class_device *cd, char *buf) | 251 | static ssize_t show_saturation(struct class_device *cd, char *buf) |
260 | { | 252 | { |
261 | struct video_device *vdev = container_of(cd, struct video_device, class_dev); | 253 | struct video_device *vdev = |
254 | container_of(cd, struct video_device, class_dev); | ||
262 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 255 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
263 | struct v4l2_control ctrl; | 256 | struct v4l2_control ctrl; |
264 | ctrl.id = V4L2_CID_SATURATION; | 257 | ctrl.id = V4L2_CID_SATURATION; |
@@ -271,23 +264,28 @@ static CLASS_DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL); | |||
271 | 264 | ||
272 | static ssize_t show_streaming(struct class_device *cd, char *buf) | 265 | static ssize_t show_streaming(struct class_device *cd, char *buf) |
273 | { | 266 | { |
274 | struct video_device *vdev = container_of(cd, struct video_device, class_dev); | 267 | struct video_device *vdev = |
268 | container_of(cd, struct video_device, class_dev); | ||
275 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 269 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
276 | return sprintf(buf, "%s\n", YES_NO(usbvision->streaming==Stream_On?1:0)); | 270 | return sprintf(buf, "%s\n", |
271 | YES_NO(usbvision->streaming==Stream_On?1:0)); | ||
277 | } | 272 | } |
278 | static CLASS_DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL); | 273 | static CLASS_DEVICE_ATTR(streaming, S_IRUGO, show_streaming, NULL); |
279 | 274 | ||
280 | static ssize_t show_compression(struct class_device *cd, char *buf) | 275 | static ssize_t show_compression(struct class_device *cd, char *buf) |
281 | { | 276 | { |
282 | struct video_device *vdev = container_of(cd, struct video_device, class_dev); | 277 | struct video_device *vdev = |
278 | container_of(cd, struct video_device, class_dev); | ||
283 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 279 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
284 | return sprintf(buf, "%s\n", YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS)); | 280 | return sprintf(buf, "%s\n", |
281 | YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS)); | ||
285 | } | 282 | } |
286 | static CLASS_DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL); | 283 | static CLASS_DEVICE_ATTR(compression, S_IRUGO, show_compression, NULL); |
287 | 284 | ||
288 | static ssize_t show_device_bridge(struct class_device *cd, char *buf) | 285 | static ssize_t show_device_bridge(struct class_device *cd, char *buf) |
289 | { | 286 | { |
290 | struct video_device *vdev = container_of(cd, struct video_device, class_dev); | 287 | struct video_device *vdev = |
288 | container_of(cd, struct video_device, class_dev); | ||
291 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); | 289 | struct usb_usbvision *usbvision = video_get_drvdata(vdev); |
292 | return sprintf(buf, "%d\n", usbvision->bridgeType); | 290 | return sprintf(buf, "%d\n", usbvision->bridgeType); |
293 | } | 291 | } |
@@ -376,7 +374,8 @@ static void usbvision_remove_sysfs(struct video_device *vdev) | |||
376 | static int usbvision_v4l2_open(struct inode *inode, struct file *file) | 374 | static int usbvision_v4l2_open(struct inode *inode, struct file *file) |
377 | { | 375 | { |
378 | struct video_device *dev = video_devdata(file); | 376 | struct video_device *dev = video_devdata(file); |
379 | struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); | 377 | struct usb_usbvision *usbvision = |
378 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
380 | int errCode = 0; | 379 | int errCode = 0; |
381 | 380 | ||
382 | PDEBUG(DBG_IO, "open"); | 381 | PDEBUG(DBG_IO, "open"); |
@@ -390,7 +389,8 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) | |||
390 | /* Allocate memory for the scratch ring buffer */ | 389 | /* Allocate memory for the scratch ring buffer */ |
391 | errCode = usbvision_scratch_alloc(usbvision); | 390 | errCode = usbvision_scratch_alloc(usbvision); |
392 | if (isocMode==ISOC_MODE_COMPRESS) { | 391 | if (isocMode==ISOC_MODE_COMPRESS) { |
393 | /* Allocate intermediate decompression buffers only if needed */ | 392 | /* Allocate intermediate decompression buffers |
393 | only if needed */ | ||
394 | errCode = usbvision_decompress_alloc(usbvision); | 394 | errCode = usbvision_decompress_alloc(usbvision); |
395 | } | 395 | } |
396 | if (errCode) { | 396 | if (errCode) { |
@@ -421,11 +421,10 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) | |||
421 | if (!errCode) { | 421 | if (!errCode) { |
422 | usbvision_begin_streaming(usbvision); | 422 | usbvision_begin_streaming(usbvision); |
423 | errCode = usbvision_init_isoc(usbvision); | 423 | errCode = usbvision_init_isoc(usbvision); |
424 | /* device needs to be initialized before isoc transfer */ | 424 | /* device must be initialized before isoc transfer */ |
425 | usbvision_muxsel(usbvision,0); | 425 | usbvision_muxsel(usbvision,0); |
426 | usbvision->user++; | 426 | usbvision->user++; |
427 | } | 427 | } else { |
428 | else { | ||
429 | if (PowerOnAtOpen) { | 428 | if (PowerOnAtOpen) { |
430 | usbvision_i2c_unregister(usbvision); | 429 | usbvision_i2c_unregister(usbvision); |
431 | usbvision_power_off(usbvision); | 430 | usbvision_power_off(usbvision); |
@@ -456,7 +455,8 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) | |||
456 | static int usbvision_v4l2_close(struct inode *inode, struct file *file) | 455 | static int usbvision_v4l2_close(struct inode *inode, struct file *file) |
457 | { | 456 | { |
458 | struct video_device *dev = video_devdata(file); | 457 | struct video_device *dev = video_devdata(file); |
459 | struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); | 458 | struct usb_usbvision *usbvision = |
459 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
460 | 460 | ||
461 | PDEBUG(DBG_IO, "close"); | 461 | PDEBUG(DBG_IO, "close"); |
462 | down(&usbvision->lock); | 462 | down(&usbvision->lock); |
@@ -473,7 +473,8 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file) | |||
473 | usbvision->user--; | 473 | usbvision->user--; |
474 | 474 | ||
475 | if (PowerOnAtOpen) { | 475 | if (PowerOnAtOpen) { |
476 | /* power off in a little while to avoid off/on every close/open short sequences */ | 476 | /* power off in a little while |
477 | to avoid off/on every close/open short sequences */ | ||
477 | usbvision_set_powerOffTimer(usbvision); | 478 | usbvision_set_powerOffTimer(usbvision); |
478 | usbvision->initialized = 0; | 479 | usbvision->initialized = 0; |
479 | } | 480 | } |
@@ -498,583 +499,612 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file) | |||
498 | * This is part of Video 4 Linux API. The procedure handles ioctl() calls. | 499 | * This is part of Video 4 Linux API. The procedure handles ioctl() calls. |
499 | * | 500 | * |
500 | */ | 501 | */ |
501 | static int usbvision_v4l2_do_ioctl(struct inode *inode, struct file *file, | 502 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
502 | unsigned int cmd, void *arg) | 503 | static int vidioc_g_register (struct file *file, void *priv, |
504 | struct v4l2_register *reg) | ||
503 | { | 505 | { |
504 | struct video_device *dev = video_devdata(file); | 506 | struct video_device *dev = video_devdata(file); |
505 | struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); | 507 | struct usb_usbvision *usbvision = |
506 | 508 | (struct usb_usbvision *) video_get_drvdata(dev); | |
507 | if (!USBVISION_IS_OPERATIONAL(usbvision)) | 509 | int errCode; |
508 | return -EFAULT; | ||
509 | 510 | ||
510 | switch (cmd) { | 511 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) |
512 | return -EINVAL; | ||
513 | /* NT100x has a 8-bit register space */ | ||
514 | errCode = usbvision_read_reg(usbvision, reg->reg&0xff); | ||
515 | if (errCode < 0) { | ||
516 | err("%s: VIDIOC_DBG_G_REGISTER failed: error %d", | ||
517 | __FUNCTION__, errCode); | ||
518 | return errCode; | ||
519 | } | ||
520 | return 0; | ||
521 | } | ||
511 | 522 | ||
512 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 523 | static int vidioc_s_register (struct file *file, void *priv, |
513 | /* ioctls to allow direct acces to the NT100x registers */ | 524 | struct v4l2_register *reg) |
514 | case VIDIOC_DBG_G_REGISTER: | 525 | { |
515 | case VIDIOC_DBG_S_REGISTER: | 526 | struct video_device *dev = video_devdata(file); |
516 | { | 527 | struct usb_usbvision *usbvision = |
517 | struct v4l2_register *reg = arg; | 528 | (struct usb_usbvision *) video_get_drvdata(dev); |
518 | int errCode; | 529 | int errCode; |
519 | |||
520 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | ||
521 | return -EINVAL; | ||
522 | if (!capable(CAP_SYS_ADMIN)) | ||
523 | return -EPERM; | ||
524 | /* NT100x has a 8-bit register space */ | ||
525 | if (cmd == VIDIOC_DBG_G_REGISTER) | ||
526 | errCode = usbvision_read_reg(usbvision, reg->reg&0xff); | ||
527 | else | ||
528 | errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); | ||
529 | if (errCode < 0) { | ||
530 | err("%s: VIDIOC_DBG_%c_REGISTER failed: error %d", __FUNCTION__, | ||
531 | cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S', errCode); | ||
532 | return errCode; | ||
533 | } | ||
534 | if (cmd == VIDIOC_DBG_S_REGISTER) | ||
535 | reg->val = (u8)errCode; | ||
536 | 530 | ||
537 | PDEBUG(DBG_IOCTL, "VIDIOC_DBG_%c_REGISTER reg=0x%02X, value=0x%02X", | 531 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) |
538 | cmd == VIDIOC_DBG_G_REGISTER ? 'G' : 'S', | 532 | return -EINVAL; |
539 | (unsigned int)reg->reg, (unsigned int)reg->val); | 533 | /* NT100x has a 8-bit register space */ |
540 | return 0; | 534 | reg->val = (u8)usbvision_write_reg(usbvision, reg->reg&0xff, reg->val); |
541 | } | 535 | if (reg->val < 0) { |
536 | err("%s: VIDIOC_DBG_S_REGISTER failed: error %d", | ||
537 | __FUNCTION__, errCode); | ||
538 | return errCode; | ||
539 | } | ||
540 | return 0; | ||
541 | } | ||
542 | #endif | 542 | #endif |
543 | case VIDIOC_QUERYCAP: | 543 | |
544 | { | 544 | static int vidioc_querycap (struct file *file, void *priv, |
545 | struct v4l2_capability *vc=arg; | 545 | struct v4l2_capability *vc) |
546 | 546 | { | |
547 | memset(vc, 0, sizeof(*vc)); | 547 | struct video_device *dev = video_devdata(file); |
548 | strlcpy(vc->driver, "USBVision", sizeof(vc->driver)); | 548 | struct usb_usbvision *usbvision = |
549 | strlcpy(vc->card, usbvision_device_data[usbvision->DevModel].ModelString, | 549 | (struct usb_usbvision *) video_get_drvdata(dev); |
550 | sizeof(vc->card)); | 550 | |
551 | strlcpy(vc->bus_info, usbvision->dev->dev.bus_id, | 551 | strlcpy(vc->driver, "USBVision", sizeof(vc->driver)); |
552 | sizeof(vc->bus_info)); | 552 | strlcpy(vc->card, |
553 | vc->version = USBVISION_DRIVER_VERSION; | 553 | usbvision_device_data[usbvision->DevModel].ModelString, |
554 | vc->capabilities = V4L2_CAP_VIDEO_CAPTURE | | 554 | sizeof(vc->card)); |
555 | V4L2_CAP_AUDIO | | 555 | strlcpy(vc->bus_info, usbvision->dev->dev.bus_id, |
556 | V4L2_CAP_READWRITE | | 556 | sizeof(vc->bus_info)); |
557 | V4L2_CAP_STREAMING | | 557 | vc->version = USBVISION_DRIVER_VERSION; |
558 | (usbvision->have_tuner ? V4L2_CAP_TUNER : 0); | 558 | vc->capabilities = V4L2_CAP_VIDEO_CAPTURE | |
559 | PDEBUG(DBG_IOCTL, "VIDIOC_QUERYCAP"); | 559 | V4L2_CAP_AUDIO | |
560 | return 0; | 560 | V4L2_CAP_READWRITE | |
561 | } | 561 | V4L2_CAP_STREAMING | |
562 | case VIDIOC_ENUMINPUT: | 562 | (usbvision->have_tuner ? V4L2_CAP_TUNER : 0); |
563 | { | 563 | return 0; |
564 | struct v4l2_input *vi = arg; | 564 | } |
565 | int chan; | 565 | |
566 | 566 | static int vidioc_enum_input (struct file *file, void *priv, | |
567 | if ((vi->index >= usbvision->video_inputs) || (vi->index < 0) ) | 567 | struct v4l2_input *vi) |
568 | return -EINVAL; | 568 | { |
569 | if (usbvision->have_tuner) { | 569 | struct video_device *dev = video_devdata(file); |
570 | chan = vi->index; | 570 | struct usb_usbvision *usbvision = |
571 | } | 571 | (struct usb_usbvision *) video_get_drvdata(dev); |
572 | else { | 572 | int chan; |
573 | chan = vi->index + 1; //skip Television string | 573 | |
574 | } | 574 | if ((vi->index >= usbvision->video_inputs) || (vi->index < 0) ) |
575 | switch(chan) { | 575 | return -EINVAL; |
576 | case 0: | 576 | if (usbvision->have_tuner) { |
577 | if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) { | 577 | chan = vi->index; |
578 | strcpy(vi->name, "White Video Input"); | 578 | } else { |
579 | } | 579 | chan = vi->index + 1; /*skip Television string*/ |
580 | else { | 580 | } |
581 | strcpy(vi->name, "Television"); | 581 | /* Determine the requested input characteristics |
582 | vi->type = V4L2_INPUT_TYPE_TUNER; | 582 | specific for each usbvision card model */ |
583 | vi->audioset = 1; | 583 | switch(chan) { |
584 | vi->tuner = chan; | 584 | case 0: |
585 | vi->std = V4L2_STD_PAL | V4L2_STD_NTSC | V4L2_STD_SECAM; | 585 | if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) { |
586 | } | 586 | strcpy(vi->name, "White Video Input"); |
587 | break; | 587 | } else { |
588 | case 1: | 588 | strcpy(vi->name, "Television"); |
589 | vi->type = V4L2_INPUT_TYPE_CAMERA; | 589 | vi->type = V4L2_INPUT_TYPE_TUNER; |
590 | if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) { | 590 | vi->audioset = 1; |
591 | strcpy(vi->name, "Green Video Input"); | 591 | vi->tuner = chan; |
592 | } | 592 | vi->std = USBVISION_NORMS; |
593 | else { | ||
594 | strcpy(vi->name, "Composite Video Input"); | ||
595 | } | ||
596 | vi->std = V4L2_STD_PAL; | ||
597 | break; | ||
598 | case 2: | ||
599 | vi->type = V4L2_INPUT_TYPE_CAMERA; | ||
600 | if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) { | ||
601 | strcpy(vi->name, "Yellow Video Input"); | ||
602 | } | ||
603 | else { | ||
604 | strcpy(vi->name, "S-Video Input"); | ||
605 | } | ||
606 | vi->std = V4L2_STD_PAL; | ||
607 | break; | ||
608 | case 3: | ||
609 | vi->type = V4L2_INPUT_TYPE_CAMERA; | ||
610 | strcpy(vi->name, "Red Video Input"); | ||
611 | vi->std = V4L2_STD_PAL; | ||
612 | break; | ||
613 | } | ||
614 | PDEBUG(DBG_IOCTL, "VIDIOC_ENUMINPUT name=%s:%d tuners=%d type=%d norm=%x", | ||
615 | vi->name, vi->index, vi->tuner,vi->type,(int)vi->std); | ||
616 | return 0; | ||
617 | } | ||
618 | case VIDIOC_ENUMSTD: | ||
619 | { | ||
620 | struct v4l2_standard *e = arg; | ||
621 | unsigned int i; | ||
622 | int ret; | ||
623 | |||
624 | i = e->index; | ||
625 | if (i >= TVNORMS) | ||
626 | return -EINVAL; | ||
627 | ret = v4l2_video_std_construct(e, tvnorms[e->index].id, | ||
628 | tvnorms[e->index].name); | ||
629 | e->index = i; | ||
630 | if (ret < 0) | ||
631 | return ret; | ||
632 | return 0; | ||
633 | } | 593 | } |
634 | case VIDIOC_G_INPUT: | 594 | break; |
635 | { | 595 | case 1: |
636 | int *input = arg; | 596 | vi->type = V4L2_INPUT_TYPE_CAMERA; |
637 | *input = usbvision->ctl_input; | 597 | if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) { |
638 | return 0; | 598 | strcpy(vi->name, "Green Video Input"); |
599 | } else { | ||
600 | strcpy(vi->name, "Composite Video Input"); | ||
639 | } | 601 | } |
640 | case VIDIOC_S_INPUT: | 602 | vi->std = V4L2_STD_PAL; |
641 | { | 603 | break; |
642 | int *input = arg; | 604 | case 2: |
643 | if ((*input >= usbvision->video_inputs) || (*input < 0) ) | 605 | vi->type = V4L2_INPUT_TYPE_CAMERA; |
644 | return -EINVAL; | 606 | if (usbvision_device_data[usbvision->DevModel].VideoChannels == 4) { |
645 | usbvision->ctl_input = *input; | 607 | strcpy(vi->name, "Yellow Video Input"); |
646 | 608 | } else { | |
647 | down(&usbvision->lock); | 609 | strcpy(vi->name, "S-Video Input"); |
648 | usbvision_muxsel(usbvision, usbvision->ctl_input); | ||
649 | usbvision_set_input(usbvision); | ||
650 | usbvision_set_output(usbvision, usbvision->curwidth, usbvision->curheight); | ||
651 | up(&usbvision->lock); | ||
652 | return 0; | ||
653 | } | 610 | } |
654 | case VIDIOC_G_STD: | 611 | vi->std = V4L2_STD_PAL; |
655 | { | 612 | break; |
656 | v4l2_std_id *id = arg; | 613 | case 3: |
614 | vi->type = V4L2_INPUT_TYPE_CAMERA; | ||
615 | strcpy(vi->name, "Red Video Input"); | ||
616 | vi->std = V4L2_STD_PAL; | ||
617 | break; | ||
618 | } | ||
619 | return 0; | ||
620 | } | ||
657 | 621 | ||
658 | *id = usbvision->tvnorm->id; | 622 | static int vidioc_g_input (struct file *file, void *priv, unsigned int *input) |
623 | { | ||
624 | struct video_device *dev = video_devdata(file); | ||
625 | struct usb_usbvision *usbvision = | ||
626 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
659 | 627 | ||
660 | PDEBUG(DBG_IOCTL, "VIDIOC_G_STD std_id=%s", usbvision->tvnorm->name); | 628 | *input = usbvision->ctl_input; |
661 | return 0; | 629 | return 0; |
662 | } | 630 | } |
663 | case VIDIOC_S_STD: | ||
664 | { | ||
665 | v4l2_std_id *id = arg; | ||
666 | unsigned int i; | ||
667 | |||
668 | for (i = 0; i < TVNORMS; i++) | ||
669 | if (*id == tvnorms[i].id) | ||
670 | break; | ||
671 | if (i == TVNORMS) | ||
672 | for (i = 0; i < TVNORMS; i++) | ||
673 | if (*id & tvnorms[i].id) | ||
674 | break; | ||
675 | if (i == TVNORMS) | ||
676 | return -EINVAL; | ||
677 | |||
678 | down(&usbvision->lock); | ||
679 | usbvision->tvnorm = &tvnorms[i]; | ||
680 | |||
681 | call_i2c_clients(usbvision, VIDIOC_S_STD, | ||
682 | &usbvision->tvnorm->id); | ||
683 | 631 | ||
684 | up(&usbvision->lock); | 632 | static int vidioc_s_input (struct file *file, void *priv, unsigned int input) |
633 | { | ||
634 | struct video_device *dev = video_devdata(file); | ||
635 | struct usb_usbvision *usbvision = | ||
636 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
685 | 637 | ||
686 | PDEBUG(DBG_IOCTL, "VIDIOC_S_STD std_id=%s", usbvision->tvnorm->name); | 638 | if ((input >= usbvision->video_inputs) || (input < 0) ) |
687 | return 0; | 639 | return -EINVAL; |
688 | } | ||
689 | case VIDIOC_G_TUNER: | ||
690 | { | ||
691 | struct v4l2_tuner *vt = arg; | ||
692 | |||
693 | if (!usbvision->have_tuner || vt->index) // Only tuner 0 | ||
694 | return -EINVAL; | ||
695 | strcpy(vt->name, "Television"); | ||
696 | /* Let clients fill in the remainder of this struct */ | ||
697 | call_i2c_clients(usbvision,VIDIOC_G_TUNER,vt); | ||
698 | |||
699 | PDEBUG(DBG_IOCTL, "VIDIOC_G_TUNER signal=%x, afc=%x",vt->signal,vt->afc); | ||
700 | return 0; | ||
701 | } | ||
702 | case VIDIOC_S_TUNER: | ||
703 | { | ||
704 | struct v4l2_tuner *vt = arg; | ||
705 | |||
706 | // Only no or one tuner for now | ||
707 | if (!usbvision->have_tuner || vt->index) | ||
708 | return -EINVAL; | ||
709 | /* let clients handle this */ | ||
710 | call_i2c_clients(usbvision,VIDIOC_S_TUNER,vt); | ||
711 | |||
712 | PDEBUG(DBG_IOCTL, "VIDIOC_S_TUNER"); | ||
713 | return 0; | ||
714 | } | ||
715 | case VIDIOC_G_FREQUENCY: | ||
716 | { | ||
717 | struct v4l2_frequency *freq = arg; | ||
718 | |||
719 | freq->tuner = 0; // Only one tuner | ||
720 | freq->type = V4L2_TUNER_ANALOG_TV; | ||
721 | freq->frequency = usbvision->freq; | ||
722 | PDEBUG(DBG_IOCTL, "VIDIOC_G_FREQUENCY freq=0x%X", (unsigned)freq->frequency); | ||
723 | return 0; | ||
724 | } | ||
725 | case VIDIOC_S_FREQUENCY: | ||
726 | { | ||
727 | struct v4l2_frequency *freq = arg; | ||
728 | |||
729 | // Only no or one tuner for now | ||
730 | if (!usbvision->have_tuner || freq->tuner) | ||
731 | return -EINVAL; | ||
732 | |||
733 | usbvision->freq = freq->frequency; | ||
734 | call_i2c_clients(usbvision, cmd, freq); | ||
735 | PDEBUG(DBG_IOCTL, "VIDIOC_S_FREQUENCY freq=0x%X", (unsigned)freq->frequency); | ||
736 | return 0; | ||
737 | } | ||
738 | case VIDIOC_G_AUDIO: | ||
739 | { | ||
740 | struct v4l2_audio *v = arg; | ||
741 | memset(v,0, sizeof(v)); | ||
742 | strcpy(v->name, "TV"); | ||
743 | PDEBUG(DBG_IOCTL, "VIDIOC_G_AUDIO"); | ||
744 | return 0; | ||
745 | } | ||
746 | case VIDIOC_S_AUDIO: | ||
747 | { | ||
748 | struct v4l2_audio *v = arg; | ||
749 | if(v->index) { | ||
750 | return -EINVAL; | ||
751 | } | ||
752 | PDEBUG(DBG_IOCTL, "VIDIOC_S_AUDIO"); | ||
753 | return 0; | ||
754 | } | ||
755 | case VIDIOC_QUERYCTRL: | ||
756 | { | ||
757 | struct v4l2_queryctrl *ctrl = arg; | ||
758 | int id=ctrl->id; | ||
759 | 640 | ||
760 | memset(ctrl,0,sizeof(*ctrl)); | 641 | down(&usbvision->lock); |
761 | ctrl->id=id; | 642 | usbvision_muxsel(usbvision, input); |
643 | usbvision_set_input(usbvision); | ||
644 | usbvision_set_output(usbvision, | ||
645 | usbvision->curwidth, | ||
646 | usbvision->curheight); | ||
647 | up(&usbvision->lock); | ||
648 | return 0; | ||
649 | } | ||
762 | 650 | ||
763 | call_i2c_clients(usbvision, cmd, arg); | 651 | static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id) |
652 | { | ||
653 | struct video_device *dev = video_devdata(file); | ||
654 | struct usb_usbvision *usbvision = | ||
655 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
656 | usbvision->tvnormId=*id; | ||
764 | 657 | ||
765 | if (ctrl->type) | 658 | down(&usbvision->lock); |
766 | return 0; | 659 | call_i2c_clients(usbvision, VIDIOC_S_STD, |
767 | else | 660 | &usbvision->tvnormId); |
768 | return -EINVAL; | 661 | up(&usbvision->lock); |
662 | /* propagate the change to the decoder */ | ||
663 | usbvision_muxsel(usbvision, usbvision->ctl_input); | ||
769 | 664 | ||
770 | PDEBUG(DBG_IOCTL,"VIDIOC_QUERYCTRL id=%x value=%x",ctrl->id,ctrl->type); | 665 | return 0; |
771 | } | 666 | } |
772 | case VIDIOC_G_CTRL: | ||
773 | { | ||
774 | struct v4l2_control *ctrl = arg; | ||
775 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl); | ||
776 | PDEBUG(DBG_IOCTL,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value); | ||
777 | return 0; | ||
778 | } | ||
779 | case VIDIOC_S_CTRL: | ||
780 | { | ||
781 | struct v4l2_control *ctrl = arg; | ||
782 | 667 | ||
783 | PDEBUG(DBG_IOCTL, "VIDIOC_S_CTRL id=%x value=%x",ctrl->id,ctrl->value); | 668 | static int vidioc_g_tuner (struct file *file, void *priv, |
784 | call_i2c_clients(usbvision, VIDIOC_S_CTRL, ctrl); | 669 | struct v4l2_tuner *vt) |
785 | return 0; | 670 | { |
786 | } | 671 | struct video_device *dev = video_devdata(file); |
787 | case VIDIOC_REQBUFS: | 672 | struct usb_usbvision *usbvision = |
788 | { | 673 | (struct usb_usbvision *) video_get_drvdata(dev); |
789 | struct v4l2_requestbuffers *vr = arg; | ||
790 | int ret; | ||
791 | 674 | ||
792 | RESTRICT_TO_RANGE(vr->count,1,USBVISION_NUMFRAMES); | 675 | if (!usbvision->have_tuner || vt->index) // Only tuner 0 |
676 | return -EINVAL; | ||
677 | if(usbvision->radio) { | ||
678 | strcpy(vt->name, "Radio"); | ||
679 | vt->type = V4L2_TUNER_RADIO; | ||
680 | } else { | ||
681 | strcpy(vt->name, "Television"); | ||
682 | } | ||
683 | /* Let clients fill in the remainder of this struct */ | ||
684 | call_i2c_clients(usbvision,VIDIOC_G_TUNER,vt); | ||
793 | 685 | ||
794 | // Check input validity : the user must do a VIDEO CAPTURE and MMAP method. | 686 | return 0; |
795 | if((vr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) || | 687 | } |
796 | (vr->memory != V4L2_MEMORY_MMAP)) | ||
797 | return -EINVAL; | ||
798 | 688 | ||
799 | if(usbvision->streaming == Stream_On) { | 689 | static int vidioc_s_tuner (struct file *file, void *priv, |
800 | if ((ret = usbvision_stream_interrupt(usbvision))) | 690 | struct v4l2_tuner *vt) |
801 | return ret; | 691 | { |
802 | } | 692 | struct video_device *dev = video_devdata(file); |
693 | struct usb_usbvision *usbvision = | ||
694 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
803 | 695 | ||
804 | usbvision_frames_free(usbvision); | 696 | // Only no or one tuner for now |
805 | usbvision_empty_framequeues(usbvision); | 697 | if (!usbvision->have_tuner || vt->index) |
806 | vr->count = usbvision_frames_alloc(usbvision,vr->count); | 698 | return -EINVAL; |
699 | /* let clients handle this */ | ||
700 | call_i2c_clients(usbvision,VIDIOC_S_TUNER,vt); | ||
807 | 701 | ||
808 | usbvision->curFrame = NULL; | 702 | return 0; |
703 | } | ||
809 | 704 | ||
810 | PDEBUG(DBG_IOCTL, "VIDIOC_REQBUFS count=%d",vr->count); | 705 | static int vidioc_g_frequency (struct file *file, void *priv, |
811 | return 0; | 706 | struct v4l2_frequency *freq) |
812 | } | 707 | { |
813 | case VIDIOC_QUERYBUF: | 708 | struct video_device *dev = video_devdata(file); |
814 | { | 709 | struct usb_usbvision *usbvision = |
815 | struct v4l2_buffer *vb = arg; | 710 | (struct usb_usbvision *) video_get_drvdata(dev); |
816 | struct usbvision_frame *frame; | ||
817 | 711 | ||
818 | // FIXME : must control that buffers are mapped (VIDIOC_REQBUFS has been called) | 712 | freq->tuner = 0; // Only one tuner |
713 | if(usbvision->radio) { | ||
714 | freq->type = V4L2_TUNER_RADIO; | ||
715 | } else { | ||
716 | freq->type = V4L2_TUNER_ANALOG_TV; | ||
717 | } | ||
718 | freq->frequency = usbvision->freq; | ||
819 | 719 | ||
820 | if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { | 720 | return 0; |
821 | return -EINVAL; | 721 | } |
822 | } | ||
823 | if(vb->index>=usbvision->num_frames) { | ||
824 | return -EINVAL; | ||
825 | } | ||
826 | // Updating the corresponding frame state | ||
827 | vb->flags = 0; | ||
828 | frame = &usbvision->frame[vb->index]; | ||
829 | if(frame->grabstate >= FrameState_Ready) | ||
830 | vb->flags |= V4L2_BUF_FLAG_QUEUED; | ||
831 | if(frame->grabstate >= FrameState_Done) | ||
832 | vb->flags |= V4L2_BUF_FLAG_DONE; | ||
833 | if(frame->grabstate == FrameState_Unused) | ||
834 | vb->flags |= V4L2_BUF_FLAG_MAPPED; | ||
835 | vb->memory = V4L2_MEMORY_MMAP; | ||
836 | |||
837 | vb->m.offset = vb->index*PAGE_ALIGN(usbvision->max_frame_size); | ||
838 | |||
839 | vb->memory = V4L2_MEMORY_MMAP; | ||
840 | vb->field = V4L2_FIELD_NONE; | ||
841 | vb->length = usbvision->curwidth*usbvision->curheight*usbvision->palette.bytes_per_pixel; | ||
842 | vb->timestamp = usbvision->frame[vb->index].timestamp; | ||
843 | vb->sequence = usbvision->frame[vb->index].sequence; | ||
844 | return 0; | ||
845 | } | ||
846 | case VIDIOC_QBUF: | ||
847 | { | ||
848 | struct v4l2_buffer *vb = arg; | ||
849 | struct usbvision_frame *frame; | ||
850 | unsigned long lock_flags; | ||
851 | |||
852 | // FIXME : works only on VIDEO_CAPTURE MODE, MMAP. | ||
853 | if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { | ||
854 | return -EINVAL; | ||
855 | } | ||
856 | if(vb->index>=usbvision->num_frames) { | ||
857 | return -EINVAL; | ||
858 | } | ||
859 | 722 | ||
860 | frame = &usbvision->frame[vb->index]; | 723 | static int vidioc_s_frequency (struct file *file, void *priv, |
724 | struct v4l2_frequency *freq) | ||
725 | { | ||
726 | struct video_device *dev = video_devdata(file); | ||
727 | struct usb_usbvision *usbvision = | ||
728 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
861 | 729 | ||
862 | if (frame->grabstate != FrameState_Unused) { | 730 | // Only no or one tuner for now |
863 | return -EAGAIN; | 731 | if (!usbvision->have_tuner || freq->tuner) |
864 | } | 732 | return -EINVAL; |
865 | 733 | ||
866 | /* Mark it as ready and enqueue frame */ | 734 | usbvision->freq = freq->frequency; |
867 | frame->grabstate = FrameState_Ready; | 735 | call_i2c_clients(usbvision, VIDIOC_S_FREQUENCY, freq); |
868 | frame->scanstate = ScanState_Scanning; | ||
869 | frame->scanlength = 0; /* Accumulated in usbvision_parse_data() */ | ||
870 | 736 | ||
871 | vb->flags &= ~V4L2_BUF_FLAG_DONE; | 737 | return 0; |
738 | } | ||
872 | 739 | ||
873 | /* set v4l2_format index */ | 740 | static int vidioc_g_audio (struct file *file, void *priv, struct v4l2_audio *a) |
874 | frame->v4l2_format = usbvision->palette; | 741 | { |
742 | struct video_device *dev = video_devdata(file); | ||
743 | struct usb_usbvision *usbvision = | ||
744 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
875 | 745 | ||
876 | spin_lock_irqsave(&usbvision->queue_lock, lock_flags); | 746 | memset(a,0,sizeof(*a)); |
877 | list_add_tail(&usbvision->frame[vb->index].frame, &usbvision->inqueue); | 747 | if(usbvision->radio) { |
878 | spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); | 748 | strcpy(a->name,"Radio"); |
749 | } else { | ||
750 | strcpy(a->name, "TV"); | ||
751 | } | ||
879 | 752 | ||
880 | PDEBUG(DBG_IOCTL, "VIDIOC_QBUF frame #%d",vb->index); | 753 | return 0; |
881 | return 0; | 754 | } |
882 | } | ||
883 | case VIDIOC_DQBUF: | ||
884 | { | ||
885 | struct v4l2_buffer *vb = arg; | ||
886 | int ret; | ||
887 | struct usbvision_frame *f; | ||
888 | unsigned long lock_flags; | ||
889 | |||
890 | if (vb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
891 | return -EINVAL; | ||
892 | |||
893 | if (list_empty(&(usbvision->outqueue))) { | ||
894 | if (usbvision->streaming == Stream_Idle) | ||
895 | return -EINVAL; | ||
896 | ret = wait_event_interruptible | ||
897 | (usbvision->wait_frame, | ||
898 | !list_empty(&(usbvision->outqueue))); | ||
899 | if (ret) | ||
900 | return ret; | ||
901 | } | ||
902 | 755 | ||
903 | spin_lock_irqsave(&usbvision->queue_lock, lock_flags); | 756 | static int vidioc_s_audio (struct file *file, void *fh, |
904 | f = list_entry(usbvision->outqueue.next, | 757 | struct v4l2_audio *a) |
905 | struct usbvision_frame, frame); | 758 | { |
906 | list_del(usbvision->outqueue.next); | 759 | if(a->index) { |
907 | spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); | 760 | return -EINVAL; |
908 | 761 | } | |
909 | f->grabstate = FrameState_Unused; | ||
910 | |||
911 | vb->memory = V4L2_MEMORY_MMAP; | ||
912 | vb->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE; | ||
913 | vb->index = f->index; | ||
914 | vb->sequence = f->sequence; | ||
915 | vb->timestamp = f->timestamp; | ||
916 | vb->field = V4L2_FIELD_NONE; | ||
917 | vb->bytesused = f->scanlength; | ||
918 | |||
919 | return 0; | ||
920 | } | ||
921 | case VIDIOC_STREAMON: | ||
922 | { | ||
923 | int b=V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
924 | 762 | ||
925 | usbvision->streaming = Stream_On; | 763 | return 0; |
764 | } | ||
926 | 765 | ||
927 | call_i2c_clients(usbvision,VIDIOC_STREAMON , &b); | 766 | static int vidioc_queryctrl (struct file *file, void *priv, |
767 | struct v4l2_queryctrl *ctrl) | ||
768 | { | ||
769 | struct video_device *dev = video_devdata(file); | ||
770 | struct usb_usbvision *usbvision = | ||
771 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
772 | int id=ctrl->id; | ||
928 | 773 | ||
929 | PDEBUG(DBG_IOCTL, "VIDIOC_STREAMON"); | 774 | memset(ctrl,0,sizeof(*ctrl)); |
775 | ctrl->id=id; | ||
930 | 776 | ||
931 | return 0; | 777 | call_i2c_clients(usbvision, VIDIOC_QUERYCTRL, ctrl); |
932 | } | ||
933 | case VIDIOC_STREAMOFF: | ||
934 | { | ||
935 | int *type = arg; | ||
936 | int b=V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
937 | |||
938 | if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
939 | return -EINVAL; | ||
940 | |||
941 | if(usbvision->streaming == Stream_On) { | ||
942 | usbvision_stream_interrupt(usbvision); | ||
943 | // Stop all video streamings | ||
944 | call_i2c_clients(usbvision,VIDIOC_STREAMOFF , &b); | ||
945 | } | ||
946 | usbvision_empty_framequeues(usbvision); | ||
947 | 778 | ||
948 | PDEBUG(DBG_IOCTL, "VIDIOC_STREAMOFF"); | 779 | if (!ctrl->type) |
949 | return 0; | 780 | return -EINVAL; |
950 | } | ||
951 | case VIDIOC_ENUM_FMT: | ||
952 | { | ||
953 | struct v4l2_fmtdesc *vfd = arg; | ||
954 | 781 | ||
955 | if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) { | 782 | return 0; |
956 | return -EINVAL; | 783 | } |
957 | } | 784 | |
958 | vfd->flags = 0; | 785 | static int vidioc_g_ctrl (struct file *file, void *priv, |
959 | vfd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 786 | struct v4l2_control *ctrl) |
960 | strcpy(vfd->description,usbvision_v4l2_format[vfd->index].desc); | 787 | { |
961 | vfd->pixelformat = usbvision_v4l2_format[vfd->index].format; | 788 | struct video_device *dev = video_devdata(file); |
962 | memset(vfd->reserved, 0, sizeof(vfd->reserved)); | 789 | struct usb_usbvision *usbvision = |
963 | return 0; | 790 | (struct usb_usbvision *) video_get_drvdata(dev); |
964 | } | 791 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl); |
965 | case VIDIOC_G_FMT: | 792 | |
966 | { | 793 | return 0; |
967 | struct v4l2_format *vf = arg; | 794 | } |
968 | 795 | ||
969 | switch (vf->type) { | 796 | static int vidioc_s_ctrl (struct file *file, void *priv, |
970 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 797 | struct v4l2_control *ctrl) |
971 | { | 798 | { |
972 | vf->fmt.pix.width = usbvision->curwidth; | 799 | struct video_device *dev = video_devdata(file); |
973 | vf->fmt.pix.height = usbvision->curheight; | 800 | struct usb_usbvision *usbvision = |
974 | vf->fmt.pix.pixelformat = usbvision->palette.format; | 801 | (struct usb_usbvision *) video_get_drvdata(dev); |
975 | vf->fmt.pix.bytesperline = usbvision->curwidth*usbvision->palette.bytes_per_pixel; | 802 | call_i2c_clients(usbvision, VIDIOC_S_CTRL, ctrl); |
976 | vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*usbvision->curheight; | 803 | |
977 | vf->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 804 | return 0; |
978 | vf->fmt.pix.field = V4L2_FIELD_NONE; /* Always progressive image */ | 805 | } |
979 | PDEBUG(DBG_IOCTL, "VIDIOC_G_FMT w=%d, h=%d, format=%s", | 806 | |
980 | vf->fmt.pix.width, vf->fmt.pix.height,usbvision->palette.desc); | 807 | static int vidioc_reqbufs (struct file *file, |
981 | return 0; | 808 | void *priv, struct v4l2_requestbuffers *vr) |
982 | } | 809 | { |
983 | default: | 810 | struct video_device *dev = video_devdata(file); |
984 | PDEBUG(DBG_IOCTL, "VIDIOC_G_FMT invalid type %d",vf->type); | 811 | struct usb_usbvision *usbvision = |
985 | return -EINVAL; | 812 | (struct usb_usbvision *) video_get_drvdata(dev); |
986 | } | 813 | int ret; |
987 | return 0; | 814 | |
988 | } | 815 | RESTRICT_TO_RANGE(vr->count,1,USBVISION_NUMFRAMES); |
989 | case VIDIOC_TRY_FMT: | 816 | |
990 | case VIDIOC_S_FMT: | 817 | /* Check input validity: |
991 | { | 818 | the user must do a VIDEO CAPTURE and MMAP method. */ |
992 | struct v4l2_format *vf = arg; | 819 | if((vr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) || |
993 | int formatIdx,ret; | 820 | (vr->memory != V4L2_MEMORY_MMAP)) |
994 | 821 | return -EINVAL; | |
995 | switch(vf->type) { | 822 | |
996 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 823 | if(usbvision->streaming == Stream_On) { |
997 | { | 824 | if ((ret = usbvision_stream_interrupt(usbvision))) |
998 | /* Find requested format in available ones */ | 825 | return ret; |
999 | for(formatIdx=0;formatIdx<USBVISION_SUPPORTED_PALETTES;formatIdx++) { | ||
1000 | if(vf->fmt.pix.pixelformat == usbvision_v4l2_format[formatIdx].format) { | ||
1001 | usbvision->palette = usbvision_v4l2_format[formatIdx]; | ||
1002 | break; | ||
1003 | } | ||
1004 | } | ||
1005 | /* robustness */ | ||
1006 | if(formatIdx == USBVISION_SUPPORTED_PALETTES) { | ||
1007 | return -EINVAL; | ||
1008 | } | ||
1009 | RESTRICT_TO_RANGE(vf->fmt.pix.width, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH); | ||
1010 | RESTRICT_TO_RANGE(vf->fmt.pix.height, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT); | ||
1011 | |||
1012 | vf->fmt.pix.bytesperline = vf->fmt.pix.width*usbvision->palette.bytes_per_pixel; | ||
1013 | vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*vf->fmt.pix.height; | ||
1014 | |||
1015 | if(cmd == VIDIOC_TRY_FMT) { | ||
1016 | PDEBUG(DBG_IOCTL, "VIDIOC_TRY_FMT grabdisplay w=%d, h=%d, format=%s", | ||
1017 | vf->fmt.pix.width, vf->fmt.pix.height,usbvision->palette.desc); | ||
1018 | return 0; | ||
1019 | } | ||
1020 | |||
1021 | /* stop io in case it is already in progress */ | ||
1022 | if(usbvision->streaming == Stream_On) { | ||
1023 | if ((ret = usbvision_stream_interrupt(usbvision))) | ||
1024 | return ret; | ||
1025 | } | ||
1026 | usbvision_frames_free(usbvision); | ||
1027 | usbvision_empty_framequeues(usbvision); | ||
1028 | |||
1029 | usbvision->curFrame = NULL; | ||
1030 | |||
1031 | // by now we are committed to the new data... | ||
1032 | down(&usbvision->lock); | ||
1033 | usbvision_set_output(usbvision, vf->fmt.pix.width, vf->fmt.pix.height); | ||
1034 | up(&usbvision->lock); | ||
1035 | |||
1036 | PDEBUG(DBG_IOCTL, "VIDIOC_S_FMT grabdisplay w=%d, h=%d, format=%s", | ||
1037 | vf->fmt.pix.width, vf->fmt.pix.height,usbvision->palette.desc); | ||
1038 | return 0; | ||
1039 | } | ||
1040 | default: | ||
1041 | return -EINVAL; | ||
1042 | } | ||
1043 | } | ||
1044 | default: | ||
1045 | return -ENOIOCTLCMD; | ||
1046 | } | 826 | } |
827 | |||
828 | usbvision_frames_free(usbvision); | ||
829 | usbvision_empty_framequeues(usbvision); | ||
830 | vr->count = usbvision_frames_alloc(usbvision,vr->count); | ||
831 | |||
832 | usbvision->curFrame = NULL; | ||
833 | |||
1047 | return 0; | 834 | return 0; |
1048 | } | 835 | } |
1049 | 836 | ||
1050 | static int usbvision_v4l2_ioctl(struct inode *inode, struct file *file, | 837 | static int vidioc_querybuf (struct file *file, |
1051 | unsigned int cmd, unsigned long arg) | 838 | void *priv, struct v4l2_buffer *vb) |
1052 | { | 839 | { |
1053 | return video_usercopy(inode, file, cmd, arg, usbvision_v4l2_do_ioctl); | 840 | struct video_device *dev = video_devdata(file); |
841 | struct usb_usbvision *usbvision = | ||
842 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
843 | struct usbvision_frame *frame; | ||
844 | |||
845 | /* FIXME : must control | ||
846 | that buffers are mapped (VIDIOC_REQBUFS has been called) */ | ||
847 | if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { | ||
848 | return -EINVAL; | ||
849 | } | ||
850 | if(vb->index>=usbvision->num_frames) { | ||
851 | return -EINVAL; | ||
852 | } | ||
853 | /* Updating the corresponding frame state */ | ||
854 | vb->flags = 0; | ||
855 | frame = &usbvision->frame[vb->index]; | ||
856 | if(frame->grabstate >= FrameState_Ready) | ||
857 | vb->flags |= V4L2_BUF_FLAG_QUEUED; | ||
858 | if(frame->grabstate >= FrameState_Done) | ||
859 | vb->flags |= V4L2_BUF_FLAG_DONE; | ||
860 | if(frame->grabstate == FrameState_Unused) | ||
861 | vb->flags |= V4L2_BUF_FLAG_MAPPED; | ||
862 | vb->memory = V4L2_MEMORY_MMAP; | ||
863 | |||
864 | vb->m.offset = vb->index*PAGE_ALIGN(usbvision->max_frame_size); | ||
865 | |||
866 | vb->memory = V4L2_MEMORY_MMAP; | ||
867 | vb->field = V4L2_FIELD_NONE; | ||
868 | vb->length = usbvision->curwidth* | ||
869 | usbvision->curheight* | ||
870 | usbvision->palette.bytes_per_pixel; | ||
871 | vb->timestamp = usbvision->frame[vb->index].timestamp; | ||
872 | vb->sequence = usbvision->frame[vb->index].sequence; | ||
873 | return 0; | ||
874 | } | ||
875 | |||
876 | static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *vb) | ||
877 | { | ||
878 | struct video_device *dev = video_devdata(file); | ||
879 | struct usb_usbvision *usbvision = | ||
880 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
881 | struct usbvision_frame *frame; | ||
882 | unsigned long lock_flags; | ||
883 | |||
884 | /* FIXME : works only on VIDEO_CAPTURE MODE, MMAP. */ | ||
885 | if(vb->type != V4L2_CAP_VIDEO_CAPTURE) { | ||
886 | return -EINVAL; | ||
887 | } | ||
888 | if(vb->index>=usbvision->num_frames) { | ||
889 | return -EINVAL; | ||
890 | } | ||
891 | |||
892 | frame = &usbvision->frame[vb->index]; | ||
893 | |||
894 | if (frame->grabstate != FrameState_Unused) { | ||
895 | return -EAGAIN; | ||
896 | } | ||
897 | |||
898 | /* Mark it as ready and enqueue frame */ | ||
899 | frame->grabstate = FrameState_Ready; | ||
900 | frame->scanstate = ScanState_Scanning; | ||
901 | frame->scanlength = 0; /* Accumulated in usbvision_parse_data() */ | ||
902 | |||
903 | vb->flags &= ~V4L2_BUF_FLAG_DONE; | ||
904 | |||
905 | /* set v4l2_format index */ | ||
906 | frame->v4l2_format = usbvision->palette; | ||
907 | |||
908 | spin_lock_irqsave(&usbvision->queue_lock, lock_flags); | ||
909 | list_add_tail(&usbvision->frame[vb->index].frame, &usbvision->inqueue); | ||
910 | spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); | ||
911 | |||
912 | return 0; | ||
1054 | } | 913 | } |
1055 | 914 | ||
915 | static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb) | ||
916 | { | ||
917 | struct video_device *dev = video_devdata(file); | ||
918 | struct usb_usbvision *usbvision = | ||
919 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
920 | int ret; | ||
921 | struct usbvision_frame *f; | ||
922 | unsigned long lock_flags; | ||
923 | |||
924 | if (vb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
925 | return -EINVAL; | ||
926 | |||
927 | if (list_empty(&(usbvision->outqueue))) { | ||
928 | if (usbvision->streaming == Stream_Idle) | ||
929 | return -EINVAL; | ||
930 | ret = wait_event_interruptible | ||
931 | (usbvision->wait_frame, | ||
932 | !list_empty(&(usbvision->outqueue))); | ||
933 | if (ret) | ||
934 | return ret; | ||
935 | } | ||
936 | |||
937 | spin_lock_irqsave(&usbvision->queue_lock, lock_flags); | ||
938 | f = list_entry(usbvision->outqueue.next, | ||
939 | struct usbvision_frame, frame); | ||
940 | list_del(usbvision->outqueue.next); | ||
941 | spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); | ||
942 | |||
943 | f->grabstate = FrameState_Unused; | ||
944 | |||
945 | vb->memory = V4L2_MEMORY_MMAP; | ||
946 | vb->flags = V4L2_BUF_FLAG_MAPPED | | ||
947 | V4L2_BUF_FLAG_QUEUED | | ||
948 | V4L2_BUF_FLAG_DONE; | ||
949 | vb->index = f->index; | ||
950 | vb->sequence = f->sequence; | ||
951 | vb->timestamp = f->timestamp; | ||
952 | vb->field = V4L2_FIELD_NONE; | ||
953 | vb->bytesused = f->scanlength; | ||
954 | |||
955 | return 0; | ||
956 | } | ||
957 | |||
958 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | ||
959 | { | ||
960 | struct video_device *dev = video_devdata(file); | ||
961 | struct usb_usbvision *usbvision = | ||
962 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
963 | int b=V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
964 | |||
965 | usbvision->streaming = Stream_On; | ||
966 | call_i2c_clients(usbvision,VIDIOC_STREAMON , &b); | ||
967 | |||
968 | return 0; | ||
969 | } | ||
970 | |||
971 | static int vidioc_streamoff(struct file *file, | ||
972 | void *priv, enum v4l2_buf_type type) | ||
973 | { | ||
974 | struct video_device *dev = video_devdata(file); | ||
975 | struct usb_usbvision *usbvision = | ||
976 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
977 | int b=V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
978 | |||
979 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
980 | return -EINVAL; | ||
981 | |||
982 | if(usbvision->streaming == Stream_On) { | ||
983 | usbvision_stream_interrupt(usbvision); | ||
984 | /* Stop all video streamings */ | ||
985 | call_i2c_clients(usbvision,VIDIOC_STREAMOFF , &b); | ||
986 | } | ||
987 | usbvision_empty_framequeues(usbvision); | ||
988 | |||
989 | return 0; | ||
990 | } | ||
991 | |||
992 | static int vidioc_enum_fmt_cap (struct file *file, void *priv, | ||
993 | struct v4l2_fmtdesc *vfd) | ||
994 | { | ||
995 | if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) { | ||
996 | return -EINVAL; | ||
997 | } | ||
998 | vfd->flags = 0; | ||
999 | vfd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1000 | strcpy(vfd->description,usbvision_v4l2_format[vfd->index].desc); | ||
1001 | vfd->pixelformat = usbvision_v4l2_format[vfd->index].format; | ||
1002 | memset(vfd->reserved, 0, sizeof(vfd->reserved)); | ||
1003 | return 0; | ||
1004 | } | ||
1005 | |||
1006 | static int vidioc_g_fmt_cap (struct file *file, void *priv, | ||
1007 | struct v4l2_format *vf) | ||
1008 | { | ||
1009 | struct video_device *dev = video_devdata(file); | ||
1010 | struct usb_usbvision *usbvision = | ||
1011 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
1012 | vf->fmt.pix.width = usbvision->curwidth; | ||
1013 | vf->fmt.pix.height = usbvision->curheight; | ||
1014 | vf->fmt.pix.pixelformat = usbvision->palette.format; | ||
1015 | vf->fmt.pix.bytesperline = | ||
1016 | usbvision->curwidth*usbvision->palette.bytes_per_pixel; | ||
1017 | vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*usbvision->curheight; | ||
1018 | vf->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
1019 | vf->fmt.pix.field = V4L2_FIELD_NONE; /* Always progressive image */ | ||
1020 | |||
1021 | return 0; | ||
1022 | } | ||
1023 | |||
1024 | static int vidioc_try_fmt_cap (struct file *file, void *priv, | ||
1025 | struct v4l2_format *vf) | ||
1026 | { | ||
1027 | struct video_device *dev = video_devdata(file); | ||
1028 | struct usb_usbvision *usbvision = | ||
1029 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
1030 | int formatIdx; | ||
1031 | |||
1032 | /* Find requested format in available ones */ | ||
1033 | for(formatIdx=0;formatIdx<USBVISION_SUPPORTED_PALETTES;formatIdx++) { | ||
1034 | if(vf->fmt.pix.pixelformat == | ||
1035 | usbvision_v4l2_format[formatIdx].format) { | ||
1036 | usbvision->palette = usbvision_v4l2_format[formatIdx]; | ||
1037 | break; | ||
1038 | } | ||
1039 | } | ||
1040 | /* robustness */ | ||
1041 | if(formatIdx == USBVISION_SUPPORTED_PALETTES) { | ||
1042 | return -EINVAL; | ||
1043 | } | ||
1044 | RESTRICT_TO_RANGE(vf->fmt.pix.width, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH); | ||
1045 | RESTRICT_TO_RANGE(vf->fmt.pix.height, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT); | ||
1046 | |||
1047 | vf->fmt.pix.bytesperline = vf->fmt.pix.width* | ||
1048 | usbvision->palette.bytes_per_pixel; | ||
1049 | vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*vf->fmt.pix.height; | ||
1050 | |||
1051 | return 0; | ||
1052 | } | ||
1053 | |||
1054 | static int vidioc_s_fmt_cap(struct file *file, void *priv, | ||
1055 | struct v4l2_format *vf) | ||
1056 | { | ||
1057 | struct video_device *dev = video_devdata(file); | ||
1058 | struct usb_usbvision *usbvision = | ||
1059 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
1060 | int ret; | ||
1061 | |||
1062 | if( 0 != (ret=vidioc_try_fmt_cap (file, priv, vf)) ) { | ||
1063 | return ret; | ||
1064 | } | ||
1065 | |||
1066 | /* stop io in case it is already in progress */ | ||
1067 | if(usbvision->streaming == Stream_On) { | ||
1068 | if ((ret = usbvision_stream_interrupt(usbvision))) | ||
1069 | return ret; | ||
1070 | } | ||
1071 | usbvision_frames_free(usbvision); | ||
1072 | usbvision_empty_framequeues(usbvision); | ||
1073 | |||
1074 | usbvision->curFrame = NULL; | ||
1075 | |||
1076 | /* by now we are committed to the new data... */ | ||
1077 | down(&usbvision->lock); | ||
1078 | usbvision_set_output(usbvision, vf->fmt.pix.width, vf->fmt.pix.height); | ||
1079 | up(&usbvision->lock); | ||
1080 | |||
1081 | return 0; | ||
1082 | } | ||
1056 | 1083 | ||
1057 | static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | 1084 | static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, |
1058 | size_t count, loff_t *ppos) | 1085 | size_t count, loff_t *ppos) |
1059 | { | 1086 | { |
1060 | struct video_device *dev = video_devdata(file); | 1087 | struct video_device *dev = video_devdata(file); |
1061 | struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); | 1088 | struct usb_usbvision *usbvision = |
1089 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
1062 | int noblock = file->f_flags & O_NONBLOCK; | 1090 | int noblock = file->f_flags & O_NONBLOCK; |
1063 | unsigned long lock_flags; | 1091 | unsigned long lock_flags; |
1064 | 1092 | ||
1065 | int ret,i; | 1093 | int ret,i; |
1066 | struct usbvision_frame *frame; | 1094 | struct usbvision_frame *frame; |
1067 | 1095 | ||
1068 | PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __FUNCTION__, (unsigned long)count, noblock); | 1096 | PDEBUG(DBG_IO, "%s: %ld bytes, noblock=%d", __FUNCTION__, |
1097 | (unsigned long)count, noblock); | ||
1069 | 1098 | ||
1070 | if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL)) | 1099 | if (!USBVISION_IS_OPERATIONAL(usbvision) || (buf == NULL)) |
1071 | return -EFAULT; | 1100 | return -EFAULT; |
1072 | 1101 | ||
1073 | /* This entry point is compatible with the mmap routines so that a user can do either | 1102 | /* This entry point is compatible with the mmap routines |
1074 | VIDIOC_QBUF/VIDIOC_DQBUF to get frames or call read on the device. */ | 1103 | so that a user can do either VIDIOC_QBUF/VIDIOC_DQBUF |
1104 | to get frames or call read on the device. */ | ||
1075 | if(!usbvision->num_frames) { | 1105 | if(!usbvision->num_frames) { |
1076 | /* First, allocate some frames to work with if this has not been done with | 1106 | /* First, allocate some frames to work with |
1077 | VIDIOC_REQBUF */ | 1107 | if this has not been done with VIDIOC_REQBUF */ |
1078 | usbvision_frames_free(usbvision); | 1108 | usbvision_frames_free(usbvision); |
1079 | usbvision_empty_framequeues(usbvision); | 1109 | usbvision_empty_framequeues(usbvision); |
1080 | usbvision_frames_alloc(usbvision,USBVISION_NUMFRAMES); | 1110 | usbvision_frames_alloc(usbvision,USBVISION_NUMFRAMES); |
@@ -1086,21 +1116,24 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1086 | call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL); | 1116 | call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL); |
1087 | } | 1117 | } |
1088 | 1118 | ||
1089 | /* Then, enqueue as many frames as possible (like a user of VIDIOC_QBUF would do) */ | 1119 | /* Then, enqueue as many frames as possible |
1120 | (like a user of VIDIOC_QBUF would do) */ | ||
1090 | for(i=0;i<usbvision->num_frames;i++) { | 1121 | for(i=0;i<usbvision->num_frames;i++) { |
1091 | frame = &usbvision->frame[i]; | 1122 | frame = &usbvision->frame[i]; |
1092 | if(frame->grabstate == FrameState_Unused) { | 1123 | if(frame->grabstate == FrameState_Unused) { |
1093 | /* Mark it as ready and enqueue frame */ | 1124 | /* Mark it as ready and enqueue frame */ |
1094 | frame->grabstate = FrameState_Ready; | 1125 | frame->grabstate = FrameState_Ready; |
1095 | frame->scanstate = ScanState_Scanning; | 1126 | frame->scanstate = ScanState_Scanning; |
1096 | frame->scanlength = 0; /* Accumulated in usbvision_parse_data() */ | 1127 | /* Accumulated in usbvision_parse_data() */ |
1128 | frame->scanlength = 0; | ||
1097 | 1129 | ||
1098 | /* set v4l2_format index */ | 1130 | /* set v4l2_format index */ |
1099 | frame->v4l2_format = usbvision->palette; | 1131 | frame->v4l2_format = usbvision->palette; |
1100 | 1132 | ||
1101 | spin_lock_irqsave(&usbvision->queue_lock, lock_flags); | 1133 | spin_lock_irqsave(&usbvision->queue_lock, lock_flags); |
1102 | list_add_tail(&frame->frame, &usbvision->inqueue); | 1134 | list_add_tail(&frame->frame, &usbvision->inqueue); |
1103 | spin_unlock_irqrestore(&usbvision->queue_lock, lock_flags); | 1135 | spin_unlock_irqrestore(&usbvision->queue_lock, |
1136 | lock_flags); | ||
1104 | } | 1137 | } |
1105 | } | 1138 | } |
1106 | 1139 | ||
@@ -1128,8 +1161,9 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1128 | return 0; | 1161 | return 0; |
1129 | } | 1162 | } |
1130 | 1163 | ||
1131 | PDEBUG(DBG_IO, "%s: frmx=%d, bytes_read=%ld, scanlength=%ld", __FUNCTION__, | 1164 | PDEBUG(DBG_IO, "%s: frmx=%d, bytes_read=%ld, scanlength=%ld", |
1132 | frame->index, frame->bytes_read, frame->scanlength); | 1165 | __FUNCTION__, |
1166 | frame->index, frame->bytes_read, frame->scanlength); | ||
1133 | 1167 | ||
1134 | /* copy bytes to user space; we allow for partials reads */ | 1168 | /* copy bytes to user space; we allow for partials reads */ |
1135 | if ((count + frame->bytes_read) > (unsigned long)frame->scanlength) | 1169 | if ((count + frame->bytes_read) > (unsigned long)frame->scanlength) |
@@ -1140,10 +1174,11 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf, | |||
1140 | } | 1174 | } |
1141 | 1175 | ||
1142 | frame->bytes_read += count; | 1176 | frame->bytes_read += count; |
1143 | PDEBUG(DBG_IO, "%s: {copy} count used=%ld, new bytes_read=%ld", __FUNCTION__, | 1177 | PDEBUG(DBG_IO, "%s: {copy} count used=%ld, new bytes_read=%ld", |
1144 | (unsigned long)count, frame->bytes_read); | 1178 | __FUNCTION__, |
1179 | (unsigned long)count, frame->bytes_read); | ||
1145 | 1180 | ||
1146 | // For now, forget the frame if it has not been read in one shot. | 1181 | /* For now, forget the frame if it has not been read in one shot. */ |
1147 | /* if (frame->bytes_read >= frame->scanlength) {// All data has been read */ | 1182 | /* if (frame->bytes_read >= frame->scanlength) {// All data has been read */ |
1148 | frame->bytes_read = 0; | 1183 | frame->bytes_read = 0; |
1149 | 1184 | ||
@@ -1162,7 +1197,8 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1162 | u32 i; | 1197 | u32 i; |
1163 | 1198 | ||
1164 | struct video_device *dev = video_devdata(file); | 1199 | struct video_device *dev = video_devdata(file); |
1165 | struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); | 1200 | struct usb_usbvision *usbvision = |
1201 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
1166 | 1202 | ||
1167 | PDEBUG(DBG_MMAP, "mmap"); | 1203 | PDEBUG(DBG_MMAP, "mmap"); |
1168 | 1204 | ||
@@ -1180,11 +1216,13 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1180 | } | 1216 | } |
1181 | 1217 | ||
1182 | for (i = 0; i < usbvision->num_frames; i++) { | 1218 | for (i = 0; i < usbvision->num_frames; i++) { |
1183 | if (((PAGE_ALIGN(usbvision->max_frame_size)*i) >> PAGE_SHIFT) == vma->vm_pgoff) | 1219 | if (((PAGE_ALIGN(usbvision->max_frame_size)*i) >> PAGE_SHIFT) == |
1220 | vma->vm_pgoff) | ||
1184 | break; | 1221 | break; |
1185 | } | 1222 | } |
1186 | if (i == usbvision->num_frames) { | 1223 | if (i == usbvision->num_frames) { |
1187 | PDEBUG(DBG_MMAP, "mmap: user supplied mapping address is out of range"); | 1224 | PDEBUG(DBG_MMAP, |
1225 | "mmap: user supplied mapping address is out of range"); | ||
1188 | up(&usbvision->lock); | 1226 | up(&usbvision->lock); |
1189 | return -EINVAL; | 1227 | return -EINVAL; |
1190 | } | 1228 | } |
@@ -1218,8 +1256,8 @@ static int usbvision_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | |||
1218 | static int usbvision_radio_open(struct inode *inode, struct file *file) | 1256 | static int usbvision_radio_open(struct inode *inode, struct file *file) |
1219 | { | 1257 | { |
1220 | struct video_device *dev = video_devdata(file); | 1258 | struct video_device *dev = video_devdata(file); |
1221 | struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); | 1259 | struct usb_usbvision *usbvision = |
1222 | struct v4l2_frequency freq; | 1260 | (struct usb_usbvision *) video_get_drvdata(dev); |
1223 | int errCode = 0; | 1261 | int errCode = 0; |
1224 | 1262 | ||
1225 | PDEBUG(DBG_IO, "%s:", __FUNCTION__); | 1263 | PDEBUG(DBG_IO, "%s:", __FUNCTION__); |
@@ -1249,8 +1287,6 @@ static int usbvision_radio_open(struct inode *inode, struct file *file) | |||
1249 | // If so far no errors then we shall start the radio | 1287 | // If so far no errors then we shall start the radio |
1250 | usbvision->radio = 1; | 1288 | usbvision->radio = 1; |
1251 | call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type); | 1289 | call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type); |
1252 | freq.frequency = 1517; //SWR3 @ 94.8MHz | ||
1253 | call_i2c_clients(usbvision, VIDIOC_S_FREQUENCY, &freq); | ||
1254 | usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO); | 1290 | usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO); |
1255 | usbvision->user++; | 1291 | usbvision->user++; |
1256 | } | 1292 | } |
@@ -1270,7 +1306,8 @@ static int usbvision_radio_open(struct inode *inode, struct file *file) | |||
1270 | static int usbvision_radio_close(struct inode *inode, struct file *file) | 1306 | static int usbvision_radio_close(struct inode *inode, struct file *file) |
1271 | { | 1307 | { |
1272 | struct video_device *dev = video_devdata(file); | 1308 | struct video_device *dev = video_devdata(file); |
1273 | struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); | 1309 | struct usb_usbvision *usbvision = |
1310 | (struct usb_usbvision *) video_get_drvdata(dev); | ||
1274 | int errCode = 0; | 1311 | int errCode = 0; |
1275 | 1312 | ||
1276 | PDEBUG(DBG_IO, ""); | 1313 | PDEBUG(DBG_IO, ""); |
@@ -1304,149 +1341,6 @@ static int usbvision_radio_close(struct inode *inode, struct file *file) | |||
1304 | return errCode; | 1341 | return errCode; |
1305 | } | 1342 | } |
1306 | 1343 | ||
1307 | static int usbvision_do_radio_ioctl(struct inode *inode, struct file *file, | ||
1308 | unsigned int cmd, void *arg) | ||
1309 | { | ||
1310 | struct video_device *dev = video_devdata(file); | ||
1311 | struct usb_usbvision *usbvision = (struct usb_usbvision *) video_get_drvdata(dev); | ||
1312 | |||
1313 | if (!USBVISION_IS_OPERATIONAL(usbvision)) | ||
1314 | return -EIO; | ||
1315 | |||
1316 | switch (cmd) { | ||
1317 | case VIDIOC_QUERYCAP: | ||
1318 | { | ||
1319 | struct v4l2_capability *vc=arg; | ||
1320 | |||
1321 | memset(vc, 0, sizeof(*vc)); | ||
1322 | strlcpy(vc->driver, "USBVision", sizeof(vc->driver)); | ||
1323 | strlcpy(vc->card, usbvision_device_data[usbvision->DevModel].ModelString, | ||
1324 | sizeof(vc->card)); | ||
1325 | strlcpy(vc->bus_info, usbvision->dev->dev.bus_id, | ||
1326 | sizeof(vc->bus_info)); | ||
1327 | vc->version = USBVISION_DRIVER_VERSION; | ||
1328 | vc->capabilities = (usbvision->have_tuner ? V4L2_CAP_TUNER : 0); | ||
1329 | PDEBUG(DBG_IO, "VIDIOC_QUERYCAP"); | ||
1330 | return 0; | ||
1331 | } | ||
1332 | case VIDIOC_QUERYCTRL: | ||
1333 | { | ||
1334 | struct v4l2_queryctrl *ctrl = arg; | ||
1335 | int id=ctrl->id; | ||
1336 | |||
1337 | memset(ctrl,0,sizeof(*ctrl)); | ||
1338 | ctrl->id=id; | ||
1339 | |||
1340 | call_i2c_clients(usbvision, cmd, arg); | ||
1341 | PDEBUG(DBG_IO,"VIDIOC_QUERYCTRL id=%x value=%x",ctrl->id,ctrl->type); | ||
1342 | |||
1343 | if (ctrl->type) | ||
1344 | return 0; | ||
1345 | else | ||
1346 | return -EINVAL; | ||
1347 | |||
1348 | } | ||
1349 | case VIDIOC_G_CTRL: | ||
1350 | { | ||
1351 | struct v4l2_control *ctrl = arg; | ||
1352 | |||
1353 | call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl); | ||
1354 | PDEBUG(DBG_IO,"VIDIOC_G_CTRL id=%x value=%x",ctrl->id,ctrl->value); | ||
1355 | return 0; | ||
1356 | } | ||
1357 | case VIDIOC_S_CTRL: | ||
1358 | { | ||
1359 | struct v4l2_control *ctrl = arg; | ||
1360 | |||
1361 | call_i2c_clients(usbvision, VIDIOC_S_CTRL, ctrl); | ||
1362 | PDEBUG(DBG_IO, "VIDIOC_S_CTRL id=%x value=%x",ctrl->id,ctrl->value); | ||
1363 | return 0; | ||
1364 | } | ||
1365 | case VIDIOC_G_TUNER: | ||
1366 | { | ||
1367 | struct v4l2_tuner *t = arg; | ||
1368 | |||
1369 | if (t->index > 0) | ||
1370 | return -EINVAL; | ||
1371 | |||
1372 | memset(t,0,sizeof(*t)); | ||
1373 | strcpy(t->name, "Radio"); | ||
1374 | t->type = V4L2_TUNER_RADIO; | ||
1375 | |||
1376 | /* Let clients fill in the remainder of this struct */ | ||
1377 | call_i2c_clients(usbvision,VIDIOC_G_TUNER,t); | ||
1378 | PDEBUG(DBG_IO, "VIDIOC_G_TUNER signal=%x, afc=%x",t->signal,t->afc); | ||
1379 | return 0; | ||
1380 | } | ||
1381 | case VIDIOC_S_TUNER: | ||
1382 | { | ||
1383 | struct v4l2_tuner *vt = arg; | ||
1384 | |||
1385 | // Only no or one tuner for now | ||
1386 | if (!usbvision->have_tuner || vt->index) | ||
1387 | return -EINVAL; | ||
1388 | /* let clients handle this */ | ||
1389 | call_i2c_clients(usbvision,VIDIOC_S_TUNER,vt); | ||
1390 | |||
1391 | PDEBUG(DBG_IO, "VIDIOC_S_TUNER"); | ||
1392 | return 0; | ||
1393 | } | ||
1394 | case VIDIOC_G_AUDIO: | ||
1395 | { | ||
1396 | struct v4l2_audio *a = arg; | ||
1397 | |||
1398 | memset(a,0,sizeof(*a)); | ||
1399 | strcpy(a->name,"Radio"); | ||
1400 | PDEBUG(DBG_IO, "VIDIOC_G_AUDIO"); | ||
1401 | return 0; | ||
1402 | } | ||
1403 | case VIDIOC_S_AUDIO: | ||
1404 | case VIDIOC_S_INPUT: | ||
1405 | case VIDIOC_S_STD: | ||
1406 | return 0; | ||
1407 | |||
1408 | case VIDIOC_G_FREQUENCY: | ||
1409 | { | ||
1410 | struct v4l2_frequency *f = arg; | ||
1411 | |||
1412 | memset(f,0,sizeof(*f)); | ||
1413 | |||
1414 | f->type = V4L2_TUNER_RADIO; | ||
1415 | f->frequency = usbvision->freq; | ||
1416 | call_i2c_clients(usbvision, cmd, f); | ||
1417 | PDEBUG(DBG_IO, "VIDIOC_G_FREQUENCY freq=0x%X", (unsigned)f->frequency); | ||
1418 | |||
1419 | return 0; | ||
1420 | } | ||
1421 | case VIDIOC_S_FREQUENCY: | ||
1422 | { | ||
1423 | struct v4l2_frequency *f = arg; | ||
1424 | |||
1425 | if (f->tuner != 0) | ||
1426 | return -EINVAL; | ||
1427 | usbvision->freq = f->frequency; | ||
1428 | call_i2c_clients(usbvision, cmd, f); | ||
1429 | PDEBUG(DBG_IO, "VIDIOC_S_FREQUENCY freq=0x%X", (unsigned)f->frequency); | ||
1430 | |||
1431 | return 0; | ||
1432 | } | ||
1433 | default: | ||
1434 | { | ||
1435 | PDEBUG(DBG_IO, "%s: Unknown command %x", __FUNCTION__, cmd); | ||
1436 | return -ENOIOCTLCMD; | ||
1437 | } | ||
1438 | } | ||
1439 | return 0; | ||
1440 | } | ||
1441 | |||
1442 | |||
1443 | static int usbvision_radio_ioctl(struct inode *inode, struct file *file, | ||
1444 | unsigned int cmd, unsigned long arg) | ||
1445 | { | ||
1446 | return video_usercopy(inode, file, cmd, arg, usbvision_do_radio_ioctl); | ||
1447 | } | ||
1448 | |||
1449 | |||
1450 | /* | 1344 | /* |
1451 | * Here comes the stuff for vbi on usbvision based devices | 1345 | * Here comes the stuff for vbi on usbvision based devices |
1452 | * | 1346 | * |
@@ -1454,21 +1348,21 @@ static int usbvision_radio_ioctl(struct inode *inode, struct file *file, | |||
1454 | static int usbvision_vbi_open(struct inode *inode, struct file *file) | 1348 | static int usbvision_vbi_open(struct inode *inode, struct file *file) |
1455 | { | 1349 | { |
1456 | /* TODO */ | 1350 | /* TODO */ |
1457 | return -EINVAL; | 1351 | return -ENODEV; |
1458 | 1352 | ||
1459 | } | 1353 | } |
1460 | 1354 | ||
1461 | static int usbvision_vbi_close(struct inode *inode, struct file *file) | 1355 | static int usbvision_vbi_close(struct inode *inode, struct file *file) |
1462 | { | 1356 | { |
1463 | /* TODO */ | 1357 | /* TODO */ |
1464 | return -EINVAL; | 1358 | return -ENODEV; |
1465 | } | 1359 | } |
1466 | 1360 | ||
1467 | static int usbvision_do_vbi_ioctl(struct inode *inode, struct file *file, | 1361 | static int usbvision_do_vbi_ioctl(struct inode *inode, struct file *file, |
1468 | unsigned int cmd, void *arg) | 1362 | unsigned int cmd, void *arg) |
1469 | { | 1363 | { |
1470 | /* TODO */ | 1364 | /* TODO */ |
1471 | return -EINVAL; | 1365 | return -ENOIOCTLCMD; |
1472 | } | 1366 | } |
1473 | 1367 | ||
1474 | static int usbvision_vbi_ioctl(struct inode *inode, struct file *file, | 1368 | static int usbvision_vbi_ioctl(struct inode *inode, struct file *file, |
@@ -1489,8 +1383,11 @@ static const struct file_operations usbvision_fops = { | |||
1489 | .release = usbvision_v4l2_close, | 1383 | .release = usbvision_v4l2_close, |
1490 | .read = usbvision_v4l2_read, | 1384 | .read = usbvision_v4l2_read, |
1491 | .mmap = usbvision_v4l2_mmap, | 1385 | .mmap = usbvision_v4l2_mmap, |
1492 | .ioctl = usbvision_v4l2_ioctl, | 1386 | .ioctl = video_ioctl2, |
1493 | .llseek = no_llseek, | 1387 | .llseek = no_llseek, |
1388 | /* .poll = video_poll, */ | ||
1389 | .mmap = usbvision_v4l2_mmap, | ||
1390 | .compat_ioctl = v4l_compat_ioctl32, | ||
1494 | }; | 1391 | }; |
1495 | static struct video_device usbvision_video_template = { | 1392 | static struct video_device usbvision_video_template = { |
1496 | .owner = THIS_MODULE, | 1393 | .owner = THIS_MODULE, |
@@ -1500,6 +1397,39 @@ static struct video_device usbvision_video_template = { | |||
1500 | .name = "usbvision-video", | 1397 | .name = "usbvision-video", |
1501 | .release = video_device_release, | 1398 | .release = video_device_release, |
1502 | .minor = -1, | 1399 | .minor = -1, |
1400 | .vidioc_querycap = vidioc_querycap, | ||
1401 | .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, | ||
1402 | .vidioc_g_fmt_cap = vidioc_g_fmt_cap, | ||
1403 | .vidioc_try_fmt_cap = vidioc_try_fmt_cap, | ||
1404 | .vidioc_s_fmt_cap = vidioc_s_fmt_cap, | ||
1405 | .vidioc_reqbufs = vidioc_reqbufs, | ||
1406 | .vidioc_querybuf = vidioc_querybuf, | ||
1407 | .vidioc_qbuf = vidioc_qbuf, | ||
1408 | .vidioc_dqbuf = vidioc_dqbuf, | ||
1409 | .vidioc_s_std = vidioc_s_std, | ||
1410 | .vidioc_enum_input = vidioc_enum_input, | ||
1411 | .vidioc_g_input = vidioc_g_input, | ||
1412 | .vidioc_s_input = vidioc_s_input, | ||
1413 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1414 | .vidioc_g_audio = vidioc_g_audio, | ||
1415 | .vidioc_g_audio = vidioc_s_audio, | ||
1416 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1417 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1418 | .vidioc_streamon = vidioc_streamon, | ||
1419 | .vidioc_streamoff = vidioc_streamoff, | ||
1420 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1421 | /* .vidiocgmbuf = vidiocgmbuf, */ | ||
1422 | #endif | ||
1423 | .vidioc_g_tuner = vidioc_g_tuner, | ||
1424 | .vidioc_s_tuner = vidioc_s_tuner, | ||
1425 | .vidioc_g_frequency = vidioc_g_frequency, | ||
1426 | .vidioc_s_frequency = vidioc_s_frequency, | ||
1427 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1428 | .vidioc_g_register = vidioc_g_register, | ||
1429 | .vidioc_s_register = vidioc_s_register, | ||
1430 | #endif | ||
1431 | .tvnorms = USBVISION_NORMS, | ||
1432 | .current_norm = V4L2_STD_PAL | ||
1503 | }; | 1433 | }; |
1504 | 1434 | ||
1505 | 1435 | ||
@@ -1508,8 +1438,9 @@ static const struct file_operations usbvision_radio_fops = { | |||
1508 | .owner = THIS_MODULE, | 1438 | .owner = THIS_MODULE, |
1509 | .open = usbvision_radio_open, | 1439 | .open = usbvision_radio_open, |
1510 | .release = usbvision_radio_close, | 1440 | .release = usbvision_radio_close, |
1511 | .ioctl = usbvision_radio_ioctl, | 1441 | .ioctl = video_ioctl2, |
1512 | .llseek = no_llseek, | 1442 | .llseek = no_llseek, |
1443 | .compat_ioctl = v4l_compat_ioctl32, | ||
1513 | }; | 1444 | }; |
1514 | 1445 | ||
1515 | static struct video_device usbvision_radio_template= | 1446 | static struct video_device usbvision_radio_template= |
@@ -1518,12 +1449,27 @@ static struct video_device usbvision_radio_template= | |||
1518 | .type = VID_TYPE_TUNER, | 1449 | .type = VID_TYPE_TUNER, |
1519 | .hardware = VID_HARDWARE_USBVISION, | 1450 | .hardware = VID_HARDWARE_USBVISION, |
1520 | .fops = &usbvision_radio_fops, | 1451 | .fops = &usbvision_radio_fops, |
1521 | .release = video_device_release, | ||
1522 | .name = "usbvision-radio", | 1452 | .name = "usbvision-radio", |
1453 | .release = video_device_release, | ||
1523 | .minor = -1, | 1454 | .minor = -1, |
1455 | .vidioc_querycap = vidioc_querycap, | ||
1456 | .vidioc_enum_input = vidioc_enum_input, | ||
1457 | .vidioc_g_input = vidioc_g_input, | ||
1458 | .vidioc_s_input = vidioc_s_input, | ||
1459 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1460 | .vidioc_g_audio = vidioc_g_audio, | ||
1461 | .vidioc_g_audio = vidioc_s_audio, | ||
1462 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1463 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1464 | .vidioc_g_tuner = vidioc_g_tuner, | ||
1465 | .vidioc_s_tuner = vidioc_s_tuner, | ||
1466 | .vidioc_g_frequency = vidioc_g_frequency, | ||
1467 | .vidioc_s_frequency = vidioc_s_frequency, | ||
1468 | |||
1469 | .tvnorms = USBVISION_NORMS, | ||
1470 | .current_norm = V4L2_STD_PAL | ||
1524 | }; | 1471 | }; |
1525 | 1472 | ||
1526 | |||
1527 | // vbi template | 1473 | // vbi template |
1528 | static const struct file_operations usbvision_vbi_fops = { | 1474 | static const struct file_operations usbvision_vbi_fops = { |
1529 | .owner = THIS_MODULE, | 1475 | .owner = THIS_MODULE, |
@@ -1531,6 +1477,7 @@ static const struct file_operations usbvision_vbi_fops = { | |||
1531 | .release = usbvision_vbi_close, | 1477 | .release = usbvision_vbi_close, |
1532 | .ioctl = usbvision_vbi_ioctl, | 1478 | .ioctl = usbvision_vbi_ioctl, |
1533 | .llseek = no_llseek, | 1479 | .llseek = no_llseek, |
1480 | .compat_ioctl = v4l_compat_ioctl32, | ||
1534 | }; | 1481 | }; |
1535 | 1482 | ||
1536 | static struct video_device usbvision_vbi_template= | 1483 | static struct video_device usbvision_vbi_template= |
@@ -1574,11 +1521,11 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) | |||
1574 | { | 1521 | { |
1575 | // vbi Device: | 1522 | // vbi Device: |
1576 | if (usbvision->vbi) { | 1523 | if (usbvision->vbi) { |
1577 | PDEBUG(DBG_PROBE, "unregister /dev/vbi%d [v4l2]", usbvision->vbi->minor & 0x1f); | 1524 | PDEBUG(DBG_PROBE, "unregister /dev/vbi%d [v4l2]", |
1525 | usbvision->vbi->minor & 0x1f); | ||
1578 | if (usbvision->vbi->minor != -1) { | 1526 | if (usbvision->vbi->minor != -1) { |
1579 | video_unregister_device(usbvision->vbi); | 1527 | video_unregister_device(usbvision->vbi); |
1580 | } | 1528 | } else { |
1581 | else { | ||
1582 | video_device_release(usbvision->vbi); | 1529 | video_device_release(usbvision->vbi); |
1583 | } | 1530 | } |
1584 | usbvision->vbi = NULL; | 1531 | usbvision->vbi = NULL; |
@@ -1586,11 +1533,11 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) | |||
1586 | 1533 | ||
1587 | // Radio Device: | 1534 | // Radio Device: |
1588 | if (usbvision->rdev) { | 1535 | if (usbvision->rdev) { |
1589 | PDEBUG(DBG_PROBE, "unregister /dev/radio%d [v4l2]", usbvision->rdev->minor & 0x1f); | 1536 | PDEBUG(DBG_PROBE, "unregister /dev/radio%d [v4l2]", |
1537 | usbvision->rdev->minor & 0x1f); | ||
1590 | if (usbvision->rdev->minor != -1) { | 1538 | if (usbvision->rdev->minor != -1) { |
1591 | video_unregister_device(usbvision->rdev); | 1539 | video_unregister_device(usbvision->rdev); |
1592 | } | 1540 | } else { |
1593 | else { | ||
1594 | video_device_release(usbvision->rdev); | 1541 | video_device_release(usbvision->rdev); |
1595 | } | 1542 | } |
1596 | usbvision->rdev = NULL; | 1543 | usbvision->rdev = NULL; |
@@ -1598,11 +1545,11 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) | |||
1598 | 1545 | ||
1599 | // Video Device: | 1546 | // Video Device: |
1600 | if (usbvision->vdev) { | 1547 | if (usbvision->vdev) { |
1601 | PDEBUG(DBG_PROBE, "unregister /dev/video%d [v4l2]", usbvision->vdev->minor & 0x1f); | 1548 | PDEBUG(DBG_PROBE, "unregister /dev/video%d [v4l2]", |
1549 | usbvision->vdev->minor & 0x1f); | ||
1602 | if (usbvision->vdev->minor != -1) { | 1550 | if (usbvision->vdev->minor != -1) { |
1603 | video_unregister_device(usbvision->vdev); | 1551 | video_unregister_device(usbvision->vdev); |
1604 | } | 1552 | } else { |
1605 | else { | ||
1606 | video_device_release(usbvision->vdev); | 1553 | video_device_release(usbvision->vdev); |
1607 | } | 1554 | } |
1608 | usbvision->vdev = NULL; | 1555 | usbvision->vdev = NULL; |
@@ -1613,37 +1560,52 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision) | |||
1613 | static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) | 1560 | static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) |
1614 | { | 1561 | { |
1615 | // Video Device: | 1562 | // Video Device: |
1616 | usbvision->vdev = usbvision_vdev_init(usbvision, &usbvision_video_template, "USBVision Video"); | 1563 | usbvision->vdev = usbvision_vdev_init(usbvision, |
1564 | &usbvision_video_template, | ||
1565 | "USBVision Video"); | ||
1617 | if (usbvision->vdev == NULL) { | 1566 | if (usbvision->vdev == NULL) { |
1618 | goto err_exit; | 1567 | goto err_exit; |
1619 | } | 1568 | } |
1620 | if (video_register_device(usbvision->vdev, VFL_TYPE_GRABBER, video_nr)<0) { | 1569 | if (video_register_device(usbvision->vdev, |
1570 | VFL_TYPE_GRABBER, | ||
1571 | video_nr)<0) { | ||
1621 | goto err_exit; | 1572 | goto err_exit; |
1622 | } | 1573 | } |
1623 | printk(KERN_INFO "USBVision[%d]: registered USBVision Video device /dev/video%d [v4l2]\n", usbvision->nr,usbvision->vdev->minor & 0x1f); | 1574 | printk(KERN_INFO "USBVision[%d]: registered USBVision Video device /dev/video%d [v4l2]\n", |
1575 | usbvision->nr,usbvision->vdev->minor & 0x1f); | ||
1624 | 1576 | ||
1625 | // Radio Device: | 1577 | // Radio Device: |
1626 | if (usbvision_device_data[usbvision->DevModel].Radio) { | 1578 | if (usbvision_device_data[usbvision->DevModel].Radio) { |
1627 | // usbvision has radio | 1579 | // usbvision has radio |
1628 | usbvision->rdev = usbvision_vdev_init(usbvision, &usbvision_radio_template, "USBVision Radio"); | 1580 | usbvision->rdev = usbvision_vdev_init(usbvision, |
1581 | &usbvision_radio_template, | ||
1582 | "USBVision Radio"); | ||
1629 | if (usbvision->rdev == NULL) { | 1583 | if (usbvision->rdev == NULL) { |
1630 | goto err_exit; | 1584 | goto err_exit; |
1631 | } | 1585 | } |
1632 | if (video_register_device(usbvision->rdev, VFL_TYPE_RADIO, radio_nr)<0) { | 1586 | if (video_register_device(usbvision->rdev, |
1587 | VFL_TYPE_RADIO, | ||
1588 | radio_nr)<0) { | ||
1633 | goto err_exit; | 1589 | goto err_exit; |
1634 | } | 1590 | } |
1635 | printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device /dev/radio%d [v4l2]\n", usbvision->nr, usbvision->rdev->minor & 0x1f); | 1591 | printk(KERN_INFO "USBVision[%d]: registered USBVision Radio device /dev/radio%d [v4l2]\n", |
1592 | usbvision->nr, usbvision->rdev->minor & 0x1f); | ||
1636 | } | 1593 | } |
1637 | // vbi Device: | 1594 | // vbi Device: |
1638 | if (usbvision_device_data[usbvision->DevModel].vbi) { | 1595 | if (usbvision_device_data[usbvision->DevModel].vbi) { |
1639 | usbvision->vbi = usbvision_vdev_init(usbvision, &usbvision_vbi_template, "USBVision VBI"); | 1596 | usbvision->vbi = usbvision_vdev_init(usbvision, |
1597 | &usbvision_vbi_template, | ||
1598 | "USBVision VBI"); | ||
1640 | if (usbvision->vdev == NULL) { | 1599 | if (usbvision->vdev == NULL) { |
1641 | goto err_exit; | 1600 | goto err_exit; |
1642 | } | 1601 | } |
1643 | if (video_register_device(usbvision->vbi, VFL_TYPE_VBI, vbi_nr)<0) { | 1602 | if (video_register_device(usbvision->vbi, |
1603 | VFL_TYPE_VBI, | ||
1604 | vbi_nr)<0) { | ||
1644 | goto err_exit; | 1605 | goto err_exit; |
1645 | } | 1606 | } |
1646 | printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device /dev/vbi%d [v4l2] (Not Working Yet!)\n", usbvision->nr,usbvision->vbi->minor & 0x1f); | 1607 | printk(KERN_INFO "USBVision[%d]: registered USBVision VBI device /dev/vbi%d [v4l2] (Not Working Yet!)\n", |
1608 | usbvision->nr,usbvision->vbi->minor & 0x1f); | ||
1647 | } | 1609 | } |
1648 | // all done | 1610 | // all done |
1649 | return 0; | 1611 | return 0; |
@@ -1657,7 +1619,8 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision) | |||
1657 | /* | 1619 | /* |
1658 | * usbvision_alloc() | 1620 | * usbvision_alloc() |
1659 | * | 1621 | * |
1660 | * This code allocates the struct usb_usbvision. It is filled with default values. | 1622 | * This code allocates the struct usb_usbvision. |
1623 | * It is filled with default values. | ||
1661 | * | 1624 | * |
1662 | * Returns NULL on error, a pointer to usb_usbvision else. | 1625 | * Returns NULL on error, a pointer to usb_usbvision else. |
1663 | * | 1626 | * |
@@ -1666,7 +1629,8 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev) | |||
1666 | { | 1629 | { |
1667 | struct usb_usbvision *usbvision; | 1630 | struct usb_usbvision *usbvision; |
1668 | 1631 | ||
1669 | if ((usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL)) == NULL) { | 1632 | if ((usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL)) == |
1633 | NULL) { | ||
1670 | goto err_exit; | 1634 | goto err_exit; |
1671 | } | 1635 | } |
1672 | 1636 | ||
@@ -1728,11 +1692,11 @@ static void usbvision_release(struct usb_usbvision *usbvision) | |||
1728 | } | 1692 | } |
1729 | 1693 | ||
1730 | 1694 | ||
1731 | /******************************** usb interface *****************************************/ | 1695 | /*********************** usb interface **********************************/ |
1732 | 1696 | ||
1733 | static void usbvision_configure_video(struct usb_usbvision *usbvision) | 1697 | static void usbvision_configure_video(struct usb_usbvision *usbvision) |
1734 | { | 1698 | { |
1735 | int model,i; | 1699 | int model; |
1736 | 1700 | ||
1737 | if (usbvision == NULL) | 1701 | if (usbvision == NULL) |
1738 | return; | 1702 | return; |
@@ -1741,25 +1705,23 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision) | |||
1741 | usbvision->palette = usbvision_v4l2_format[2]; // V4L2_PIX_FMT_RGB24; | 1705 | usbvision->palette = usbvision_v4l2_format[2]; // V4L2_PIX_FMT_RGB24; |
1742 | 1706 | ||
1743 | if (usbvision_device_data[usbvision->DevModel].Vin_Reg2_override) { | 1707 | if (usbvision_device_data[usbvision->DevModel].Vin_Reg2_override) { |
1744 | usbvision->Vin_Reg2_Preset = usbvision_device_data[usbvision->DevModel].Vin_Reg2; | 1708 | usbvision->Vin_Reg2_Preset = |
1709 | usbvision_device_data[usbvision->DevModel].Vin_Reg2; | ||
1745 | } else { | 1710 | } else { |
1746 | usbvision->Vin_Reg2_Preset = 0; | 1711 | usbvision->Vin_Reg2_Preset = 0; |
1747 | } | 1712 | } |
1748 | 1713 | ||
1749 | for (i = 0; i < TVNORMS; i++) | 1714 | usbvision->tvnormId = usbvision_device_data[model].VideoNorm; |
1750 | if (usbvision_device_data[model].VideoNorm == tvnorms[i].mode) | ||
1751 | break; | ||
1752 | if (i == TVNORMS) | ||
1753 | i = 0; | ||
1754 | usbvision->tvnorm = &tvnorms[i]; /* set default norm */ | ||
1755 | 1715 | ||
1756 | usbvision->video_inputs = usbvision_device_data[model].VideoChannels; | 1716 | usbvision->video_inputs = usbvision_device_data[model].VideoChannels; |
1757 | usbvision->ctl_input = 0; | 1717 | usbvision->ctl_input = 0; |
1758 | 1718 | ||
1759 | /* This should be here to make i2c clients to be able to register */ | 1719 | /* This should be here to make i2c clients to be able to register */ |
1760 | usbvision_audio_off(usbvision); //first switch off audio | 1720 | /* first switch off audio */ |
1721 | usbvision_audio_off(usbvision); | ||
1761 | if (!PowerOnAtOpen) { | 1722 | if (!PowerOnAtOpen) { |
1762 | usbvision_power_on(usbvision); //and then power up the noisy tuner | 1723 | /* and then power up the noisy tuner */ |
1724 | usbvision_power_on(usbvision); | ||
1763 | usbvision_i2c_register(usbvision); | 1725 | usbvision_i2c_register(usbvision); |
1764 | } | 1726 | } |
1765 | } | 1727 | } |
@@ -1796,18 +1758,22 @@ static int __devinit usbvision_probe(struct usb_interface *intf, | |||
1796 | 1758 | ||
1797 | if (usbvision_device_data[model].Interface >= 0) { | 1759 | if (usbvision_device_data[model].Interface >= 0) { |
1798 | interface = &dev->actconfig->interface[usbvision_device_data[model].Interface]->altsetting[0]; | 1760 | interface = &dev->actconfig->interface[usbvision_device_data[model].Interface]->altsetting[0]; |
1799 | } | 1761 | } else { |
1800 | else { | ||
1801 | interface = &dev->actconfig->interface[ifnum]->altsetting[0]; | 1762 | interface = &dev->actconfig->interface[ifnum]->altsetting[0]; |
1802 | } | 1763 | } |
1803 | endpoint = &interface->endpoint[1].desc; | 1764 | endpoint = &interface->endpoint[1].desc; |
1804 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) { | 1765 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != |
1805 | err("%s: interface %d. has non-ISO endpoint!", __FUNCTION__, ifnum); | 1766 | USB_ENDPOINT_XFER_ISOC) { |
1806 | err("%s: Endpoint attributes %d", __FUNCTION__, endpoint->bmAttributes); | 1767 | err("%s: interface %d. has non-ISO endpoint!", |
1768 | __FUNCTION__, ifnum); | ||
1769 | err("%s: Endpoint attributes %d", | ||
1770 | __FUNCTION__, endpoint->bmAttributes); | ||
1807 | return -ENODEV; | 1771 | return -ENODEV; |
1808 | } | 1772 | } |
1809 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { | 1773 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == |
1810 | err("%s: interface %d. has ISO OUT endpoint!", __FUNCTION__, ifnum); | 1774 | USB_DIR_OUT) { |
1775 | err("%s: interface %d. has ISO OUT endpoint!", | ||
1776 | __FUNCTION__, ifnum); | ||
1811 | return -ENODEV; | 1777 | return -ENODEV; |
1812 | } | 1778 | } |
1813 | 1779 | ||
@@ -1818,11 +1784,9 @@ static int __devinit usbvision_probe(struct usb_interface *intf, | |||
1818 | 1784 | ||
1819 | if (dev->descriptor.bNumConfigurations > 1) { | 1785 | if (dev->descriptor.bNumConfigurations > 1) { |
1820 | usbvision->bridgeType = BRIDGE_NT1004; | 1786 | usbvision->bridgeType = BRIDGE_NT1004; |
1821 | } | 1787 | } else if (model == DAZZLE_DVC_90_REV_1_SECAM) { |
1822 | else if (model == DAZZLE_DVC_90_REV_1_SECAM) { | ||
1823 | usbvision->bridgeType = BRIDGE_NT1005; | 1788 | usbvision->bridgeType = BRIDGE_NT1005; |
1824 | } | 1789 | } else { |
1825 | else { | ||
1826 | usbvision->bridgeType = BRIDGE_NT1003; | 1790 | usbvision->bridgeType = BRIDGE_NT1003; |
1827 | } | 1791 | } |
1828 | PDEBUG(DBG_PROBE, "bridgeType %d", usbvision->bridgeType); | 1792 | PDEBUG(DBG_PROBE, "bridgeType %d", usbvision->bridgeType); |
@@ -1919,11 +1883,11 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) | |||
1919 | up(&usbvision->lock); | 1883 | up(&usbvision->lock); |
1920 | 1884 | ||
1921 | if (usbvision->user) { | 1885 | if (usbvision->user) { |
1922 | printk(KERN_INFO "%s: In use, disconnect pending\n", __FUNCTION__); | 1886 | printk(KERN_INFO "%s: In use, disconnect pending\n", |
1887 | __FUNCTION__); | ||
1923 | wake_up_interruptible(&usbvision->wait_frame); | 1888 | wake_up_interruptible(&usbvision->wait_frame); |
1924 | wake_up_interruptible(&usbvision->wait_stream); | 1889 | wake_up_interruptible(&usbvision->wait_stream); |
1925 | } | 1890 | } else { |
1926 | else { | ||
1927 | usbvision_release(usbvision); | 1891 | usbvision_release(usbvision); |
1928 | } | 1892 | } |
1929 | 1893 | ||
@@ -1950,7 +1914,6 @@ static int __init usbvision_init(void) | |||
1950 | 1914 | ||
1951 | PDEBUG(DBG_PROBE, ""); | 1915 | PDEBUG(DBG_PROBE, ""); |
1952 | 1916 | ||
1953 | PDEBUG(DBG_IOCTL, "IOCTL debugging is enabled [video]"); | ||
1954 | PDEBUG(DBG_IO, "IO debugging is enabled [video]"); | 1917 | PDEBUG(DBG_IO, "IO debugging is enabled [video]"); |
1955 | PDEBUG(DBG_PROBE, "PROBE debugging is enabled [video]"); | 1918 | PDEBUG(DBG_PROBE, "PROBE debugging is enabled [video]"); |
1956 | PDEBUG(DBG_MMAP, "MMAP debugging is enabled [video]"); | 1919 | PDEBUG(DBG_MMAP, "MMAP debugging is enabled [video]"); |
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h index c759d00d7014..c5b6c501c869 100644 --- a/drivers/media/video/usbvision/usbvision.h +++ b/drivers/media/video/usbvision/usbvision.h | |||
@@ -221,6 +221,8 @@ enum { | |||
221 | 221 | ||
222 | #define I2C_USB_ADAP_MAX 16 | 222 | #define I2C_USB_ADAP_MAX 16 |
223 | 223 | ||
224 | #define USBVISION_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC | V4L2_STD_SECAM | V4L2_STD_PAL_M) | ||
225 | |||
224 | /* ----------------------------------------------------------------- */ | 226 | /* ----------------------------------------------------------------- */ |
225 | /* usbvision video structures */ | 227 | /* usbvision video structures */ |
226 | /* ----------------------------------------------------------------- */ | 228 | /* ----------------------------------------------------------------- */ |
@@ -301,14 +303,6 @@ struct usbvision_frame_header { | |||
301 | __u16 frameHeight; /* 10 - 11 after endian correction*/ | 303 | __u16 frameHeight; /* 10 - 11 after endian correction*/ |
302 | }; | 304 | }; |
303 | 305 | ||
304 | /* tvnorms */ | ||
305 | struct usbvision_tvnorm { | ||
306 | char *name; | ||
307 | v4l2_std_id id; | ||
308 | /* mode for saa7113h */ | ||
309 | int mode; | ||
310 | }; | ||
311 | |||
312 | struct usbvision_frame { | 306 | struct usbvision_frame { |
313 | char *data; /* Frame buffer */ | 307 | char *data; /* Frame buffer */ |
314 | struct usbvision_frame_header isocHeader; /* Header from stream */ | 308 | struct usbvision_frame_header isocHeader; /* Header from stream */ |
@@ -386,7 +380,6 @@ struct usb_usbvision { | |||
386 | int tuner_type; | 380 | int tuner_type; |
387 | int tuner_addr; | 381 | int tuner_addr; |
388 | int bridgeType; // NT1003, NT1004, NT1005 | 382 | int bridgeType; // NT1003, NT1004, NT1005 |
389 | int channel; | ||
390 | int radio; | 383 | int radio; |
391 | int video_inputs; // # of inputs | 384 | int video_inputs; // # of inputs |
392 | unsigned long freq; | 385 | unsigned long freq; |
@@ -441,7 +434,7 @@ struct usb_usbvision { | |||
441 | 434 | ||
442 | struct v4l2_capability vcap; /* Video capabilities */ | 435 | struct v4l2_capability vcap; /* Video capabilities */ |
443 | unsigned int ctl_input; /* selected input */ | 436 | unsigned int ctl_input; /* selected input */ |
444 | struct usbvision_tvnorm *tvnorm; /* selected tv norm */ | 437 | v4l2_std_id tvnormId; /* selected tv norm */ |
445 | unsigned char video_endp; /* 0x82 for USBVISION devices based */ | 438 | unsigned char video_endp; /* 0x82 for USBVISION devices based */ |
446 | 439 | ||
447 | // Decompression stuff: | 440 | // Decompression stuff: |
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 0c658b74f2c4..e94a9a6036f5 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c | |||
@@ -2077,12 +2077,10 @@ static int vino_wait_for_frame(struct vino_channel_settings *vcs) | |||
2077 | init_waitqueue_entry(&wait, current); | 2077 | init_waitqueue_entry(&wait, current); |
2078 | /* add ourselves into wait queue */ | 2078 | /* add ourselves into wait queue */ |
2079 | add_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait); | 2079 | add_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait); |
2080 | /* and set current state */ | ||
2081 | set_current_state(TASK_INTERRUPTIBLE); | ||
2082 | 2080 | ||
2083 | /* to ensure that schedule_timeout will return immediately | 2081 | /* to ensure that schedule_timeout will return immediately |
2084 | * if VINO interrupt was triggred meanwhile */ | 2082 | * if VINO interrupt was triggered meanwhile */ |
2085 | schedule_timeout(HZ / 10); | 2083 | schedule_timeout_interruptible(HZ / 10); |
2086 | 2084 | ||
2087 | if (signal_pending(current)) | 2085 | if (signal_pending(current)) |
2088 | err = -EINTR; | 2086 | err = -EINTR; |
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 3ef4d0159c33..f6d3a9460ccc 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/random.h> | 26 | #include <linux/random.h> |
27 | #include <linux/version.h> | 27 | #include <linux/version.h> |
28 | #include <linux/mutex.h> | ||
28 | #include <linux/videodev2.h> | 29 | #include <linux/videodev2.h> |
29 | #include <linux/dma-mapping.h> | 30 | #include <linux/dma-mapping.h> |
30 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 31 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
@@ -145,9 +146,6 @@ struct vivi_buffer { | |||
145 | 146 | ||
146 | struct vivi_fmt *fmt; | 147 | struct vivi_fmt *fmt; |
147 | 148 | ||
148 | #ifdef CONFIG_VIVI_SCATTER | ||
149 | struct sg_to_addr *to_addr; | ||
150 | #endif | ||
151 | }; | 149 | }; |
152 | 150 | ||
153 | struct vivi_dmaqueue { | 151 | struct vivi_dmaqueue { |
@@ -168,7 +166,7 @@ static LIST_HEAD(vivi_devlist); | |||
168 | struct vivi_dev { | 166 | struct vivi_dev { |
169 | struct list_head vivi_devlist; | 167 | struct list_head vivi_devlist; |
170 | 168 | ||
171 | struct semaphore lock; | 169 | struct mutex lock; |
172 | 170 | ||
173 | int users; | 171 | int users; |
174 | 172 | ||
@@ -232,68 +230,13 @@ static u8 bars[8][3] = { | |||
232 | #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 | 230 | #define TSTAMP_MAX_Y TSTAMP_MIN_Y+15 |
233 | #define TSTAMP_MIN_X 64 | 231 | #define TSTAMP_MIN_X 64 |
234 | 232 | ||
235 | #ifdef CONFIG_VIVI_SCATTER | ||
236 | static void prep_to_addr(struct sg_to_addr to_addr[], | ||
237 | struct videobuf_buffer *vb) | ||
238 | { | ||
239 | int i, pos=0; | ||
240 | |||
241 | for (i=0;i<vb->dma.nr_pages;i++) { | ||
242 | to_addr[i].sg=&vb->dma.sglist[i]; | ||
243 | to_addr[i].pos=pos; | ||
244 | pos += vb->dma.sglist[i].length; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | static int get_addr_pos(int pos, int pages, struct sg_to_addr to_addr[]) | ||
249 | { | ||
250 | int p1=0,p2=pages-1,p3=pages/2; | ||
251 | |||
252 | /* Sanity test */ | ||
253 | BUG_ON (pos>=to_addr[p2].pos+to_addr[p2].sg->length); | ||
254 | |||
255 | while (p1+1<p2) { | ||
256 | if (pos < to_addr[p3].pos) { | ||
257 | p2=p3; | ||
258 | } else { | ||
259 | p1=p3; | ||
260 | } | ||
261 | p3=(p1+p2)/2; | ||
262 | } | ||
263 | if (pos >= to_addr[p2].pos) | ||
264 | p1=p2; | ||
265 | |||
266 | return (p1); | ||
267 | } | ||
268 | #endif | ||
269 | 233 | ||
270 | #ifdef CONFIG_VIVI_SCATTER | ||
271 | static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, | ||
272 | int hmax, int line, char *timestr) | ||
273 | #else | ||
274 | static void gen_line(char *basep,int inipos,int wmax, | 234 | static void gen_line(char *basep,int inipos,int wmax, |
275 | int hmax, int line, char *timestr) | 235 | int hmax, int line, char *timestr) |
276 | #endif | ||
277 | { | 236 | { |
278 | int w,i,j,pos=inipos,y; | 237 | int w,i,j,pos=inipos,y; |
279 | char *p,*s; | 238 | char *p,*s; |
280 | u8 chr,r,g,b,color; | 239 | u8 chr,r,g,b,color; |
281 | #ifdef CONFIG_VIVI_SCATTER | ||
282 | int pgpos,oldpg; | ||
283 | char *basep; | ||
284 | struct page *pg; | ||
285 | |||
286 | unsigned long flags; | ||
287 | spinlock_t spinlock; | ||
288 | |||
289 | spin_lock_init(&spinlock); | ||
290 | |||
291 | /* Get first addr pointed to pixel position */ | ||
292 | oldpg=get_addr_pos(pos,pages,to_addr); | ||
293 | pg=pfn_to_page(sg_dma_address(to_addr[oldpg].sg) >> PAGE_SHIFT); | ||
294 | spin_lock_irqsave(&spinlock,flags); | ||
295 | basep = kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[oldpg].sg->offset; | ||
296 | #endif | ||
297 | 240 | ||
298 | /* We will just duplicate the second pixel at the packet */ | 241 | /* We will just duplicate the second pixel at the packet */ |
299 | wmax/=2; | 242 | wmax/=2; |
@@ -305,18 +248,7 @@ static void gen_line(char *basep,int inipos,int wmax, | |||
305 | b=bars[w*7/wmax][2]; | 248 | b=bars[w*7/wmax][2]; |
306 | 249 | ||
307 | for (color=0;color<4;color++) { | 250 | for (color=0;color<4;color++) { |
308 | #ifdef CONFIG_VIVI_SCATTER | ||
309 | pgpos=get_addr_pos(pos,pages,to_addr); | ||
310 | if (pgpos!=oldpg) { | ||
311 | pg=pfn_to_page(sg_dma_address(to_addr[pgpos].sg) >> PAGE_SHIFT); | ||
312 | kunmap_atomic(basep, KM_BOUNCE_READ); | ||
313 | basep= kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[pgpos].sg->offset; | ||
314 | oldpg=pgpos; | ||
315 | } | ||
316 | p=basep+pos-to_addr[pgpos].pos; | ||
317 | #else | ||
318 | p=basep+pos; | 251 | p=basep+pos; |
319 | #endif | ||
320 | 252 | ||
321 | switch (color) { | 253 | switch (color) { |
322 | case 0: | 254 | case 0: |
@@ -361,23 +293,7 @@ static void gen_line(char *basep,int inipos,int wmax, | |||
361 | 293 | ||
362 | pos=inipos+j*2; | 294 | pos=inipos+j*2; |
363 | for (color=0;color<4;color++) { | 295 | for (color=0;color<4;color++) { |
364 | #ifdef CONFIG_VIVI_SCATTER | ||
365 | pgpos=get_addr_pos(pos,pages,to_addr); | ||
366 | if (pgpos!=oldpg) { | ||
367 | pg=pfn_to_page(sg_dma_address( | ||
368 | to_addr[pgpos].sg) | ||
369 | >> PAGE_SHIFT); | ||
370 | kunmap_atomic(basep, | ||
371 | KM_BOUNCE_READ); | ||
372 | basep= kmap_atomic(pg, | ||
373 | KM_BOUNCE_READ)+ | ||
374 | to_addr[pgpos].sg->offset; | ||
375 | oldpg=pgpos; | ||
376 | } | ||
377 | p=basep+pos-to_addr[pgpos].pos; | ||
378 | #else | ||
379 | p=basep+pos; | 296 | p=basep+pos; |
380 | #endif | ||
381 | 297 | ||
382 | y=TO_Y(r,g,b); | 298 | y=TO_Y(r,g,b); |
383 | 299 | ||
@@ -402,12 +318,7 @@ static void gen_line(char *basep,int inipos,int wmax, | |||
402 | 318 | ||
403 | 319 | ||
404 | end: | 320 | end: |
405 | #ifdef CONFIG_VIVI_SCATTER | ||
406 | kunmap_atomic(basep, KM_BOUNCE_READ); | ||
407 | spin_unlock_irqrestore(&spinlock,flags); | ||
408 | #else | ||
409 | return; | 321 | return; |
410 | #endif | ||
411 | } | 322 | } |
412 | static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) | 323 | static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) |
413 | { | 324 | { |
@@ -415,35 +326,16 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) | |||
415 | int hmax = buf->vb.height; | 326 | int hmax = buf->vb.height; |
416 | int wmax = buf->vb.width; | 327 | int wmax = buf->vb.width; |
417 | struct timeval ts; | 328 | struct timeval ts; |
418 | #ifdef CONFIG_VIVI_SCATTER | ||
419 | struct sg_to_addr *to_addr=buf->to_addr; | ||
420 | struct videobuf_buffer *vb=&buf->vb; | ||
421 | #else | ||
422 | char *tmpbuf; | 329 | char *tmpbuf; |
423 | #endif | ||
424 | |||
425 | #ifdef CONFIG_VIVI_SCATTER | ||
426 | /* Test if DMA mapping is ready */ | ||
427 | if (!sg_dma_address(&vb->dma.sglist[0])) | ||
428 | return; | ||
429 | |||
430 | prep_to_addr(to_addr,vb); | ||
431 | 330 | ||
432 | /* Check if there is enough memory */ | ||
433 | BUG_ON(buf->vb.dma.nr_pages << PAGE_SHIFT < (buf->vb.width*buf->vb.height)*2); | ||
434 | #else | ||
435 | if (buf->vb.dma.varea) { | 331 | if (buf->vb.dma.varea) { |
436 | tmpbuf=kmalloc (wmax*2, GFP_KERNEL); | 332 | tmpbuf=kmalloc (wmax*2, GFP_KERNEL); |
437 | } else { | 333 | } else { |
438 | tmpbuf=buf->vb.dma.vmalloc; | 334 | tmpbuf=buf->vb.dma.vmalloc; |
439 | } | 335 | } |
440 | 336 | ||
441 | #endif | ||
442 | 337 | ||
443 | for (h=0;h<hmax;h++) { | 338 | for (h=0;h<hmax;h++) { |
444 | #ifdef CONFIG_VIVI_SCATTER | ||
445 | gen_line(to_addr,pos,vb->dma.nr_pages,wmax,hmax,h,dev->timestr); | ||
446 | #else | ||
447 | if (buf->vb.dma.varea) { | 339 | if (buf->vb.dma.varea) { |
448 | gen_line(tmpbuf,0,wmax,hmax,h,dev->timestr); | 340 | gen_line(tmpbuf,0,wmax,hmax,h,dev->timestr); |
449 | /* FIXME: replacing to __copy_to_user */ | 341 | /* FIXME: replacing to __copy_to_user */ |
@@ -452,7 +344,6 @@ static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) | |||
452 | } else { | 344 | } else { |
453 | gen_line(tmpbuf,pos,wmax,hmax,h,dev->timestr); | 345 | gen_line(tmpbuf,pos,wmax,hmax,h,dev->timestr); |
454 | } | 346 | } |
455 | #endif | ||
456 | pos += wmax*2; | 347 | pos += wmax*2; |
457 | } | 348 | } |
458 | 349 | ||
@@ -718,11 +609,6 @@ static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) | |||
718 | if (in_interrupt()) | 609 | if (in_interrupt()) |
719 | BUG(); | 610 | BUG(); |
720 | 611 | ||
721 | #ifdef CONFIG_VIVI_SCATTER | ||
722 | /*FIXME: Maybe a spinlock is required here */ | ||
723 | kfree(buf->to_addr); | ||
724 | buf->to_addr=NULL; | ||
725 | #endif | ||
726 | 612 | ||
727 | videobuf_waiton(&buf->vb,0,0); | 613 | videobuf_waiton(&buf->vb,0,0); |
728 | videobuf_dma_unmap(vq, &buf->vb.dma); | 614 | videobuf_dma_unmap(vq, &buf->vb.dma); |
@@ -768,12 +654,6 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
768 | 654 | ||
769 | buf->vb.state = STATE_PREPARED; | 655 | buf->vb.state = STATE_PREPARED; |
770 | 656 | ||
771 | #ifdef CONFIG_VIVI_SCATTER | ||
772 | if (NULL == (buf->to_addr = kmalloc(sizeof(*buf->to_addr) * vb->dma.nr_pages,GFP_KERNEL))) { | ||
773 | rc=-ENOMEM; | ||
774 | goto fail; | ||
775 | } | ||
776 | #endif | ||
777 | return 0; | 657 | return 0; |
778 | 658 | ||
779 | fail: | 659 | fail: |
@@ -838,40 +718,6 @@ static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb | |||
838 | free_buffer(vq,buf); | 718 | free_buffer(vq,buf); |
839 | } | 719 | } |
840 | 720 | ||
841 | #ifdef CONFIG_VIVI_SCATTER | ||
842 | static int vivi_map_sg(void *dev, struct scatterlist *sg, int nents, | ||
843 | int direction) | ||
844 | { | ||
845 | int i; | ||
846 | |||
847 | dprintk(1,"%s, number of pages=%d\n",__FUNCTION__,nents); | ||
848 | BUG_ON(direction == DMA_NONE); | ||
849 | |||
850 | for (i = 0; i < nents; i++ ) { | ||
851 | BUG_ON(!sg[i].page); | ||
852 | |||
853 | sg_dma_address(&sg[i]) = page_to_phys(sg[i].page) + sg[i].offset; | ||
854 | } | ||
855 | |||
856 | return nents; | ||
857 | } | ||
858 | |||
859 | static int vivi_unmap_sg(void *dev,struct scatterlist *sglist,int nr_pages, | ||
860 | int direction) | ||
861 | { | ||
862 | dprintk(1,"%s\n",__FUNCTION__); | ||
863 | return 0; | ||
864 | } | ||
865 | |||
866 | static int vivi_dma_sync_sg(void *dev,struct scatterlist *sglist, int nr_pages, | ||
867 | int direction) | ||
868 | { | ||
869 | // dprintk(1,"%s\n",__FUNCTION__); | ||
870 | |||
871 | // flush_write_buffers(); | ||
872 | return 0; | ||
873 | } | ||
874 | #endif | ||
875 | 721 | ||
876 | static struct videobuf_queue_ops vivi_video_qops = { | 722 | static struct videobuf_queue_ops vivi_video_qops = { |
877 | .buf_setup = buffer_setup, | 723 | .buf_setup = buffer_setup, |
@@ -893,16 +739,16 @@ static struct videobuf_queue_ops vivi_video_qops = { | |||
893 | static int res_get(struct vivi_dev *dev, struct vivi_fh *fh) | 739 | static int res_get(struct vivi_dev *dev, struct vivi_fh *fh) |
894 | { | 740 | { |
895 | /* is it free? */ | 741 | /* is it free? */ |
896 | down(&dev->lock); | 742 | mutex_lock(&dev->lock); |
897 | if (dev->resources) { | 743 | if (dev->resources) { |
898 | /* no, someone else uses it */ | 744 | /* no, someone else uses it */ |
899 | up(&dev->lock); | 745 | mutex_unlock(&dev->lock); |
900 | return 0; | 746 | return 0; |
901 | } | 747 | } |
902 | /* it's free, grab it */ | 748 | /* it's free, grab it */ |
903 | dev->resources =1; | 749 | dev->resources =1; |
904 | dprintk(1,"res: get\n"); | 750 | dprintk(1,"res: get\n"); |
905 | up(&dev->lock); | 751 | mutex_unlock(&dev->lock); |
906 | return 1; | 752 | return 1; |
907 | } | 753 | } |
908 | 754 | ||
@@ -913,10 +759,10 @@ static int res_locked(struct vivi_dev *dev) | |||
913 | 759 | ||
914 | static void res_free(struct vivi_dev *dev, struct vivi_fh *fh) | 760 | static void res_free(struct vivi_dev *dev, struct vivi_fh *fh) |
915 | { | 761 | { |
916 | down(&dev->lock); | 762 | mutex_lock(&dev->lock); |
917 | dev->resources = 0; | 763 | dev->resources = 0; |
918 | dprintk(1,"res: put\n"); | 764 | dprintk(1,"res: put\n"); |
919 | up(&dev->lock); | 765 | mutex_lock(&dev->lock); |
920 | } | 766 | } |
921 | 767 | ||
922 | /* ------------------------------------------------------------------ | 768 | /* ------------------------------------------------------------------ |
@@ -1260,19 +1106,11 @@ static int vivi_open(struct inode *inode, struct file *file) | |||
1260 | sprintf(dev->timestr,"%02d:%02d:%02d:%03d", | 1106 | sprintf(dev->timestr,"%02d:%02d:%02d:%03d", |
1261 | dev->h,dev->m,dev->s,(dev->us+500)/1000); | 1107 | dev->h,dev->m,dev->s,(dev->us+500)/1000); |
1262 | 1108 | ||
1263 | #ifdef CONFIG_VIVI_SCATTER | ||
1264 | videobuf_queue_init(&fh->vb_vidq,VIDEOBUF_DMA_SCATTER, &vivi_video_qops, | ||
1265 | NULL, NULL, | ||
1266 | fh->type, | ||
1267 | V4L2_FIELD_INTERLACED, | ||
1268 | sizeof(struct vivi_buffer),fh); | ||
1269 | #else | ||
1270 | videobuf_queue_init(&fh->vb_vidq, &vivi_video_qops, | 1109 | videobuf_queue_init(&fh->vb_vidq, &vivi_video_qops, |
1271 | NULL, NULL, | 1110 | NULL, NULL, |
1272 | fh->type, | 1111 | fh->type, |
1273 | V4L2_FIELD_INTERLACED, | 1112 | V4L2_FIELD_INTERLACED, |
1274 | sizeof(struct vivi_buffer),fh); | 1113 | sizeof(struct vivi_buffer),fh); |
1275 | #endif | ||
1276 | 1114 | ||
1277 | return 0; | 1115 | return 0; |
1278 | } | 1116 | } |
@@ -1423,7 +1261,7 @@ static int __init vivi_init(void) | |||
1423 | init_waitqueue_head(&dev->vidq.wq); | 1261 | init_waitqueue_head(&dev->vidq.wq); |
1424 | 1262 | ||
1425 | /* initialize locks */ | 1263 | /* initialize locks */ |
1426 | init_MUTEX(&dev->lock); | 1264 | mutex_init(&dev->lock); |
1427 | 1265 | ||
1428 | dev->vidq.timeout.function = vivi_vid_timeout; | 1266 | dev->vidq.timeout.function = vivi_vid_timeout; |
1429 | dev->vidq.timeout.data = (unsigned long)dev; | 1267 | dev->vidq.timeout.data = (unsigned long)dev; |
diff --git a/drivers/media/video/zc0301/Kconfig b/drivers/media/video/zc0301/Kconfig index 47cd93f9c7de..edb00293cd59 100644 --- a/drivers/media/video/zc0301/Kconfig +++ b/drivers/media/video/zc0301/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config USB_ZC0301 | 1 | config USB_ZC0301 |
2 | tristate "USB ZC0301[P] Image Processor and Control Chip support" | 2 | tristate "USB ZC0301[P] Image Processor and Control Chip support" |
3 | depends on VIDEO_V4L1 | 3 | depends on VIDEO_V4L2 |
4 | ---help--- | 4 | ---help--- |
5 | Say Y here if you want support for cameras based on the ZC0301 or | 5 | Say Y here if you want support for cameras based on the ZC0301 or |
6 | ZC0301P Image Processors and Control Chips. | 6 | ZC0301P Image Processors and Control Chips. |
diff --git a/drivers/media/video/zc0301/zc0301.h b/drivers/media/video/zc0301/zc0301.h index 710f12eb9126..a2de50efa31a 100644 --- a/drivers/media/video/zc0301/zc0301.h +++ b/drivers/media/video/zc0301/zc0301.h | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/rwsem.h> | 36 | #include <linux/rwsem.h> |
37 | #include <linux/stddef.h> | 37 | #include <linux/stddef.h> |
38 | #include <linux/string.h> | 38 | #include <linux/string.h> |
39 | #include <linux/kref.h> | ||
39 | 40 | ||
40 | #include "zc0301_sensor.h" | 41 | #include "zc0301_sensor.h" |
41 | 42 | ||
@@ -98,7 +99,7 @@ struct zc0301_module_param { | |||
98 | u16 frame_timeout; | 99 | u16 frame_timeout; |
99 | }; | 100 | }; |
100 | 101 | ||
101 | static DECLARE_RWSEM(zc0301_disconnect); | 102 | static DECLARE_RWSEM(zc0301_dev_lock); |
102 | 103 | ||
103 | struct zc0301_device { | 104 | struct zc0301_device { |
104 | struct video_device* v4ldev; | 105 | struct video_device* v4ldev; |
@@ -121,12 +122,14 @@ struct zc0301_device { | |||
121 | 122 | ||
122 | struct zc0301_module_param module_param; | 123 | struct zc0301_module_param module_param; |
123 | 124 | ||
125 | struct kref kref; | ||
124 | enum zc0301_dev_state state; | 126 | enum zc0301_dev_state state; |
125 | u8 users; | 127 | u8 users; |
126 | 128 | ||
127 | struct mutex dev_mutex, fileop_mutex; | 129 | struct completion probe; |
130 | struct mutex open_mutex, fileop_mutex; | ||
128 | spinlock_t queue_lock; | 131 | spinlock_t queue_lock; |
129 | wait_queue_head_t open, wait_frame, wait_stream; | 132 | wait_queue_head_t wait_open, wait_frame, wait_stream; |
130 | }; | 133 | }; |
131 | 134 | ||
132 | /*****************************************************************************/ | 135 | /*****************************************************************************/ |
@@ -156,8 +159,8 @@ do { \ | |||
156 | else if ((level) == 2) \ | 159 | else if ((level) == 2) \ |
157 | dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ | 160 | dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ |
158 | else if ((level) >= 3) \ | 161 | else if ((level) >= 3) \ |
159 | dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ | 162 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \ |
160 | __FUNCTION__, __LINE__ , ## args); \ | 163 | __FILE__, __FUNCTION__, __LINE__ , ## args); \ |
161 | } \ | 164 | } \ |
162 | } while (0) | 165 | } while (0) |
163 | # define KDBG(level, fmt, args...) \ | 166 | # define KDBG(level, fmt, args...) \ |
@@ -166,8 +169,8 @@ do { \ | |||
166 | if ((level) == 1 || (level) == 2) \ | 169 | if ((level) == 1 || (level) == 2) \ |
167 | pr_info("zc0301: " fmt "\n", ## args); \ | 170 | pr_info("zc0301: " fmt "\n", ## args); \ |
168 | else if ((level) == 3) \ | 171 | else if ((level) == 3) \ |
169 | pr_debug("zc0301: [%s:%d] " fmt "\n", __FUNCTION__, \ | 172 | pr_debug("sn9c102: [%s:%s:%d] " fmt "\n", __FILE__, \ |
170 | __LINE__ , ## args); \ | 173 | __FUNCTION__, __LINE__ , ## args); \ |
171 | } \ | 174 | } \ |
172 | } while (0) | 175 | } while (0) |
173 | # define V4LDBG(level, name, cmd) \ | 176 | # define V4LDBG(level, name, cmd) \ |
@@ -183,8 +186,8 @@ do { \ | |||
183 | 186 | ||
184 | #undef PDBG | 187 | #undef PDBG |
185 | #define PDBG(fmt, args...) \ | 188 | #define PDBG(fmt, args...) \ |
186 | dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ | 189 | dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \ |
187 | __FUNCTION__, __LINE__ , ## args) | 190 | __LINE__ , ## args) |
188 | 191 | ||
189 | #undef PDBGG | 192 | #undef PDBGG |
190 | #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ | 193 | #define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ |
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c index f1120551c70c..703b741e46df 100644 --- a/drivers/media/video/zc0301/zc0301_core.c +++ b/drivers/media/video/zc0301/zc0301_core.c | |||
@@ -49,11 +49,11 @@ | |||
49 | 49 | ||
50 | #define ZC0301_MODULE_NAME "V4L2 driver for ZC0301[P] " \ | 50 | #define ZC0301_MODULE_NAME "V4L2 driver for ZC0301[P] " \ |
51 | "Image Processor and Control Chip" | 51 | "Image Processor and Control Chip" |
52 | #define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia" | 52 | #define ZC0301_MODULE_AUTHOR "(C) 2006-2007 Luca Risolia" |
53 | #define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" | 53 | #define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" |
54 | #define ZC0301_MODULE_LICENSE "GPL" | 54 | #define ZC0301_MODULE_LICENSE "GPL" |
55 | #define ZC0301_MODULE_VERSION "1:1.07" | 55 | #define ZC0301_MODULE_VERSION "1:1.10" |
56 | #define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 7) | 56 | #define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 10) |
57 | 57 | ||
58 | /*****************************************************************************/ | 58 | /*****************************************************************************/ |
59 | 59 | ||
@@ -573,7 +573,8 @@ static int zc0301_init(struct zc0301_device* cam) | |||
573 | int err = 0; | 573 | int err = 0; |
574 | 574 | ||
575 | if (!(cam->state & DEV_INITIALIZED)) { | 575 | if (!(cam->state & DEV_INITIALIZED)) { |
576 | init_waitqueue_head(&cam->open); | 576 | mutex_init(&cam->open_mutex); |
577 | init_waitqueue_head(&cam->wait_open); | ||
577 | qctrl = s->qctrl; | 578 | qctrl = s->qctrl; |
578 | rect = &(s->cropcap.defrect); | 579 | rect = &(s->cropcap.defrect); |
579 | cam->compression.quality = ZC0301_COMPRESSION_QUALITY; | 580 | cam->compression.quality = ZC0301_COMPRESSION_QUALITY; |
@@ -634,59 +635,73 @@ static int zc0301_init(struct zc0301_device* cam) | |||
634 | return 0; | 635 | return 0; |
635 | } | 636 | } |
636 | 637 | ||
638 | /*****************************************************************************/ | ||
637 | 639 | ||
638 | static void zc0301_release_resources(struct zc0301_device* cam) | 640 | static void zc0301_release_resources(struct kref *kref) |
639 | { | 641 | { |
642 | struct zc0301_device *cam = container_of(kref, struct zc0301_device, | ||
643 | kref); | ||
640 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); | 644 | DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); |
641 | video_set_drvdata(cam->v4ldev, NULL); | 645 | video_set_drvdata(cam->v4ldev, NULL); |
642 | video_unregister_device(cam->v4ldev); | 646 | video_unregister_device(cam->v4ldev); |
647 | usb_put_dev(cam->usbdev); | ||
643 | kfree(cam->control_buffer); | 648 | kfree(cam->control_buffer); |
649 | kfree(cam); | ||
644 | } | 650 | } |
645 | 651 | ||
646 | /*****************************************************************************/ | ||
647 | 652 | ||
648 | static int zc0301_open(struct inode* inode, struct file* filp) | 653 | static int zc0301_open(struct inode* inode, struct file* filp) |
649 | { | 654 | { |
650 | struct zc0301_device* cam; | 655 | struct zc0301_device* cam; |
651 | int err = 0; | 656 | int err = 0; |
652 | 657 | ||
653 | /* | 658 | if (!down_read_trylock(&zc0301_dev_lock)) |
654 | This is the only safe way to prevent race conditions with | ||
655 | disconnect | ||
656 | */ | ||
657 | if (!down_read_trylock(&zc0301_disconnect)) | ||
658 | return -ERESTARTSYS; | 659 | return -ERESTARTSYS; |
659 | 660 | ||
660 | cam = video_get_drvdata(video_devdata(filp)); | 661 | cam = video_get_drvdata(video_devdata(filp)); |
661 | 662 | ||
662 | if (mutex_lock_interruptible(&cam->dev_mutex)) { | 663 | if (wait_for_completion_interruptible(&cam->probe)) { |
663 | up_read(&zc0301_disconnect); | 664 | up_read(&zc0301_dev_lock); |
664 | return -ERESTARTSYS; | 665 | return -ERESTARTSYS; |
665 | } | 666 | } |
666 | 667 | ||
668 | kref_get(&cam->kref); | ||
669 | |||
670 | if (mutex_lock_interruptible(&cam->open_mutex)) { | ||
671 | kref_put(&cam->kref, zc0301_release_resources); | ||
672 | up_read(&zc0301_dev_lock); | ||
673 | return -ERESTARTSYS; | ||
674 | } | ||
675 | |||
676 | if (cam->state & DEV_DISCONNECTED) { | ||
677 | DBG(1, "Device not present"); | ||
678 | err = -ENODEV; | ||
679 | goto out; | ||
680 | } | ||
681 | |||
667 | if (cam->users) { | 682 | if (cam->users) { |
668 | DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor); | 683 | DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor); |
684 | DBG(3, "Simultaneous opens are not supported"); | ||
669 | if ((filp->f_flags & O_NONBLOCK) || | 685 | if ((filp->f_flags & O_NONBLOCK) || |
670 | (filp->f_flags & O_NDELAY)) { | 686 | (filp->f_flags & O_NDELAY)) { |
671 | err = -EWOULDBLOCK; | 687 | err = -EWOULDBLOCK; |
672 | goto out; | 688 | goto out; |
673 | } | 689 | } |
674 | mutex_unlock(&cam->dev_mutex); | 690 | DBG(2, "A blocking open() has been requested. Wait for the " |
675 | err = wait_event_interruptible_exclusive(cam->open, | 691 | "device to be released..."); |
676 | cam->state & DEV_DISCONNECTED | 692 | up_read(&zc0301_dev_lock); |
693 | err = wait_event_interruptible_exclusive(cam->wait_open, | ||
694 | (cam->state & DEV_DISCONNECTED) | ||
677 | || !cam->users); | 695 | || !cam->users); |
678 | if (err) { | 696 | down_read(&zc0301_dev_lock); |
679 | up_read(&zc0301_disconnect); | 697 | if (err) |
680 | return err; | 698 | goto out; |
681 | } | ||
682 | if (cam->state & DEV_DISCONNECTED) { | 699 | if (cam->state & DEV_DISCONNECTED) { |
683 | up_read(&zc0301_disconnect); | 700 | err = -ENODEV; |
684 | return -ENODEV; | 701 | goto out; |
685 | } | 702 | } |
686 | mutex_lock(&cam->dev_mutex); | ||
687 | } | 703 | } |
688 | 704 | ||
689 | |||
690 | if (cam->state & DEV_MISCONFIGURED) { | 705 | if (cam->state & DEV_MISCONFIGURED) { |
691 | err = zc0301_init(cam); | 706 | err = zc0301_init(cam); |
692 | if (err) { | 707 | if (err) { |
@@ -711,36 +726,32 @@ static int zc0301_open(struct inode* inode, struct file* filp) | |||
711 | DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); | 726 | DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); |
712 | 727 | ||
713 | out: | 728 | out: |
714 | mutex_unlock(&cam->dev_mutex); | 729 | mutex_unlock(&cam->open_mutex); |
715 | up_read(&zc0301_disconnect); | 730 | if (err) |
731 | kref_put(&cam->kref, zc0301_release_resources); | ||
732 | up_read(&zc0301_dev_lock); | ||
716 | return err; | 733 | return err; |
717 | } | 734 | } |
718 | 735 | ||
719 | 736 | ||
720 | static int zc0301_release(struct inode* inode, struct file* filp) | 737 | static int zc0301_release(struct inode* inode, struct file* filp) |
721 | { | 738 | { |
722 | struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); | 739 | struct zc0301_device* cam; |
723 | 740 | ||
724 | mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */ | 741 | down_write(&zc0301_dev_lock); |
725 | 742 | ||
726 | zc0301_stop_transfer(cam); | 743 | cam = video_get_drvdata(video_devdata(filp)); |
727 | 744 | ||
745 | zc0301_stop_transfer(cam); | ||
728 | zc0301_release_buffers(cam); | 746 | zc0301_release_buffers(cam); |
729 | |||
730 | if (cam->state & DEV_DISCONNECTED) { | ||
731 | zc0301_release_resources(cam); | ||
732 | usb_put_dev(cam->usbdev); | ||
733 | mutex_unlock(&cam->dev_mutex); | ||
734 | kfree(cam); | ||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | cam->users--; | 747 | cam->users--; |
739 | wake_up_interruptible_nr(&cam->open, 1); | 748 | wake_up_interruptible_nr(&cam->wait_open, 1); |
740 | 749 | ||
741 | DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); | 750 | DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); |
742 | 751 | ||
743 | mutex_unlock(&cam->dev_mutex); | 752 | kref_put(&cam->kref, zc0301_release_resources); |
753 | |||
754 | up_write(&zc0301_dev_lock); | ||
744 | 755 | ||
745 | return 0; | 756 | return 0; |
746 | } | 757 | } |
@@ -775,7 +786,7 @@ zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos) | |||
775 | DBG(3, "Close and open the device again to choose the read " | 786 | DBG(3, "Close and open the device again to choose the read " |
776 | "method"); | 787 | "method"); |
777 | mutex_unlock(&cam->fileop_mutex); | 788 | mutex_unlock(&cam->fileop_mutex); |
778 | return -EINVAL; | 789 | return -EBUSY; |
779 | } | 790 | } |
780 | 791 | ||
781 | if (cam->io == IO_NONE) { | 792 | if (cam->io == IO_NONE) { |
@@ -953,7 +964,12 @@ static int zc0301_mmap(struct file* filp, struct vm_area_struct *vma) | |||
953 | return -EIO; | 964 | return -EIO; |
954 | } | 965 | } |
955 | 966 | ||
956 | if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || | 967 | if (!(vma->vm_flags & (VM_WRITE | VM_READ))) { |
968 | mutex_unlock(&cam->fileop_mutex); | ||
969 | return -EACCES; | ||
970 | } | ||
971 | |||
972 | if (cam->io != IO_MMAP || | ||
957 | size != PAGE_ALIGN(cam->frame[0].buf.length)) { | 973 | size != PAGE_ALIGN(cam->frame[0].buf.length)) { |
958 | mutex_unlock(&cam->fileop_mutex); | 974 | mutex_unlock(&cam->fileop_mutex); |
959 | return -EINVAL; | 975 | return -EINVAL; |
@@ -984,7 +1000,6 @@ static int zc0301_mmap(struct file* filp, struct vm_area_struct *vma) | |||
984 | 1000 | ||
985 | vma->vm_ops = &zc0301_vm_ops; | 1001 | vma->vm_ops = &zc0301_vm_ops; |
986 | vma->vm_private_data = &cam->frame[i]; | 1002 | vma->vm_private_data = &cam->frame[i]; |
987 | |||
988 | zc0301_vm_open(vma); | 1003 | zc0301_vm_open(vma); |
989 | 1004 | ||
990 | mutex_unlock(&cam->fileop_mutex); | 1005 | mutex_unlock(&cam->fileop_mutex); |
@@ -1211,7 +1226,7 @@ zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg) | |||
1211 | if (cam->frame[i].vma_use_count) { | 1226 | if (cam->frame[i].vma_use_count) { |
1212 | DBG(3, "VIDIOC_S_CROP failed. " | 1227 | DBG(3, "VIDIOC_S_CROP failed. " |
1213 | "Unmap the buffers first."); | 1228 | "Unmap the buffers first."); |
1214 | return -EINVAL; | 1229 | return -EBUSY; |
1215 | } | 1230 | } |
1216 | 1231 | ||
1217 | if (!s->set_crop) { | 1232 | if (!s->set_crop) { |
@@ -1434,7 +1449,7 @@ zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd, | |||
1434 | if (cam->frame[i].vma_use_count) { | 1449 | if (cam->frame[i].vma_use_count) { |
1435 | DBG(3, "VIDIOC_S_FMT failed. " | 1450 | DBG(3, "VIDIOC_S_FMT failed. " |
1436 | "Unmap the buffers first."); | 1451 | "Unmap the buffers first."); |
1437 | return -EINVAL; | 1452 | return -EBUSY; |
1438 | } | 1453 | } |
1439 | 1454 | ||
1440 | if (cam->stream == STREAM_ON) | 1455 | if (cam->stream == STREAM_ON) |
@@ -1544,14 +1559,14 @@ zc0301_vidioc_reqbufs(struct zc0301_device* cam, void __user * arg) | |||
1544 | if (cam->io == IO_READ) { | 1559 | if (cam->io == IO_READ) { |
1545 | DBG(3, "Close and open the device again to choose the mmap " | 1560 | DBG(3, "Close and open the device again to choose the mmap " |
1546 | "I/O method"); | 1561 | "I/O method"); |
1547 | return -EINVAL; | 1562 | return -EBUSY; |
1548 | } | 1563 | } |
1549 | 1564 | ||
1550 | for (i = 0; i < cam->nbuffers; i++) | 1565 | for (i = 0; i < cam->nbuffers; i++) |
1551 | if (cam->frame[i].vma_use_count) { | 1566 | if (cam->frame[i].vma_use_count) { |
1552 | DBG(3, "VIDIOC_REQBUFS failed. " | 1567 | DBG(3, "VIDIOC_REQBUFS failed. " |
1553 | "Previous buffers are still mapped."); | 1568 | "Previous buffers are still mapped."); |
1554 | return -EINVAL; | 1569 | return -EBUSY; |
1555 | } | 1570 | } |
1556 | 1571 | ||
1557 | if (cam->stream == STREAM_ON) | 1572 | if (cam->stream == STREAM_ON) |
@@ -1699,9 +1714,6 @@ zc0301_vidioc_streamon(struct zc0301_device* cam, void __user * arg) | |||
1699 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) | 1714 | if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) |
1700 | return -EINVAL; | 1715 | return -EINVAL; |
1701 | 1716 | ||
1702 | if (list_empty(&cam->inqueue)) | ||
1703 | return -EINVAL; | ||
1704 | |||
1705 | cam->stream = STREAM_ON; | 1717 | cam->stream = STREAM_ON; |
1706 | 1718 | ||
1707 | DBG(3, "Stream on"); | 1719 | DBG(3, "Stream on"); |
@@ -1949,8 +1961,6 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
1949 | goto fail; | 1961 | goto fail; |
1950 | } | 1962 | } |
1951 | 1963 | ||
1952 | mutex_init(&cam->dev_mutex); | ||
1953 | |||
1954 | DBG(2, "ZC0301[P] Image Processor and Control Chip detected " | 1964 | DBG(2, "ZC0301[P] Image Processor and Control Chip detected " |
1955 | "(vid/pid 0x%04X:0x%04X)",id->idVendor, id->idProduct); | 1965 | "(vid/pid 0x%04X:0x%04X)",id->idVendor, id->idProduct); |
1956 | 1966 | ||
@@ -1982,7 +1992,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
1982 | cam->v4ldev->release = video_device_release; | 1992 | cam->v4ldev->release = video_device_release; |
1983 | video_set_drvdata(cam->v4ldev, cam); | 1993 | video_set_drvdata(cam->v4ldev, cam); |
1984 | 1994 | ||
1985 | mutex_lock(&cam->dev_mutex); | 1995 | init_completion(&cam->probe); |
1986 | 1996 | ||
1987 | err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, | 1997 | err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, |
1988 | video_nr[dev_nr]); | 1998 | video_nr[dev_nr]); |
@@ -1992,7 +2002,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
1992 | DBG(1, "Free /dev/videoX node not found"); | 2002 | DBG(1, "Free /dev/videoX node not found"); |
1993 | video_nr[dev_nr] = -1; | 2003 | video_nr[dev_nr] = -1; |
1994 | dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0; | 2004 | dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0; |
1995 | mutex_unlock(&cam->dev_mutex); | 2005 | complete_all(&cam->probe); |
1996 | goto fail; | 2006 | goto fail; |
1997 | } | 2007 | } |
1998 | 2008 | ||
@@ -2004,8 +2014,10 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) | |||
2004 | dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0; | 2014 | dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0; |
2005 | 2015 | ||
2006 | usb_set_intfdata(intf, cam); | 2016 | usb_set_intfdata(intf, cam); |
2017 | kref_init(&cam->kref); | ||
2018 | usb_get_dev(cam->usbdev); | ||
2007 | 2019 | ||
2008 | mutex_unlock(&cam->dev_mutex); | 2020 | complete_all(&cam->probe); |
2009 | 2021 | ||
2010 | return 0; | 2022 | return 0; |
2011 | 2023 | ||
@@ -2022,40 +2034,31 @@ fail: | |||
2022 | 2034 | ||
2023 | static void zc0301_usb_disconnect(struct usb_interface* intf) | 2035 | static void zc0301_usb_disconnect(struct usb_interface* intf) |
2024 | { | 2036 | { |
2025 | struct zc0301_device* cam = usb_get_intfdata(intf); | 2037 | struct zc0301_device* cam; |
2026 | |||
2027 | if (!cam) | ||
2028 | return; | ||
2029 | 2038 | ||
2030 | down_write(&zc0301_disconnect); | 2039 | down_write(&zc0301_dev_lock); |
2031 | 2040 | ||
2032 | mutex_lock(&cam->dev_mutex); | 2041 | cam = usb_get_intfdata(intf); |
2033 | 2042 | ||
2034 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); | 2043 | DBG(2, "Disconnecting %s...", cam->v4ldev->name); |
2035 | 2044 | ||
2036 | wake_up_interruptible_all(&cam->open); | ||
2037 | |||
2038 | if (cam->users) { | 2045 | if (cam->users) { |
2039 | DBG(2, "Device /dev/video%d is open! Deregistration and " | 2046 | DBG(2, "Device /dev/video%d is open! Deregistration and " |
2040 | "memory deallocation are deferred on close.", | 2047 | "memory deallocation are deferred.", |
2041 | cam->v4ldev->minor); | 2048 | cam->v4ldev->minor); |
2042 | cam->state |= DEV_MISCONFIGURED; | 2049 | cam->state |= DEV_MISCONFIGURED; |
2043 | zc0301_stop_transfer(cam); | 2050 | zc0301_stop_transfer(cam); |
2044 | cam->state |= DEV_DISCONNECTED; | 2051 | cam->state |= DEV_DISCONNECTED; |
2045 | wake_up_interruptible(&cam->wait_frame); | 2052 | wake_up_interruptible(&cam->wait_frame); |
2046 | wake_up(&cam->wait_stream); | 2053 | wake_up(&cam->wait_stream); |
2047 | usb_get_dev(cam->usbdev); | 2054 | } else |
2048 | } else { | ||
2049 | cam->state |= DEV_DISCONNECTED; | 2055 | cam->state |= DEV_DISCONNECTED; |
2050 | zc0301_release_resources(cam); | ||
2051 | } | ||
2052 | 2056 | ||
2053 | mutex_unlock(&cam->dev_mutex); | 2057 | wake_up_interruptible_all(&cam->wait_open); |
2054 | 2058 | ||
2055 | if (!cam->users) | 2059 | kref_put(&cam->kref, zc0301_release_resources); |
2056 | kfree(cam); | ||
2057 | 2060 | ||
2058 | up_write(&zc0301_disconnect); | 2061 | up_write(&zc0301_dev_lock); |
2059 | } | 2062 | } |
2060 | 2063 | ||
2061 | 2064 | ||
diff --git a/drivers/media/video/zc0301/zc0301_pas202bcb.c b/drivers/media/video/zc0301/zc0301_pas202bcb.c index 3efb92a0d0da..24b0dfba357e 100644 --- a/drivers/media/video/zc0301/zc0301_pas202bcb.c +++ b/drivers/media/video/zc0301/zc0301_pas202bcb.c | |||
@@ -327,6 +327,7 @@ static struct zc0301_sensor pas202bcb = { | |||
327 | .height = 480, | 327 | .height = 480, |
328 | .pixelformat = V4L2_PIX_FMT_JPEG, | 328 | .pixelformat = V4L2_PIX_FMT_JPEG, |
329 | .priv = 8, | 329 | .priv = 8, |
330 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
330 | }, | 331 | }, |
331 | }; | 332 | }; |
332 | 333 | ||
diff --git a/drivers/media/video/zc0301/zc0301_pb0330.c b/drivers/media/video/zc0301/zc0301_pb0330.c index 5784b1d1491c..9519aba3612e 100644 --- a/drivers/media/video/zc0301/zc0301_pb0330.c +++ b/drivers/media/video/zc0301/zc0301_pb0330.c | |||
@@ -157,6 +157,7 @@ static struct zc0301_sensor pb0330 = { | |||
157 | .height = 480, | 157 | .height = 480, |
158 | .pixelformat = V4L2_PIX_FMT_JPEG, | 158 | .pixelformat = V4L2_PIX_FMT_JPEG, |
159 | .priv = 8, | 159 | .priv = 8, |
160 | .colorspace = V4L2_COLORSPACE_JPEG, | ||
160 | }, | 161 | }, |
161 | }; | 162 | }; |
162 | 163 | ||
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h index 44e82cff9319..70fe6fc6cdd5 100644 --- a/drivers/media/video/zc0301/zc0301_sensor.h +++ b/drivers/media/video/zc0301/zc0301_sensor.h | |||
@@ -23,7 +23,7 @@ | |||
23 | #define _ZC0301_SENSOR_H_ | 23 | #define _ZC0301_SENSOR_H_ |
24 | 24 | ||
25 | #include <linux/usb.h> | 25 | #include <linux/usb.h> |
26 | #include <linux/videodev.h> | 26 | #include <linux/videodev2.h> |
27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
28 | #include <linux/stddef.h> | 28 | #include <linux/stddef.h> |
29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index cf0ed6cbb0e3..17118a490f81 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c | |||
@@ -183,14 +183,7 @@ static const int zoran_num_formats = | |||
183 | (sizeof(zoran_formats) / sizeof(struct zoran_format)); | 183 | (sizeof(zoran_formats) / sizeof(struct zoran_format)); |
184 | 184 | ||
185 | // RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined | 185 | // RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined |
186 | #if !defined(CONFIG_BIGPHYS_AREA) | ||
187 | //#undef CONFIG_BIGPHYS_AREA | ||
188 | #define BUZ_USE_HIMEM | ||
189 | #endif | ||
190 | 186 | ||
191 | #if defined(CONFIG_BIGPHYS_AREA) | ||
192 | # include <linux/bigphysarea.h> | ||
193 | #endif | ||
194 | 187 | ||
195 | extern int *zr_debug; | 188 | extern int *zr_debug; |
196 | 189 | ||
@@ -250,7 +243,6 @@ static void jpg_fbuffer_free(struct file *file); | |||
250 | * Linux with the necessary memory left over). | 243 | * Linux with the necessary memory left over). |
251 | */ | 244 | */ |
252 | 245 | ||
253 | #if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA) | ||
254 | static unsigned long | 246 | static unsigned long |
255 | get_high_mem (unsigned long size) | 247 | get_high_mem (unsigned long size) |
256 | { | 248 | { |
@@ -314,7 +306,6 @@ get_high_mem (unsigned long size) | |||
314 | 306 | ||
315 | return hi_mem_ph; | 307 | return hi_mem_ph; |
316 | } | 308 | } |
317 | #endif | ||
318 | 309 | ||
319 | static int | 310 | static int |
320 | v4l_fbuffer_alloc (struct file *file) | 311 | v4l_fbuffer_alloc (struct file *file) |
@@ -323,9 +314,7 @@ v4l_fbuffer_alloc (struct file *file) | |||
323 | struct zoran *zr = fh->zr; | 314 | struct zoran *zr = fh->zr; |
324 | int i, off; | 315 | int i, off; |
325 | unsigned char *mem; | 316 | unsigned char *mem; |
326 | #if defined(BUZ_USE_HIMEM) && !defined(CONFIG_BIGPHYS_AREA) | ||
327 | unsigned long pmem = 0; | 317 | unsigned long pmem = 0; |
328 | #endif | ||
329 | 318 | ||
330 | /* we might have old buffers lying around... */ | 319 | /* we might have old buffers lying around... */ |
331 | if (fh->v4l_buffers.ready_to_be_freed) { | 320 | if (fh->v4l_buffers.ready_to_be_freed) { |
@@ -369,39 +358,6 @@ v4l_fbuffer_alloc (struct file *file) | |||
369 | ZR_DEVNAME(zr), i, (unsigned long) mem, | 358 | ZR_DEVNAME(zr), i, (unsigned long) mem, |
370 | virt_to_bus(mem)); | 359 | virt_to_bus(mem)); |
371 | } else { | 360 | } else { |
372 | #if defined(CONFIG_BIGPHYS_AREA) | ||
373 | /* Use bigphysarea_alloc_pages */ | ||
374 | |||
375 | int n = | ||
376 | (fh->v4l_buffers.buffer_size + PAGE_SIZE - | ||
377 | 1) / PAGE_SIZE; | ||
378 | |||
379 | mem = | ||
380 | (unsigned char *) bigphysarea_alloc_pages(n, 0, | ||
381 | GFP_KERNEL); | ||
382 | if (mem == 0) { | ||
383 | dprintk(1, | ||
384 | KERN_ERR | ||
385 | "%s: v4l_fbuffer_alloc() - bigphysarea_alloc_pages for V4L buf %d failed\n", | ||
386 | ZR_DEVNAME(zr), i); | ||
387 | v4l_fbuffer_free(file); | ||
388 | return -ENOBUFS; | ||
389 | } | ||
390 | fh->v4l_buffers.buffer[i].fbuffer = mem; | ||
391 | fh->v4l_buffers.buffer[i].fbuffer_phys = | ||
392 | virt_to_phys(mem); | ||
393 | fh->v4l_buffers.buffer[i].fbuffer_bus = | ||
394 | virt_to_bus(mem); | ||
395 | dprintk(4, | ||
396 | KERN_INFO | ||
397 | "%s: Bigphysarea frame %d mem 0x%x (bus: 0x%x)\n", | ||
398 | ZR_DEVNAME(zr), i, (unsigned) mem, | ||
399 | (unsigned) virt_to_bus(mem)); | ||
400 | |||
401 | /* Zero out the allocated memory */ | ||
402 | memset(fh->v4l_buffers.buffer[i].fbuffer, 0, | ||
403 | fh->v4l_buffers.buffer_size); | ||
404 | #elif defined(BUZ_USE_HIMEM) | ||
405 | 361 | ||
406 | /* Use high memory which has been left at boot time */ | 362 | /* Use high memory which has been left at boot time */ |
407 | 363 | ||
@@ -441,20 +397,6 @@ v4l_fbuffer_alloc (struct file *file) | |||
441 | fh->v4l_buffers.buffer[i].fbuffer_bus = | 397 | fh->v4l_buffers.buffer[i].fbuffer_bus = |
442 | pmem + i * fh->v4l_buffers.buffer_size; | 398 | pmem + i * fh->v4l_buffers.buffer_size; |
443 | } | 399 | } |
444 | #else | ||
445 | /* No bigphysarea present, usage of high memory disabled, | ||
446 | * but user wants buffers of more than MAX_KMALLOC_MEM */ | ||
447 | dprintk(1, | ||
448 | KERN_ERR | ||
449 | "%s: v4l_fbuffer_alloc() - no bigphysarea_patch present, usage of high memory disabled,\n", | ||
450 | ZR_DEVNAME(zr)); | ||
451 | dprintk(1, | ||
452 | KERN_ERR | ||
453 | "%s: v4l_fbuffer_alloc() - sorry, could not allocate %d V4L buffers of size %d KB.\n", | ||
454 | ZR_DEVNAME(zr), fh->v4l_buffers.num_buffers, | ||
455 | fh->v4l_buffers.buffer_size >> 10); | ||
456 | return -ENOBUFS; | ||
457 | #endif | ||
458 | } | 400 | } |
459 | } | 401 | } |
460 | 402 | ||
@@ -485,11 +427,6 @@ v4l_fbuffer_free (struct file *file) | |||
485 | ClearPageReserved(MAP_NR(mem + off)); | 427 | ClearPageReserved(MAP_NR(mem + off)); |
486 | kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); | 428 | kfree((void *) fh->v4l_buffers.buffer[i].fbuffer); |
487 | } | 429 | } |
488 | #if defined(CONFIG_BIGPHYS_AREA) | ||
489 | else | ||
490 | bigphysarea_free_pages((void *) fh->v4l_buffers. | ||
491 | buffer[i].fbuffer); | ||
492 | #endif | ||
493 | fh->v4l_buffers.buffer[i].fbuffer = NULL; | 430 | fh->v4l_buffers.buffer[i].fbuffer = NULL; |
494 | } | 431 | } |
495 | 432 | ||
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index b5d3364c94c7..6f1892585cbb 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c | |||
@@ -92,6 +92,7 @@ static struct usb_device_id device_table[] = { | |||
92 | {USB_DEVICE(0x0784, 0x0040), .driver_info = METHOD1 }, | 92 | {USB_DEVICE(0x0784, 0x0040), .driver_info = METHOD1 }, |
93 | {USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 }, | 93 | {USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 }, |
94 | {USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 }, | 94 | {USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 }, |
95 | {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 }, | ||
95 | {} /* Terminating entry */ | 96 | {} /* Terminating entry */ |
96 | }; | 97 | }; |
97 | 98 | ||
@@ -792,6 +793,7 @@ static int zr364xx_probe(struct usb_interface *intf, | |||
792 | { | 793 | { |
793 | struct usb_device *udev = interface_to_usbdev(intf); | 794 | struct usb_device *udev = interface_to_usbdev(intf); |
794 | struct zr364xx_camera *cam = NULL; | 795 | struct zr364xx_camera *cam = NULL; |
796 | int err; | ||
795 | 797 | ||
796 | DBG("probing..."); | 798 | DBG("probing..."); |
797 | 799 | ||
@@ -799,12 +801,11 @@ static int zr364xx_probe(struct usb_interface *intf, | |||
799 | info("model %04x:%04x detected", udev->descriptor.idVendor, | 801 | info("model %04x:%04x detected", udev->descriptor.idVendor, |
800 | udev->descriptor.idProduct); | 802 | udev->descriptor.idProduct); |
801 | 803 | ||
802 | if ((cam = | 804 | cam = kzalloc(sizeof(struct zr364xx_camera), GFP_KERNEL); |
803 | kmalloc(sizeof(struct zr364xx_camera), GFP_KERNEL)) == NULL) { | 805 | if (cam == NULL) { |
804 | info("cam: out of memory !"); | 806 | info("cam: out of memory !"); |
805 | return -ENODEV; | 807 | return -ENOMEM; |
806 | } | 808 | } |
807 | memset(cam, 0x00, sizeof(struct zr364xx_camera)); | ||
808 | /* save the init method used by this camera */ | 809 | /* save the init method used by this camera */ |
809 | cam->method = id->driver_info; | 810 | cam->method = id->driver_info; |
810 | 811 | ||
@@ -812,7 +813,7 @@ static int zr364xx_probe(struct usb_interface *intf, | |||
812 | if (cam->vdev == NULL) { | 813 | if (cam->vdev == NULL) { |
813 | info("cam->vdev: out of memory !"); | 814 | info("cam->vdev: out of memory !"); |
814 | kfree(cam); | 815 | kfree(cam); |
815 | return -ENODEV; | 816 | return -ENOMEM; |
816 | } | 817 | } |
817 | memcpy(cam->vdev, &zr364xx_template, sizeof(zr364xx_template)); | 818 | memcpy(cam->vdev, &zr364xx_template, sizeof(zr364xx_template)); |
818 | video_set_drvdata(cam->vdev, cam); | 819 | video_set_drvdata(cam->vdev, cam); |
@@ -858,12 +859,13 @@ static int zr364xx_probe(struct usb_interface *intf, | |||
858 | cam->brightness = 64; | 859 | cam->brightness = 64; |
859 | mutex_init(&cam->lock); | 860 | mutex_init(&cam->lock); |
860 | 861 | ||
861 | if (video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1) == -1) { | 862 | err = video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1); |
863 | if (err) { | ||
862 | info("video_register_device failed"); | 864 | info("video_register_device failed"); |
863 | video_device_release(cam->vdev); | 865 | video_device_release(cam->vdev); |
864 | kfree(cam->buffer); | 866 | kfree(cam->buffer); |
865 | kfree(cam); | 867 | kfree(cam); |
866 | return -ENODEV; | 868 | return err; |
867 | } | 869 | } |
868 | 870 | ||
869 | usb_set_intfdata(intf, cam); | 871 | usb_set_intfdata(intf, cam); |
@@ -905,7 +907,7 @@ static struct usb_driver zr364xx_driver = { | |||
905 | static int __init zr364xx_init(void) | 907 | static int __init zr364xx_init(void) |
906 | { | 908 | { |
907 | int retval; | 909 | int retval; |
908 | retval = usb_register(&zr364xx_driver) < 0; | 910 | retval = usb_register(&zr364xx_driver); |
909 | if (retval) | 911 | if (retval) |
910 | info("usb_register failed!"); | 912 | info("usb_register failed!"); |
911 | else | 913 | else |
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 555d594d1811..1cb22bfae750 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/moduleparam.h> | 33 | #include <linux/moduleparam.h> |
34 | #include <linux/stringify.h> | 34 | #include <linux/stringify.h> |
35 | #include <linux/stat.h> | 35 | #include <linux/stat.h> |
36 | #include <linux/log2.h> | ||
36 | #include "ubi.h" | 37 | #include "ubi.h" |
37 | 38 | ||
38 | /* Maximum length of the 'mtd=' parameter */ | 39 | /* Maximum length of the 'mtd=' parameter */ |
@@ -369,7 +370,7 @@ static int attach_by_scanning(struct ubi_device *ubi) | |||
369 | out_wl: | 370 | out_wl: |
370 | ubi_wl_close(ubi); | 371 | ubi_wl_close(ubi); |
371 | out_vtbl: | 372 | out_vtbl: |
372 | kfree(ubi->vtbl); | 373 | vfree(ubi->vtbl); |
373 | out_si: | 374 | out_si: |
374 | ubi_scan_destroy_si(si); | 375 | ubi_scan_destroy_si(si); |
375 | return err; | 376 | return err; |
@@ -422,8 +423,7 @@ static int io_init(struct ubi_device *ubi) | |||
422 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; | 423 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; |
423 | 424 | ||
424 | /* Make sure minimal I/O unit is power of 2 */ | 425 | /* Make sure minimal I/O unit is power of 2 */ |
425 | if (ubi->min_io_size == 0 || | 426 | if (!is_power_of_2(ubi->min_io_size)) { |
426 | (ubi->min_io_size & (ubi->min_io_size - 1))) { | ||
427 | ubi_err("bad min. I/O unit"); | 427 | ubi_err("bad min. I/O unit"); |
428 | return -EINVAL; | 428 | return -EINVAL; |
429 | } | 429 | } |
@@ -593,8 +593,6 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset, | |||
593 | if (err) | 593 | if (err) |
594 | goto out_detach; | 594 | goto out_detach; |
595 | 595 | ||
596 | ubi_devices_cnt += 1; | ||
597 | |||
598 | ubi_msg("attached mtd%d to ubi%d", ubi->mtd->index, ubi_devices_cnt); | 596 | ubi_msg("attached mtd%d to ubi%d", ubi->mtd->index, ubi_devices_cnt); |
599 | ubi_msg("MTD device name: \"%s\"", ubi->mtd->name); | 597 | ubi_msg("MTD device name: \"%s\"", ubi->mtd->name); |
600 | ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); | 598 | ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); |
@@ -624,12 +622,13 @@ static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset, | |||
624 | wake_up_process(ubi->bgt_thread); | 622 | wake_up_process(ubi->bgt_thread); |
625 | } | 623 | } |
626 | 624 | ||
625 | ubi_devices_cnt += 1; | ||
627 | return 0; | 626 | return 0; |
628 | 627 | ||
629 | out_detach: | 628 | out_detach: |
630 | ubi_eba_close(ubi); | 629 | ubi_eba_close(ubi); |
631 | ubi_wl_close(ubi); | 630 | ubi_wl_close(ubi); |
632 | kfree(ubi->vtbl); | 631 | vfree(ubi->vtbl); |
633 | out_free: | 632 | out_free: |
634 | kfree(ubi); | 633 | kfree(ubi); |
635 | out_mtd: | 634 | out_mtd: |
@@ -650,7 +649,7 @@ static void detach_mtd_dev(struct ubi_device *ubi) | |||
650 | uif_close(ubi); | 649 | uif_close(ubi); |
651 | ubi_eba_close(ubi); | 650 | ubi_eba_close(ubi); |
652 | ubi_wl_close(ubi); | 651 | ubi_wl_close(ubi); |
653 | kfree(ubi->vtbl); | 652 | vfree(ubi->vtbl); |
654 | put_mtd_device(ubi->mtd); | 653 | put_mtd_device(ubi->mtd); |
655 | kfree(ubi_devices[ubi_num]); | 654 | kfree(ubi_devices[ubi_num]); |
656 | ubi_devices[ubi_num] = NULL; | 655 | ubi_devices[ubi_num] = NULL; |
@@ -686,13 +685,6 @@ static int __init ubi_init(void) | |||
686 | struct mtd_dev_param *p = &mtd_dev_param[i]; | 685 | struct mtd_dev_param *p = &mtd_dev_param[i]; |
687 | 686 | ||
688 | cond_resched(); | 687 | cond_resched(); |
689 | |||
690 | if (!p->name) { | ||
691 | dbg_err("empty name"); | ||
692 | err = -EINVAL; | ||
693 | goto out_detach; | ||
694 | } | ||
695 | |||
696 | err = attach_mtd_dev(p->name, p->vid_hdr_offs, p->data_offs); | 688 | err = attach_mtd_dev(p->name, p->vid_hdr_offs, p->data_offs); |
697 | if (err) | 689 | if (err) |
698 | goto out_detach; | 690 | goto out_detach; |
@@ -799,7 +791,7 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) | |||
799 | 791 | ||
800 | /* Get rid of the final newline */ | 792 | /* Get rid of the final newline */ |
801 | if (buf[len - 1] == '\n') | 793 | if (buf[len - 1] == '\n') |
802 | buf[len - 1] = 0; | 794 | buf[len - 1] = '\0'; |
803 | 795 | ||
804 | for (i = 0; i < 3; i++) | 796 | for (i = 0; i < 3; i++) |
805 | tokens[i] = strsep(&pbuf, ","); | 797 | tokens[i] = strsep(&pbuf, ","); |
@@ -809,9 +801,6 @@ static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) | |||
809 | return -EINVAL; | 801 | return -EINVAL; |
810 | } | 802 | } |
811 | 803 | ||
812 | if (tokens[0] == '\0') | ||
813 | return -EINVAL; | ||
814 | |||
815 | p = &mtd_dev_param[mtd_devs]; | 804 | p = &mtd_dev_param[mtd_devs]; |
816 | strcpy(&p->name[0], tokens[0]); | 805 | strcpy(&p->name[0], tokens[0]); |
817 | 806 | ||
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 6612eb79bf17..fe4da1e96c52 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -64,6 +64,7 @@ static struct ubi_device *major_to_device(int major) | |||
64 | if (ubi_devices[i] && ubi_devices[i]->major == major) | 64 | if (ubi_devices[i] && ubi_devices[i]->major == major) |
65 | return ubi_devices[i]; | 65 | return ubi_devices[i]; |
66 | BUG(); | 66 | BUG(); |
67 | return NULL; | ||
67 | } | 68 | } |
68 | 69 | ||
69 | /** | 70 | /** |
@@ -153,7 +154,7 @@ static int vol_cdev_release(struct inode *inode, struct file *file) | |||
153 | ubi_warn("update of volume %d not finished, volume is damaged", | 154 | ubi_warn("update of volume %d not finished, volume is damaged", |
154 | vol->vol_id); | 155 | vol->vol_id); |
155 | vol->updating = 0; | 156 | vol->updating = 0; |
156 | kfree(vol->upd_buf); | 157 | vfree(vol->upd_buf); |
157 | } | 158 | } |
158 | 159 | ||
159 | ubi_close_volume(desc); | 160 | ubi_close_volume(desc); |
@@ -232,7 +233,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, | |||
232 | tbuf_size = vol->usable_leb_size; | 233 | tbuf_size = vol->usable_leb_size; |
233 | if (count < tbuf_size) | 234 | if (count < tbuf_size) |
234 | tbuf_size = ALIGN(count, ubi->min_io_size); | 235 | tbuf_size = ALIGN(count, ubi->min_io_size); |
235 | tbuf = kmalloc(tbuf_size, GFP_KERNEL); | 236 | tbuf = vmalloc(tbuf_size); |
236 | if (!tbuf) | 237 | if (!tbuf) |
237 | return -ENOMEM; | 238 | return -ENOMEM; |
238 | 239 | ||
@@ -271,7 +272,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, | |||
271 | len = count > tbuf_size ? tbuf_size : count; | 272 | len = count > tbuf_size ? tbuf_size : count; |
272 | } while (count); | 273 | } while (count); |
273 | 274 | ||
274 | kfree(tbuf); | 275 | vfree(tbuf); |
275 | return err ? err : count_save - count; | 276 | return err ? err : count_save - count; |
276 | } | 277 | } |
277 | 278 | ||
@@ -320,7 +321,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, | |||
320 | tbuf_size = vol->usable_leb_size; | 321 | tbuf_size = vol->usable_leb_size; |
321 | if (count < tbuf_size) | 322 | if (count < tbuf_size) |
322 | tbuf_size = ALIGN(count, ubi->min_io_size); | 323 | tbuf_size = ALIGN(count, ubi->min_io_size); |
323 | tbuf = kmalloc(tbuf_size, GFP_KERNEL); | 324 | tbuf = vmalloc(tbuf_size); |
324 | if (!tbuf) | 325 | if (!tbuf) |
325 | return -ENOMEM; | 326 | return -ENOMEM; |
326 | 327 | ||
@@ -355,7 +356,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, | |||
355 | len = count > tbuf_size ? tbuf_size : count; | 356 | len = count > tbuf_size ? tbuf_size : count; |
356 | } | 357 | } |
357 | 358 | ||
358 | kfree(tbuf); | 359 | vfree(tbuf); |
359 | return err ? err : count_save - count; | 360 | return err ? err : count_save - count; |
360 | } | 361 | } |
361 | 362 | ||
@@ -397,6 +398,7 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, | |||
397 | vol->corrupted = 1; | 398 | vol->corrupted = 1; |
398 | } | 399 | } |
399 | vol->checked = 1; | 400 | vol->checked = 1; |
401 | ubi_gluebi_updated(vol); | ||
400 | revoke_exclusive(desc, UBI_READWRITE); | 402 | revoke_exclusive(desc, UBI_READWRITE); |
401 | } | 403 | } |
402 | 404 | ||
@@ -413,19 +415,7 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, | |||
413 | struct ubi_device *ubi = vol->ubi; | 415 | struct ubi_device *ubi = vol->ubi; |
414 | void __user *argp = (void __user *)arg; | 416 | void __user *argp = (void __user *)arg; |
415 | 417 | ||
416 | if (_IOC_NR(cmd) > VOL_CDEV_IOC_MAX_SEQ || | ||
417 | _IOC_TYPE(cmd) != UBI_VOL_IOC_MAGIC) | ||
418 | return -ENOTTY; | ||
419 | |||
420 | if (_IOC_DIR(cmd) && _IOC_READ) | ||
421 | err = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd)); | ||
422 | else if (_IOC_DIR(cmd) && _IOC_WRITE) | ||
423 | err = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd)); | ||
424 | if (err) | ||
425 | return -EFAULT; | ||
426 | |||
427 | switch (cmd) { | 418 | switch (cmd) { |
428 | |||
429 | /* Volume update command */ | 419 | /* Volume update command */ |
430 | case UBI_IOCVOLUP: | 420 | case UBI_IOCVOLUP: |
431 | { | 421 | { |
@@ -471,7 +461,7 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, | |||
471 | { | 461 | { |
472 | int32_t lnum; | 462 | int32_t lnum; |
473 | 463 | ||
474 | err = __get_user(lnum, (__user int32_t *)argp); | 464 | err = get_user(lnum, (__user int32_t *)argp); |
475 | if (err) { | 465 | if (err) { |
476 | err = -EFAULT; | 466 | err = -EFAULT; |
477 | break; | 467 | break; |
@@ -587,17 +577,6 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
587 | struct ubi_volume_desc *desc; | 577 | struct ubi_volume_desc *desc; |
588 | void __user *argp = (void __user *)arg; | 578 | void __user *argp = (void __user *)arg; |
589 | 579 | ||
590 | if (_IOC_NR(cmd) > UBI_CDEV_IOC_MAX_SEQ || | ||
591 | _IOC_TYPE(cmd) != UBI_IOC_MAGIC) | ||
592 | return -ENOTTY; | ||
593 | |||
594 | if (_IOC_DIR(cmd) && _IOC_READ) | ||
595 | err = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd)); | ||
596 | else if (_IOC_DIR(cmd) && _IOC_WRITE) | ||
597 | err = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd)); | ||
598 | if (err) | ||
599 | return -EFAULT; | ||
600 | |||
601 | if (!capable(CAP_SYS_RESOURCE)) | 580 | if (!capable(CAP_SYS_RESOURCE)) |
602 | return -EPERM; | 581 | return -EPERM; |
603 | 582 | ||
@@ -612,7 +591,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
612 | struct ubi_mkvol_req req; | 591 | struct ubi_mkvol_req req; |
613 | 592 | ||
614 | dbg_msg("create volume"); | 593 | dbg_msg("create volume"); |
615 | err = __copy_from_user(&req, argp, | 594 | err = copy_from_user(&req, argp, |
616 | sizeof(struct ubi_mkvol_req)); | 595 | sizeof(struct ubi_mkvol_req)); |
617 | if (err) { | 596 | if (err) { |
618 | err = -EFAULT; | 597 | err = -EFAULT; |
@@ -629,7 +608,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
629 | if (err) | 608 | if (err) |
630 | break; | 609 | break; |
631 | 610 | ||
632 | err = __put_user(req.vol_id, (__user int32_t *)argp); | 611 | err = put_user(req.vol_id, (__user int32_t *)argp); |
633 | if (err) | 612 | if (err) |
634 | err = -EFAULT; | 613 | err = -EFAULT; |
635 | 614 | ||
@@ -642,7 +621,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
642 | int vol_id; | 621 | int vol_id; |
643 | 622 | ||
644 | dbg_msg("remove volume"); | 623 | dbg_msg("remove volume"); |
645 | err = __get_user(vol_id, (__user int32_t *)argp); | 624 | err = get_user(vol_id, (__user int32_t *)argp); |
646 | if (err) { | 625 | if (err) { |
647 | err = -EFAULT; | 626 | err = -EFAULT; |
648 | break; | 627 | break; |
@@ -669,7 +648,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
669 | struct ubi_rsvol_req req; | 648 | struct ubi_rsvol_req req; |
670 | 649 | ||
671 | dbg_msg("re-size volume"); | 650 | dbg_msg("re-size volume"); |
672 | err = __copy_from_user(&req, argp, | 651 | err = copy_from_user(&req, argp, |
673 | sizeof(struct ubi_rsvol_req)); | 652 | sizeof(struct ubi_rsvol_req)); |
674 | if (err) { | 653 | if (err) { |
675 | err = -EFAULT; | 654 | err = -EFAULT; |
@@ -707,7 +686,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
707 | struct file_operations ubi_cdev_operations = { | 686 | struct file_operations ubi_cdev_operations = { |
708 | .owner = THIS_MODULE, | 687 | .owner = THIS_MODULE, |
709 | .ioctl = ubi_cdev_ioctl, | 688 | .ioctl = ubi_cdev_ioctl, |
710 | .llseek = no_llseek | 689 | .llseek = no_llseek, |
711 | }; | 690 | }; |
712 | 691 | ||
713 | /* UBI volume character device operations */ | 692 | /* UBI volume character device operations */ |
@@ -718,5 +697,5 @@ struct file_operations ubi_vol_cdev_operations = { | |||
718 | .llseek = vol_cdev_llseek, | 697 | .llseek = vol_cdev_llseek, |
719 | .read = vol_cdev_read, | 698 | .read = vol_cdev_read, |
720 | .write = vol_cdev_write, | 699 | .write = vol_cdev_write, |
721 | .ioctl = vol_cdev_ioctl | 700 | .ioctl = vol_cdev_ioctl, |
722 | }; | 701 | }; |
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 86364221fafe..310341e5cd43 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c | |||
@@ -35,12 +35,12 @@ | |||
35 | void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) | 35 | void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) |
36 | { | 36 | { |
37 | dbg_msg("erase counter header dump:"); | 37 | dbg_msg("erase counter header dump:"); |
38 | dbg_msg("magic %#08x", ubi32_to_cpu(ec_hdr->magic)); | 38 | dbg_msg("magic %#08x", be32_to_cpu(ec_hdr->magic)); |
39 | dbg_msg("version %d", (int)ec_hdr->version); | 39 | dbg_msg("version %d", (int)ec_hdr->version); |
40 | dbg_msg("ec %llu", (long long)ubi64_to_cpu(ec_hdr->ec)); | 40 | dbg_msg("ec %llu", (long long)be64_to_cpu(ec_hdr->ec)); |
41 | dbg_msg("vid_hdr_offset %d", ubi32_to_cpu(ec_hdr->vid_hdr_offset)); | 41 | dbg_msg("vid_hdr_offset %d", be32_to_cpu(ec_hdr->vid_hdr_offset)); |
42 | dbg_msg("data_offset %d", ubi32_to_cpu(ec_hdr->data_offset)); | 42 | dbg_msg("data_offset %d", be32_to_cpu(ec_hdr->data_offset)); |
43 | dbg_msg("hdr_crc %#08x", ubi32_to_cpu(ec_hdr->hdr_crc)); | 43 | dbg_msg("hdr_crc %#08x", be32_to_cpu(ec_hdr->hdr_crc)); |
44 | dbg_msg("erase counter header hexdump:"); | 44 | dbg_msg("erase counter header hexdump:"); |
45 | ubi_dbg_hexdump(ec_hdr, UBI_EC_HDR_SIZE); | 45 | ubi_dbg_hexdump(ec_hdr, UBI_EC_HDR_SIZE); |
46 | } | 46 | } |
@@ -52,20 +52,20 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) | |||
52 | void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) | 52 | void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr) |
53 | { | 53 | { |
54 | dbg_msg("volume identifier header dump:"); | 54 | dbg_msg("volume identifier header dump:"); |
55 | dbg_msg("magic %08x", ubi32_to_cpu(vid_hdr->magic)); | 55 | dbg_msg("magic %08x", be32_to_cpu(vid_hdr->magic)); |
56 | dbg_msg("version %d", (int)vid_hdr->version); | 56 | dbg_msg("version %d", (int)vid_hdr->version); |
57 | dbg_msg("vol_type %d", (int)vid_hdr->vol_type); | 57 | dbg_msg("vol_type %d", (int)vid_hdr->vol_type); |
58 | dbg_msg("copy_flag %d", (int)vid_hdr->copy_flag); | 58 | dbg_msg("copy_flag %d", (int)vid_hdr->copy_flag); |
59 | dbg_msg("compat %d", (int)vid_hdr->compat); | 59 | dbg_msg("compat %d", (int)vid_hdr->compat); |
60 | dbg_msg("vol_id %d", ubi32_to_cpu(vid_hdr->vol_id)); | 60 | dbg_msg("vol_id %d", be32_to_cpu(vid_hdr->vol_id)); |
61 | dbg_msg("lnum %d", ubi32_to_cpu(vid_hdr->lnum)); | 61 | dbg_msg("lnum %d", be32_to_cpu(vid_hdr->lnum)); |
62 | dbg_msg("leb_ver %u", ubi32_to_cpu(vid_hdr->leb_ver)); | 62 | dbg_msg("leb_ver %u", be32_to_cpu(vid_hdr->leb_ver)); |
63 | dbg_msg("data_size %d", ubi32_to_cpu(vid_hdr->data_size)); | 63 | dbg_msg("data_size %d", be32_to_cpu(vid_hdr->data_size)); |
64 | dbg_msg("used_ebs %d", ubi32_to_cpu(vid_hdr->used_ebs)); | 64 | dbg_msg("used_ebs %d", be32_to_cpu(vid_hdr->used_ebs)); |
65 | dbg_msg("data_pad %d", ubi32_to_cpu(vid_hdr->data_pad)); | 65 | dbg_msg("data_pad %d", be32_to_cpu(vid_hdr->data_pad)); |
66 | dbg_msg("sqnum %llu", | 66 | dbg_msg("sqnum %llu", |
67 | (unsigned long long)ubi64_to_cpu(vid_hdr->sqnum)); | 67 | (unsigned long long)be64_to_cpu(vid_hdr->sqnum)); |
68 | dbg_msg("hdr_crc %08x", ubi32_to_cpu(vid_hdr->hdr_crc)); | 68 | dbg_msg("hdr_crc %08x", be32_to_cpu(vid_hdr->hdr_crc)); |
69 | dbg_msg("volume identifier header hexdump:"); | 69 | dbg_msg("volume identifier header hexdump:"); |
70 | } | 70 | } |
71 | 71 | ||
@@ -91,7 +91,7 @@ void ubi_dbg_dump_vol_info(const struct ubi_volume *vol) | |||
91 | 91 | ||
92 | if (vol->name_len <= UBI_VOL_NAME_MAX && | 92 | if (vol->name_len <= UBI_VOL_NAME_MAX && |
93 | strnlen(vol->name, vol->name_len + 1) == vol->name_len) { | 93 | strnlen(vol->name, vol->name_len + 1) == vol->name_len) { |
94 | dbg_msg("name %s", vol->name); | 94 | dbg_msg("name %s", vol->name); |
95 | } else { | 95 | } else { |
96 | dbg_msg("the 1st 5 characters of the name: %c%c%c%c%c", | 96 | dbg_msg("the 1st 5 characters of the name: %c%c%c%c%c", |
97 | vol->name[0], vol->name[1], vol->name[2], | 97 | vol->name[0], vol->name[1], vol->name[2], |
@@ -106,30 +106,30 @@ void ubi_dbg_dump_vol_info(const struct ubi_volume *vol) | |||
106 | */ | 106 | */ |
107 | void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) | 107 | void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx) |
108 | { | 108 | { |
109 | int name_len = ubi16_to_cpu(r->name_len); | 109 | int name_len = be16_to_cpu(r->name_len); |
110 | 110 | ||
111 | dbg_msg("volume table record %d dump:", idx); | 111 | dbg_msg("volume table record %d dump:", idx); |
112 | dbg_msg("reserved_pebs %d", ubi32_to_cpu(r->reserved_pebs)); | 112 | dbg_msg("reserved_pebs %d", be32_to_cpu(r->reserved_pebs)); |
113 | dbg_msg("alignment %d", ubi32_to_cpu(r->alignment)); | 113 | dbg_msg("alignment %d", be32_to_cpu(r->alignment)); |
114 | dbg_msg("data_pad %d", ubi32_to_cpu(r->data_pad)); | 114 | dbg_msg("data_pad %d", be32_to_cpu(r->data_pad)); |
115 | dbg_msg("vol_type %d", (int)r->vol_type); | 115 | dbg_msg("vol_type %d", (int)r->vol_type); |
116 | dbg_msg("upd_marker %d", (int)r->upd_marker); | 116 | dbg_msg("upd_marker %d", (int)r->upd_marker); |
117 | dbg_msg("name_len %d", name_len); | 117 | dbg_msg("name_len %d", name_len); |
118 | 118 | ||
119 | if (r->name[0] == '\0') { | 119 | if (r->name[0] == '\0') { |
120 | dbg_msg("name NULL"); | 120 | dbg_msg("name NULL"); |
121 | return; | 121 | return; |
122 | } | 122 | } |
123 | 123 | ||
124 | if (name_len <= UBI_VOL_NAME_MAX && | 124 | if (name_len <= UBI_VOL_NAME_MAX && |
125 | strnlen(&r->name[0], name_len + 1) == name_len) { | 125 | strnlen(&r->name[0], name_len + 1) == name_len) { |
126 | dbg_msg("name %s", &r->name[0]); | 126 | dbg_msg("name %s", &r->name[0]); |
127 | } else { | 127 | } else { |
128 | dbg_msg("1st 5 characters of the name: %c%c%c%c%c", | 128 | dbg_msg("1st 5 characters of the name: %c%c%c%c%c", |
129 | r->name[0], r->name[1], r->name[2], r->name[3], | 129 | r->name[0], r->name[1], r->name[2], r->name[3], |
130 | r->name[4]); | 130 | r->name[4]); |
131 | } | 131 | } |
132 | dbg_msg("crc %#08x", ubi32_to_cpu(r->crc)); | 132 | dbg_msg("crc %#08x", be32_to_cpu(r->crc)); |
133 | } | 133 | } |
134 | 134 | ||
135 | /** | 135 | /** |
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index f816ad9a36c0..ff8f39548cd8 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h | |||
@@ -52,7 +52,6 @@ struct ubi_scan_volume; | |||
52 | struct ubi_scan_leb; | 52 | struct ubi_scan_leb; |
53 | struct ubi_mkvol_req; | 53 | struct ubi_mkvol_req; |
54 | 54 | ||
55 | void ubi_dbg_print(int type, const char *func, const char *fmt, ...); | ||
56 | void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr); | 55 | void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr); |
57 | void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); | 56 | void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr); |
58 | void ubi_dbg_dump_vol_info(const struct ubi_volume *vol); | 57 | void ubi_dbg_dump_vol_info(const struct ubi_volume *vol); |
@@ -66,7 +65,6 @@ void ubi_dbg_hexdump(const void *buf, int size); | |||
66 | 65 | ||
67 | #define dbg_msg(fmt, ...) ({}) | 66 | #define dbg_msg(fmt, ...) ({}) |
68 | #define ubi_dbg_dump_stack() ({}) | 67 | #define ubi_dbg_dump_stack() ({}) |
69 | #define ubi_dbg_print(func, fmt, ...) ({}) | ||
70 | #define ubi_dbg_dump_ec_hdr(ec_hdr) ({}) | 68 | #define ubi_dbg_dump_ec_hdr(ec_hdr) ({}) |
71 | #define ubi_dbg_dump_vid_hdr(vid_hdr) ({}) | 69 | #define ubi_dbg_dump_vid_hdr(vid_hdr) ({}) |
72 | #define ubi_dbg_dump_vol_info(vol) ({}) | 70 | #define ubi_dbg_dump_vol_info(vol) ({}) |
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index 7c6b223b3f8a..8aff9385613f 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c | |||
@@ -425,10 +425,10 @@ retry: | |||
425 | } else if (err == UBI_IO_BITFLIPS) | 425 | } else if (err == UBI_IO_BITFLIPS) |
426 | scrub = 1; | 426 | scrub = 1; |
427 | 427 | ||
428 | ubi_assert(lnum < ubi32_to_cpu(vid_hdr->used_ebs)); | 428 | ubi_assert(lnum < be32_to_cpu(vid_hdr->used_ebs)); |
429 | ubi_assert(len == ubi32_to_cpu(vid_hdr->data_size)); | 429 | ubi_assert(len == be32_to_cpu(vid_hdr->data_size)); |
430 | 430 | ||
431 | crc = ubi32_to_cpu(vid_hdr->data_crc); | 431 | crc = be32_to_cpu(vid_hdr->data_crc); |
432 | ubi_free_vid_hdr(ubi, vid_hdr); | 432 | ubi_free_vid_hdr(ubi, vid_hdr); |
433 | } | 433 | } |
434 | 434 | ||
@@ -518,13 +518,13 @@ retry: | |||
518 | goto out_put; | 518 | goto out_put; |
519 | } | 519 | } |
520 | 520 | ||
521 | vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi)); | 521 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); |
522 | err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); | 522 | err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr); |
523 | if (err) | 523 | if (err) |
524 | goto write_error; | 524 | goto write_error; |
525 | 525 | ||
526 | data_size = offset + len; | 526 | data_size = offset + len; |
527 | new_buf = kmalloc(data_size, GFP_KERNEL); | 527 | new_buf = vmalloc(data_size); |
528 | if (!new_buf) { | 528 | if (!new_buf) { |
529 | err = -ENOMEM; | 529 | err = -ENOMEM; |
530 | goto out_put; | 530 | goto out_put; |
@@ -535,7 +535,7 @@ retry: | |||
535 | if (offset > 0) { | 535 | if (offset > 0) { |
536 | err = ubi_io_read_data(ubi, new_buf, pnum, 0, offset); | 536 | err = ubi_io_read_data(ubi, new_buf, pnum, 0, offset); |
537 | if (err && err != UBI_IO_BITFLIPS) { | 537 | if (err && err != UBI_IO_BITFLIPS) { |
538 | kfree(new_buf); | 538 | vfree(new_buf); |
539 | goto out_put; | 539 | goto out_put; |
540 | } | 540 | } |
541 | } | 541 | } |
@@ -544,11 +544,11 @@ retry: | |||
544 | 544 | ||
545 | err = ubi_io_write_data(ubi, new_buf, new_pnum, 0, data_size); | 545 | err = ubi_io_write_data(ubi, new_buf, new_pnum, 0, data_size); |
546 | if (err) { | 546 | if (err) { |
547 | kfree(new_buf); | 547 | vfree(new_buf); |
548 | goto write_error; | 548 | goto write_error; |
549 | } | 549 | } |
550 | 550 | ||
551 | kfree(new_buf); | 551 | vfree(new_buf); |
552 | ubi_free_vid_hdr(ubi, vid_hdr); | 552 | ubi_free_vid_hdr(ubi, vid_hdr); |
553 | 553 | ||
554 | vol->eba_tbl[lnum] = new_pnum; | 554 | vol->eba_tbl[lnum] = new_pnum; |
@@ -634,11 +634,11 @@ int ubi_eba_write_leb(struct ubi_device *ubi, int vol_id, int lnum, | |||
634 | } | 634 | } |
635 | 635 | ||
636 | vid_hdr->vol_type = UBI_VID_DYNAMIC; | 636 | vid_hdr->vol_type = UBI_VID_DYNAMIC; |
637 | vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi)); | 637 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); |
638 | vid_hdr->vol_id = cpu_to_ubi32(vol_id); | 638 | vid_hdr->vol_id = cpu_to_be32(vol_id); |
639 | vid_hdr->lnum = cpu_to_ubi32(lnum); | 639 | vid_hdr->lnum = cpu_to_be32(lnum); |
640 | vid_hdr->compat = ubi_get_compat(ubi, vol_id); | 640 | vid_hdr->compat = ubi_get_compat(ubi, vol_id); |
641 | vid_hdr->data_pad = cpu_to_ubi32(vol->data_pad); | 641 | vid_hdr->data_pad = cpu_to_be32(vol->data_pad); |
642 | 642 | ||
643 | retry: | 643 | retry: |
644 | pnum = ubi_wl_get_peb(ubi, dtype); | 644 | pnum = ubi_wl_get_peb(ubi, dtype); |
@@ -692,7 +692,7 @@ write_error: | |||
692 | return err; | 692 | return err; |
693 | } | 693 | } |
694 | 694 | ||
695 | vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi)); | 695 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); |
696 | ubi_msg("try another PEB"); | 696 | ubi_msg("try another PEB"); |
697 | goto retry; | 697 | goto retry; |
698 | } | 698 | } |
@@ -748,17 +748,17 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, int vol_id, int lnum, | |||
748 | return err; | 748 | return err; |
749 | } | 749 | } |
750 | 750 | ||
751 | vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi)); | 751 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); |
752 | vid_hdr->vol_id = cpu_to_ubi32(vol_id); | 752 | vid_hdr->vol_id = cpu_to_be32(vol_id); |
753 | vid_hdr->lnum = cpu_to_ubi32(lnum); | 753 | vid_hdr->lnum = cpu_to_be32(lnum); |
754 | vid_hdr->compat = ubi_get_compat(ubi, vol_id); | 754 | vid_hdr->compat = ubi_get_compat(ubi, vol_id); |
755 | vid_hdr->data_pad = cpu_to_ubi32(vol->data_pad); | 755 | vid_hdr->data_pad = cpu_to_be32(vol->data_pad); |
756 | 756 | ||
757 | crc = crc32(UBI_CRC32_INIT, buf, data_size); | 757 | crc = crc32(UBI_CRC32_INIT, buf, data_size); |
758 | vid_hdr->vol_type = UBI_VID_STATIC; | 758 | vid_hdr->vol_type = UBI_VID_STATIC; |
759 | vid_hdr->data_size = cpu_to_ubi32(data_size); | 759 | vid_hdr->data_size = cpu_to_be32(data_size); |
760 | vid_hdr->used_ebs = cpu_to_ubi32(used_ebs); | 760 | vid_hdr->used_ebs = cpu_to_be32(used_ebs); |
761 | vid_hdr->data_crc = cpu_to_ubi32(crc); | 761 | vid_hdr->data_crc = cpu_to_be32(crc); |
762 | 762 | ||
763 | retry: | 763 | retry: |
764 | pnum = ubi_wl_get_peb(ubi, dtype); | 764 | pnum = ubi_wl_get_peb(ubi, dtype); |
@@ -813,7 +813,7 @@ write_error: | |||
813 | return err; | 813 | return err; |
814 | } | 814 | } |
815 | 815 | ||
816 | vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi)); | 816 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); |
817 | ubi_msg("try another PEB"); | 817 | ubi_msg("try another PEB"); |
818 | goto retry; | 818 | goto retry; |
819 | } | 819 | } |
@@ -854,17 +854,17 @@ int ubi_eba_atomic_leb_change(struct ubi_device *ubi, int vol_id, int lnum, | |||
854 | return err; | 854 | return err; |
855 | } | 855 | } |
856 | 856 | ||
857 | vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi)); | 857 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); |
858 | vid_hdr->vol_id = cpu_to_ubi32(vol_id); | 858 | vid_hdr->vol_id = cpu_to_be32(vol_id); |
859 | vid_hdr->lnum = cpu_to_ubi32(lnum); | 859 | vid_hdr->lnum = cpu_to_be32(lnum); |
860 | vid_hdr->compat = ubi_get_compat(ubi, vol_id); | 860 | vid_hdr->compat = ubi_get_compat(ubi, vol_id); |
861 | vid_hdr->data_pad = cpu_to_ubi32(vol->data_pad); | 861 | vid_hdr->data_pad = cpu_to_be32(vol->data_pad); |
862 | 862 | ||
863 | crc = crc32(UBI_CRC32_INIT, buf, len); | 863 | crc = crc32(UBI_CRC32_INIT, buf, len); |
864 | vid_hdr->vol_type = UBI_VID_STATIC; | 864 | vid_hdr->vol_type = UBI_VID_DYNAMIC; |
865 | vid_hdr->data_size = cpu_to_ubi32(len); | 865 | vid_hdr->data_size = cpu_to_be32(len); |
866 | vid_hdr->copy_flag = 1; | 866 | vid_hdr->copy_flag = 1; |
867 | vid_hdr->data_crc = cpu_to_ubi32(crc); | 867 | vid_hdr->data_crc = cpu_to_be32(crc); |
868 | 868 | ||
869 | retry: | 869 | retry: |
870 | pnum = ubi_wl_get_peb(ubi, dtype); | 870 | pnum = ubi_wl_get_peb(ubi, dtype); |
@@ -891,11 +891,13 @@ retry: | |||
891 | goto write_error; | 891 | goto write_error; |
892 | } | 892 | } |
893 | 893 | ||
894 | err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 1); | 894 | if (vol->eba_tbl[lnum] >= 0) { |
895 | if (err) { | 895 | err = ubi_wl_put_peb(ubi, vol->eba_tbl[lnum], 1); |
896 | ubi_free_vid_hdr(ubi, vid_hdr); | 896 | if (err) { |
897 | leb_write_unlock(ubi, vol_id, lnum); | 897 | ubi_free_vid_hdr(ubi, vid_hdr); |
898 | return err; | 898 | leb_write_unlock(ubi, vol_id, lnum); |
899 | return err; | ||
900 | } | ||
899 | } | 901 | } |
900 | 902 | ||
901 | vol->eba_tbl[lnum] = pnum; | 903 | vol->eba_tbl[lnum] = pnum; |
@@ -924,7 +926,7 @@ write_error: | |||
924 | return err; | 926 | return err; |
925 | } | 927 | } |
926 | 928 | ||
927 | vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi)); | 929 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); |
928 | ubi_msg("try another PEB"); | 930 | ubi_msg("try another PEB"); |
929 | goto retry; | 931 | goto retry; |
930 | } | 932 | } |
@@ -965,19 +967,19 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
965 | uint32_t crc; | 967 | uint32_t crc; |
966 | void *buf, *buf1 = NULL; | 968 | void *buf, *buf1 = NULL; |
967 | 969 | ||
968 | vol_id = ubi32_to_cpu(vid_hdr->vol_id); | 970 | vol_id = be32_to_cpu(vid_hdr->vol_id); |
969 | lnum = ubi32_to_cpu(vid_hdr->lnum); | 971 | lnum = be32_to_cpu(vid_hdr->lnum); |
970 | 972 | ||
971 | dbg_eba("copy LEB %d:%d, PEB %d to PEB %d", vol_id, lnum, from, to); | 973 | dbg_eba("copy LEB %d:%d, PEB %d to PEB %d", vol_id, lnum, from, to); |
972 | 974 | ||
973 | if (vid_hdr->vol_type == UBI_VID_STATIC) { | 975 | if (vid_hdr->vol_type == UBI_VID_STATIC) { |
974 | data_size = ubi32_to_cpu(vid_hdr->data_size); | 976 | data_size = be32_to_cpu(vid_hdr->data_size); |
975 | aldata_size = ALIGN(data_size, ubi->min_io_size); | 977 | aldata_size = ALIGN(data_size, ubi->min_io_size); |
976 | } else | 978 | } else |
977 | data_size = aldata_size = | 979 | data_size = aldata_size = |
978 | ubi->leb_size - ubi32_to_cpu(vid_hdr->data_pad); | 980 | ubi->leb_size - be32_to_cpu(vid_hdr->data_pad); |
979 | 981 | ||
980 | buf = kmalloc(aldata_size, GFP_KERNEL); | 982 | buf = vmalloc(aldata_size); |
981 | if (!buf) | 983 | if (!buf) |
982 | return -ENOMEM; | 984 | return -ENOMEM; |
983 | 985 | ||
@@ -987,7 +989,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
987 | */ | 989 | */ |
988 | err = leb_write_lock(ubi, vol_id, lnum); | 990 | err = leb_write_lock(ubi, vol_id, lnum); |
989 | if (err) { | 991 | if (err) { |
990 | kfree(buf); | 992 | vfree(buf); |
991 | return err; | 993 | return err; |
992 | } | 994 | } |
993 | 995 | ||
@@ -1054,10 +1056,10 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1054 | */ | 1056 | */ |
1055 | if (data_size > 0) { | 1057 | if (data_size > 0) { |
1056 | vid_hdr->copy_flag = 1; | 1058 | vid_hdr->copy_flag = 1; |
1057 | vid_hdr->data_size = cpu_to_ubi32(data_size); | 1059 | vid_hdr->data_size = cpu_to_be32(data_size); |
1058 | vid_hdr->data_crc = cpu_to_ubi32(crc); | 1060 | vid_hdr->data_crc = cpu_to_be32(crc); |
1059 | } | 1061 | } |
1060 | vid_hdr->sqnum = cpu_to_ubi64(next_sqnum(ubi)); | 1062 | vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi)); |
1061 | 1063 | ||
1062 | err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); | 1064 | err = ubi_io_write_vid_hdr(ubi, to, vid_hdr); |
1063 | if (err) | 1065 | if (err) |
@@ -1082,7 +1084,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1082 | * We've written the data and are going to read it back to make | 1084 | * We've written the data and are going to read it back to make |
1083 | * sure it was written correctly. | 1085 | * sure it was written correctly. |
1084 | */ | 1086 | */ |
1085 | buf1 = kmalloc(aldata_size, GFP_KERNEL); | 1087 | buf1 = vmalloc(aldata_size); |
1086 | if (!buf1) { | 1088 | if (!buf1) { |
1087 | err = -ENOMEM; | 1089 | err = -ENOMEM; |
1088 | goto out_unlock; | 1090 | goto out_unlock; |
@@ -1111,15 +1113,15 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to, | |||
1111 | vol->eba_tbl[lnum] = to; | 1113 | vol->eba_tbl[lnum] = to; |
1112 | 1114 | ||
1113 | leb_write_unlock(ubi, vol_id, lnum); | 1115 | leb_write_unlock(ubi, vol_id, lnum); |
1114 | kfree(buf); | 1116 | vfree(buf); |
1115 | kfree(buf1); | 1117 | vfree(buf1); |
1116 | 1118 | ||
1117 | return 0; | 1119 | return 0; |
1118 | 1120 | ||
1119 | out_unlock: | 1121 | out_unlock: |
1120 | leb_write_unlock(ubi, vol_id, lnum); | 1122 | leb_write_unlock(ubi, vol_id, lnum); |
1121 | kfree(buf); | 1123 | vfree(buf); |
1122 | kfree(buf1); | 1124 | vfree(buf1); |
1123 | return err; | 1125 | return err; |
1124 | } | 1126 | } |
1125 | 1127 | ||
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index fc9478d605ff..41ff74c60e14 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c | |||
@@ -282,7 +282,6 @@ int ubi_create_gluebi(struct ubi_device *ubi, struct ubi_volume *vol) | |||
282 | mtd->flags = MTD_WRITEABLE; | 282 | mtd->flags = MTD_WRITEABLE; |
283 | mtd->writesize = ubi->min_io_size; | 283 | mtd->writesize = ubi->min_io_size; |
284 | mtd->owner = THIS_MODULE; | 284 | mtd->owner = THIS_MODULE; |
285 | mtd->size = vol->usable_leb_size * vol->reserved_pebs; | ||
286 | mtd->erasesize = vol->usable_leb_size; | 285 | mtd->erasesize = vol->usable_leb_size; |
287 | mtd->read = gluebi_read; | 286 | mtd->read = gluebi_read; |
288 | mtd->write = gluebi_write; | 287 | mtd->write = gluebi_write; |
@@ -290,6 +289,15 @@ int ubi_create_gluebi(struct ubi_device *ubi, struct ubi_volume *vol) | |||
290 | mtd->get_device = gluebi_get_device; | 289 | mtd->get_device = gluebi_get_device; |
291 | mtd->put_device = gluebi_put_device; | 290 | mtd->put_device = gluebi_put_device; |
292 | 291 | ||
292 | /* | ||
293 | * In case of dynamic volume, MTD device size is just volume size. In | ||
294 | * case of a static volume the size is equivalent to the amount of data | ||
295 | * bytes, which is zero at this moment and will be changed after volume | ||
296 | * update. | ||
297 | */ | ||
298 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) | ||
299 | mtd->size = vol->usable_leb_size * vol->reserved_pebs; | ||
300 | |||
293 | if (add_mtd_device(mtd)) { | 301 | if (add_mtd_device(mtd)) { |
294 | ubi_err("cannot not add MTD device\n"); | 302 | ubi_err("cannot not add MTD device\n"); |
295 | kfree(mtd->name); | 303 | kfree(mtd->name); |
@@ -321,3 +329,20 @@ int ubi_destroy_gluebi(struct ubi_volume *vol) | |||
321 | kfree(mtd->name); | 329 | kfree(mtd->name); |
322 | return 0; | 330 | return 0; |
323 | } | 331 | } |
332 | |||
333 | /** | ||
334 | * ubi_gluebi_updated - UBI volume was updated notifier. | ||
335 | * @vol: volume description object | ||
336 | * | ||
337 | * This function is called every time an UBI volume is updated. This function | ||
338 | * does nothing if volume @vol is dynamic, and changes MTD device size if the | ||
339 | * volume is static. This is needed because static volumes cannot be read past | ||
340 | * data they contain. | ||
341 | */ | ||
342 | void ubi_gluebi_updated(struct ubi_volume *vol) | ||
343 | { | ||
344 | struct mtd_info *mtd = &vol->gluebi_mtd; | ||
345 | |||
346 | if (vol->vol_type == UBI_STATIC_VOLUME) | ||
347 | mtd->size = vol->used_bytes; | ||
348 | } | ||
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 438914d05151..b0d8f4cede97 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
@@ -125,9 +125,9 @@ static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum, | |||
125 | * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but | 125 | * o %UBI_IO_BITFLIPS if all the requested data were successfully read, but |
126 | * correctable bit-flips were detected; this is harmless but may indicate | 126 | * correctable bit-flips were detected; this is harmless but may indicate |
127 | * that this eraseblock may become bad soon (but do not have to); | 127 | * that this eraseblock may become bad soon (but do not have to); |
128 | * o %-EBADMSG if the MTD subsystem reported about data data integrity | 128 | * o %-EBADMSG if the MTD subsystem reported about data integrity problems, for |
129 | * problems, for example it can me an ECC error in case of NAND; this most | 129 | * example it can be an ECC error in case of NAND; this most probably means |
130 | * probably means that the data is corrupted; | 130 | * that the data is corrupted; |
131 | * o %-EIO if some I/O error occurred; | 131 | * o %-EIO if some I/O error occurred; |
132 | * o other negative error codes in case of other errors. | 132 | * o other negative error codes in case of other errors. |
133 | */ | 133 | */ |
@@ -298,7 +298,7 @@ retry: | |||
298 | memset(&ei, 0, sizeof(struct erase_info)); | 298 | memset(&ei, 0, sizeof(struct erase_info)); |
299 | 299 | ||
300 | ei.mtd = ubi->mtd; | 300 | ei.mtd = ubi->mtd; |
301 | ei.addr = pnum * ubi->peb_size; | 301 | ei.addr = (loff_t)pnum * ubi->peb_size; |
302 | ei.len = ubi->peb_size; | 302 | ei.len = ubi->peb_size; |
303 | ei.callback = erase_callback; | 303 | ei.callback = erase_callback; |
304 | ei.priv = (unsigned long)&wq; | 304 | ei.priv = (unsigned long)&wq; |
@@ -382,7 +382,7 @@ static int torture_peb(const struct ubi_device *ubi, int pnum) | |||
382 | void *buf; | 382 | void *buf; |
383 | int err, i, patt_count; | 383 | int err, i, patt_count; |
384 | 384 | ||
385 | buf = kmalloc(ubi->peb_size, GFP_KERNEL); | 385 | buf = vmalloc(ubi->peb_size); |
386 | if (!buf) | 386 | if (!buf) |
387 | return -ENOMEM; | 387 | return -ENOMEM; |
388 | 388 | ||
@@ -437,7 +437,7 @@ out: | |||
437 | * physical eraseblock which means something is wrong with it. | 437 | * physical eraseblock which means something is wrong with it. |
438 | */ | 438 | */ |
439 | err = -EIO; | 439 | err = -EIO; |
440 | kfree(buf); | 440 | vfree(buf); |
441 | return err; | 441 | return err; |
442 | } | 442 | } |
443 | 443 | ||
@@ -557,9 +557,9 @@ static int validate_ec_hdr(const struct ubi_device *ubi, | |||
557 | long long ec; | 557 | long long ec; |
558 | int vid_hdr_offset, leb_start; | 558 | int vid_hdr_offset, leb_start; |
559 | 559 | ||
560 | ec = ubi64_to_cpu(ec_hdr->ec); | 560 | ec = be64_to_cpu(ec_hdr->ec); |
561 | vid_hdr_offset = ubi32_to_cpu(ec_hdr->vid_hdr_offset); | 561 | vid_hdr_offset = be32_to_cpu(ec_hdr->vid_hdr_offset); |
562 | leb_start = ubi32_to_cpu(ec_hdr->data_offset); | 562 | leb_start = be32_to_cpu(ec_hdr->data_offset); |
563 | 563 | ||
564 | if (ec_hdr->version != UBI_VERSION) { | 564 | if (ec_hdr->version != UBI_VERSION) { |
565 | ubi_err("node with incompatible UBI version found: " | 565 | ubi_err("node with incompatible UBI version found: " |
@@ -640,7 +640,7 @@ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
640 | read_err = err; | 640 | read_err = err; |
641 | } | 641 | } |
642 | 642 | ||
643 | magic = ubi32_to_cpu(ec_hdr->magic); | 643 | magic = be32_to_cpu(ec_hdr->magic); |
644 | if (magic != UBI_EC_HDR_MAGIC) { | 644 | if (magic != UBI_EC_HDR_MAGIC) { |
645 | /* | 645 | /* |
646 | * The magic field is wrong. Let's check if we have read all | 646 | * The magic field is wrong. Let's check if we have read all |
@@ -684,7 +684,7 @@ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
684 | } | 684 | } |
685 | 685 | ||
686 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); | 686 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); |
687 | hdr_crc = ubi32_to_cpu(ec_hdr->hdr_crc); | 687 | hdr_crc = be32_to_cpu(ec_hdr->hdr_crc); |
688 | 688 | ||
689 | if (hdr_crc != crc) { | 689 | if (hdr_crc != crc) { |
690 | if (verbose) { | 690 | if (verbose) { |
@@ -729,12 +729,12 @@ int ubi_io_write_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
729 | dbg_io("write EC header to PEB %d", pnum); | 729 | dbg_io("write EC header to PEB %d", pnum); |
730 | ubi_assert(pnum >= 0 && pnum < ubi->peb_count); | 730 | ubi_assert(pnum >= 0 && pnum < ubi->peb_count); |
731 | 731 | ||
732 | ec_hdr->magic = cpu_to_ubi32(UBI_EC_HDR_MAGIC); | 732 | ec_hdr->magic = cpu_to_be32(UBI_EC_HDR_MAGIC); |
733 | ec_hdr->version = UBI_VERSION; | 733 | ec_hdr->version = UBI_VERSION; |
734 | ec_hdr->vid_hdr_offset = cpu_to_ubi32(ubi->vid_hdr_offset); | 734 | ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); |
735 | ec_hdr->data_offset = cpu_to_ubi32(ubi->leb_start); | 735 | ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); |
736 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); | 736 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); |
737 | ec_hdr->hdr_crc = cpu_to_ubi32(crc); | 737 | ec_hdr->hdr_crc = cpu_to_be32(crc); |
738 | 738 | ||
739 | err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr); | 739 | err = paranoid_check_ec_hdr(ubi, pnum, ec_hdr); |
740 | if (err) | 740 | if (err) |
@@ -757,13 +757,13 @@ static int validate_vid_hdr(const struct ubi_device *ubi, | |||
757 | { | 757 | { |
758 | int vol_type = vid_hdr->vol_type; | 758 | int vol_type = vid_hdr->vol_type; |
759 | int copy_flag = vid_hdr->copy_flag; | 759 | int copy_flag = vid_hdr->copy_flag; |
760 | int vol_id = ubi32_to_cpu(vid_hdr->vol_id); | 760 | int vol_id = be32_to_cpu(vid_hdr->vol_id); |
761 | int lnum = ubi32_to_cpu(vid_hdr->lnum); | 761 | int lnum = be32_to_cpu(vid_hdr->lnum); |
762 | int compat = vid_hdr->compat; | 762 | int compat = vid_hdr->compat; |
763 | int data_size = ubi32_to_cpu(vid_hdr->data_size); | 763 | int data_size = be32_to_cpu(vid_hdr->data_size); |
764 | int used_ebs = ubi32_to_cpu(vid_hdr->used_ebs); | 764 | int used_ebs = be32_to_cpu(vid_hdr->used_ebs); |
765 | int data_pad = ubi32_to_cpu(vid_hdr->data_pad); | 765 | int data_pad = be32_to_cpu(vid_hdr->data_pad); |
766 | int data_crc = ubi32_to_cpu(vid_hdr->data_crc); | 766 | int data_crc = be32_to_cpu(vid_hdr->data_crc); |
767 | int usable_leb_size = ubi->leb_size - data_pad; | 767 | int usable_leb_size = ubi->leb_size - data_pad; |
768 | 768 | ||
769 | if (copy_flag != 0 && copy_flag != 1) { | 769 | if (copy_flag != 0 && copy_flag != 1) { |
@@ -914,7 +914,7 @@ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum, | |||
914 | read_err = err; | 914 | read_err = err; |
915 | } | 915 | } |
916 | 916 | ||
917 | magic = ubi32_to_cpu(vid_hdr->magic); | 917 | magic = be32_to_cpu(vid_hdr->magic); |
918 | if (magic != UBI_VID_HDR_MAGIC) { | 918 | if (magic != UBI_VID_HDR_MAGIC) { |
919 | /* | 919 | /* |
920 | * If we have read all 0xFF bytes, the VID header probably does | 920 | * If we have read all 0xFF bytes, the VID header probably does |
@@ -957,7 +957,7 @@ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum, | |||
957 | } | 957 | } |
958 | 958 | ||
959 | crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); | 959 | crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); |
960 | hdr_crc = ubi32_to_cpu(vid_hdr->hdr_crc); | 960 | hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); |
961 | 961 | ||
962 | if (hdr_crc != crc) { | 962 | if (hdr_crc != crc) { |
963 | if (verbose) { | 963 | if (verbose) { |
@@ -1007,10 +1007,10 @@ int ubi_io_write_vid_hdr(const struct ubi_device *ubi, int pnum, | |||
1007 | if (err) | 1007 | if (err) |
1008 | return err > 0 ? -EINVAL: err; | 1008 | return err > 0 ? -EINVAL: err; |
1009 | 1009 | ||
1010 | vid_hdr->magic = cpu_to_ubi32(UBI_VID_HDR_MAGIC); | 1010 | vid_hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); |
1011 | vid_hdr->version = UBI_VERSION; | 1011 | vid_hdr->version = UBI_VERSION; |
1012 | crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); | 1012 | crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_VID_HDR_SIZE_CRC); |
1013 | vid_hdr->hdr_crc = cpu_to_ubi32(crc); | 1013 | vid_hdr->hdr_crc = cpu_to_be32(crc); |
1014 | 1014 | ||
1015 | err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr); | 1015 | err = paranoid_check_vid_hdr(ubi, pnum, vid_hdr); |
1016 | if (err) | 1016 | if (err) |
@@ -1060,7 +1060,7 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
1060 | int err; | 1060 | int err; |
1061 | uint32_t magic; | 1061 | uint32_t magic; |
1062 | 1062 | ||
1063 | magic = ubi32_to_cpu(ec_hdr->magic); | 1063 | magic = be32_to_cpu(ec_hdr->magic); |
1064 | if (magic != UBI_EC_HDR_MAGIC) { | 1064 | if (magic != UBI_EC_HDR_MAGIC) { |
1065 | ubi_err("bad magic %#08x, must be %#08x", | 1065 | ubi_err("bad magic %#08x, must be %#08x", |
1066 | magic, UBI_EC_HDR_MAGIC); | 1066 | magic, UBI_EC_HDR_MAGIC); |
@@ -1105,7 +1105,7 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) | |||
1105 | goto exit; | 1105 | goto exit; |
1106 | 1106 | ||
1107 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); | 1107 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); |
1108 | hdr_crc = ubi32_to_cpu(ec_hdr->hdr_crc); | 1108 | hdr_crc = be32_to_cpu(ec_hdr->hdr_crc); |
1109 | if (hdr_crc != crc) { | 1109 | if (hdr_crc != crc) { |
1110 | ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc); | 1110 | ubi_err("bad CRC, calculated %#08x, read %#08x", crc, hdr_crc); |
1111 | ubi_err("paranoid check failed for PEB %d", pnum); | 1111 | ubi_err("paranoid check failed for PEB %d", pnum); |
@@ -1137,7 +1137,7 @@ static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, | |||
1137 | int err; | 1137 | int err; |
1138 | uint32_t magic; | 1138 | uint32_t magic; |
1139 | 1139 | ||
1140 | magic = ubi32_to_cpu(vid_hdr->magic); | 1140 | magic = be32_to_cpu(vid_hdr->magic); |
1141 | if (magic != UBI_VID_HDR_MAGIC) { | 1141 | if (magic != UBI_VID_HDR_MAGIC) { |
1142 | ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x", | 1142 | ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x", |
1143 | magic, pnum, UBI_VID_HDR_MAGIC); | 1143 | magic, pnum, UBI_VID_HDR_MAGIC); |
@@ -1187,7 +1187,7 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) | |||
1187 | goto exit; | 1187 | goto exit; |
1188 | 1188 | ||
1189 | crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC); | 1189 | crc = crc32(UBI_CRC32_INIT, vid_hdr, UBI_EC_HDR_SIZE_CRC); |
1190 | hdr_crc = ubi32_to_cpu(vid_hdr->hdr_crc); | 1190 | hdr_crc = be32_to_cpu(vid_hdr->hdr_crc); |
1191 | if (hdr_crc != crc) { | 1191 | if (hdr_crc != crc) { |
1192 | ubi_err("bad VID header CRC at PEB %d, calculated %#08x, " | 1192 | ubi_err("bad VID header CRC at PEB %d, calculated %#08x, " |
1193 | "read %#08x", pnum, crc, hdr_crc); | 1193 | "read %#08x", pnum, crc, hdr_crc); |
@@ -1224,9 +1224,10 @@ static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum, | |||
1224 | void *buf; | 1224 | void *buf; |
1225 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; | 1225 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; |
1226 | 1226 | ||
1227 | buf = kzalloc(len, GFP_KERNEL); | 1227 | buf = vmalloc(len); |
1228 | if (!buf) | 1228 | if (!buf) |
1229 | return -ENOMEM; | 1229 | return -ENOMEM; |
1230 | memset(buf, 0, len); | ||
1230 | 1231 | ||
1231 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); | 1232 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); |
1232 | if (err && err != -EUCLEAN) { | 1233 | if (err && err != -EUCLEAN) { |
@@ -1242,7 +1243,7 @@ static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum, | |||
1242 | goto fail; | 1243 | goto fail; |
1243 | } | 1244 | } |
1244 | 1245 | ||
1245 | kfree(buf); | 1246 | vfree(buf); |
1246 | return 0; | 1247 | return 0; |
1247 | 1248 | ||
1248 | fail: | 1249 | fail: |
@@ -1252,7 +1253,7 @@ fail: | |||
1252 | err = 1; | 1253 | err = 1; |
1253 | error: | 1254 | error: |
1254 | ubi_dbg_dump_stack(); | 1255 | ubi_dbg_dump_stack(); |
1255 | kfree(buf); | 1256 | vfree(buf); |
1256 | return err; | 1257 | return err; |
1257 | } | 1258 | } |
1258 | 1259 | ||
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index d352c4575c3d..4a458e83e4e9 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c | |||
@@ -37,14 +37,9 @@ int ubi_get_device_info(int ubi_num, struct ubi_device_info *di) | |||
37 | { | 37 | { |
38 | const struct ubi_device *ubi; | 38 | const struct ubi_device *ubi; |
39 | 39 | ||
40 | if (!try_module_get(THIS_MODULE)) | ||
41 | return -ENODEV; | ||
42 | |||
43 | if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES || | 40 | if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES || |
44 | !ubi_devices[ubi_num]) { | 41 | !ubi_devices[ubi_num]) |
45 | module_put(THIS_MODULE); | ||
46 | return -ENODEV; | 42 | return -ENODEV; |
47 | } | ||
48 | 43 | ||
49 | ubi = ubi_devices[ubi_num]; | 44 | ubi = ubi_devices[ubi_num]; |
50 | di->ubi_num = ubi->ubi_num; | 45 | di->ubi_num = ubi->ubi_num; |
@@ -52,7 +47,6 @@ int ubi_get_device_info(int ubi_num, struct ubi_device_info *di) | |||
52 | di->min_io_size = ubi->min_io_size; | 47 | di->min_io_size = ubi->min_io_size; |
53 | di->ro_mode = ubi->ro_mode; | 48 | di->ro_mode = ubi->ro_mode; |
54 | di->cdev = MKDEV(ubi->major, 0); | 49 | di->cdev = MKDEV(ubi->major, 0); |
55 | module_put(THIS_MODULE); | ||
56 | return 0; | 50 | return 0; |
57 | } | 51 | } |
58 | EXPORT_SYMBOL_GPL(ubi_get_device_info); | 52 | EXPORT_SYMBOL_GPL(ubi_get_device_info); |
@@ -319,9 +313,14 @@ int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, | |||
319 | offset + len > vol->usable_leb_size) | 313 | offset + len > vol->usable_leb_size) |
320 | return -EINVAL; | 314 | return -EINVAL; |
321 | 315 | ||
322 | if (vol->vol_type == UBI_STATIC_VOLUME && lnum == vol->used_ebs - 1 && | 316 | if (vol->vol_type == UBI_STATIC_VOLUME) { |
323 | offset + len > vol->last_eb_bytes) | 317 | if (vol->used_ebs == 0) |
324 | return -EINVAL; | 318 | /* Empty static UBI volume */ |
319 | return 0; | ||
320 | if (lnum == vol->used_ebs - 1 && | ||
321 | offset + len > vol->last_eb_bytes) | ||
322 | return -EINVAL; | ||
323 | } | ||
325 | 324 | ||
326 | if (vol->upd_marker) | 325 | if (vol->upd_marker) |
327 | return -EBADF; | 326 | return -EBADF; |
diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c index 38d4e6757dc7..9e2338c8e2cf 100644 --- a/drivers/mtd/ubi/misc.c +++ b/drivers/mtd/ubi/misc.c | |||
@@ -67,7 +67,7 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id) | |||
67 | if (vol->vol_type != UBI_STATIC_VOLUME) | 67 | if (vol->vol_type != UBI_STATIC_VOLUME) |
68 | return 0; | 68 | return 0; |
69 | 69 | ||
70 | buf = kmalloc(vol->usable_leb_size, GFP_KERNEL); | 70 | buf = vmalloc(vol->usable_leb_size); |
71 | if (!buf) | 71 | if (!buf) |
72 | return -ENOMEM; | 72 | return -ENOMEM; |
73 | 73 | ||
@@ -87,7 +87,7 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id) | |||
87 | } | 87 | } |
88 | } | 88 | } |
89 | 89 | ||
90 | kfree(buf); | 90 | vfree(buf); |
91 | return err; | 91 | return err; |
92 | } | 92 | } |
93 | 93 | ||
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 473f3200b868..94ee54934411 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * This unit is responsible for scanning the flash media, checking UBI | 24 | * This unit is responsible for scanning the flash media, checking UBI |
25 | * headers and providing complete information about the UBI flash image. | 25 | * headers and providing complete information about the UBI flash image. |
26 | * | 26 | * |
27 | * The scanning information is reoresented by a &struct ubi_scan_info' object. | 27 | * The scanning information is represented by a &struct ubi_scan_info' object. |
28 | * Information about found volumes is represented by &struct ubi_scan_volume | 28 | * Information about found volumes is represented by &struct ubi_scan_volume |
29 | * objects which are kept in volume RB-tree with root at the @volumes field. | 29 | * objects which are kept in volume RB-tree with root at the @volumes field. |
30 | * The RB-tree is indexed by the volume ID. | 30 | * The RB-tree is indexed by the volume ID. |
@@ -55,8 +55,19 @@ static int paranoid_check_si(const struct ubi_device *ubi, | |||
55 | static struct ubi_ec_hdr *ech; | 55 | static struct ubi_ec_hdr *ech; |
56 | static struct ubi_vid_hdr *vidh; | 56 | static struct ubi_vid_hdr *vidh; |
57 | 57 | ||
58 | int ubi_scan_add_to_list(struct ubi_scan_info *si, int pnum, int ec, | 58 | /** |
59 | struct list_head *list) | 59 | * add_to_list - add physical eraseblock to a list. |
60 | * @si: scanning information | ||
61 | * @pnum: physical eraseblock number to add | ||
62 | * @ec: erase counter of the physical eraseblock | ||
63 | * @list: the list to add to | ||
64 | * | ||
65 | * This function adds physical eraseblock @pnum to free, erase, corrupted or | ||
66 | * alien lists. Returns zero in case of success and a negative error code in | ||
67 | * case of failure. | ||
68 | */ | ||
69 | static int add_to_list(struct ubi_scan_info *si, int pnum, int ec, | ||
70 | struct list_head *list) | ||
60 | { | 71 | { |
61 | struct ubi_scan_leb *seb; | 72 | struct ubi_scan_leb *seb; |
62 | 73 | ||
@@ -121,9 +132,9 @@ static int validate_vid_hdr(const struct ubi_vid_hdr *vid_hdr, | |||
121 | const struct ubi_scan_volume *sv, int pnum) | 132 | const struct ubi_scan_volume *sv, int pnum) |
122 | { | 133 | { |
123 | int vol_type = vid_hdr->vol_type; | 134 | int vol_type = vid_hdr->vol_type; |
124 | int vol_id = ubi32_to_cpu(vid_hdr->vol_id); | 135 | int vol_id = be32_to_cpu(vid_hdr->vol_id); |
125 | int used_ebs = ubi32_to_cpu(vid_hdr->used_ebs); | 136 | int used_ebs = be32_to_cpu(vid_hdr->used_ebs); |
126 | int data_pad = ubi32_to_cpu(vid_hdr->data_pad); | 137 | int data_pad = be32_to_cpu(vid_hdr->data_pad); |
127 | 138 | ||
128 | if (sv->leb_count != 0) { | 139 | if (sv->leb_count != 0) { |
129 | int sv_vol_type; | 140 | int sv_vol_type; |
@@ -189,7 +200,7 @@ static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id, | |||
189 | struct ubi_scan_volume *sv; | 200 | struct ubi_scan_volume *sv; |
190 | struct rb_node **p = &si->volumes.rb_node, *parent = NULL; | 201 | struct rb_node **p = &si->volumes.rb_node, *parent = NULL; |
191 | 202 | ||
192 | ubi_assert(vol_id == ubi32_to_cpu(vid_hdr->vol_id)); | 203 | ubi_assert(vol_id == be32_to_cpu(vid_hdr->vol_id)); |
193 | 204 | ||
194 | /* Walk the volume RB-tree to look if this volume is already present */ | 205 | /* Walk the volume RB-tree to look if this volume is already present */ |
195 | while (*p) { | 206 | while (*p) { |
@@ -211,11 +222,10 @@ static struct ubi_scan_volume *add_volume(struct ubi_scan_info *si, int vol_id, | |||
211 | return ERR_PTR(-ENOMEM); | 222 | return ERR_PTR(-ENOMEM); |
212 | 223 | ||
213 | sv->highest_lnum = sv->leb_count = 0; | 224 | sv->highest_lnum = sv->leb_count = 0; |
214 | si->max_sqnum = 0; | ||
215 | sv->vol_id = vol_id; | 225 | sv->vol_id = vol_id; |
216 | sv->root = RB_ROOT; | 226 | sv->root = RB_ROOT; |
217 | sv->used_ebs = ubi32_to_cpu(vid_hdr->used_ebs); | 227 | sv->used_ebs = be32_to_cpu(vid_hdr->used_ebs); |
218 | sv->data_pad = ubi32_to_cpu(vid_hdr->data_pad); | 228 | sv->data_pad = be32_to_cpu(vid_hdr->data_pad); |
219 | sv->compat = vid_hdr->compat; | 229 | sv->compat = vid_hdr->compat; |
220 | sv->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME | 230 | sv->vol_type = vid_hdr->vol_type == UBI_VID_DYNAMIC ? UBI_DYNAMIC_VOLUME |
221 | : UBI_STATIC_VOLUME; | 231 | : UBI_STATIC_VOLUME; |
@@ -257,10 +267,10 @@ static int compare_lebs(const struct ubi_device *ubi, | |||
257 | int len, err, second_is_newer, bitflips = 0, corrupted = 0; | 267 | int len, err, second_is_newer, bitflips = 0, corrupted = 0; |
258 | uint32_t data_crc, crc; | 268 | uint32_t data_crc, crc; |
259 | struct ubi_vid_hdr *vidh = NULL; | 269 | struct ubi_vid_hdr *vidh = NULL; |
260 | unsigned long long sqnum2 = ubi64_to_cpu(vid_hdr->sqnum); | 270 | unsigned long long sqnum2 = be64_to_cpu(vid_hdr->sqnum); |
261 | 271 | ||
262 | if (seb->sqnum == 0 && sqnum2 == 0) { | 272 | if (seb->sqnum == 0 && sqnum2 == 0) { |
263 | long long abs, v1 = seb->leb_ver, v2 = ubi32_to_cpu(vid_hdr->leb_ver); | 273 | long long abs, v1 = seb->leb_ver, v2 = be32_to_cpu(vid_hdr->leb_ver); |
264 | 274 | ||
265 | /* | 275 | /* |
266 | * UBI constantly increases the logical eraseblock version | 276 | * UBI constantly increases the logical eraseblock version |
@@ -344,8 +354,8 @@ static int compare_lebs(const struct ubi_device *ubi, | |||
344 | 354 | ||
345 | /* Read the data of the copy and check the CRC */ | 355 | /* Read the data of the copy and check the CRC */ |
346 | 356 | ||
347 | len = ubi32_to_cpu(vid_hdr->data_size); | 357 | len = be32_to_cpu(vid_hdr->data_size); |
348 | buf = kmalloc(len, GFP_KERNEL); | 358 | buf = vmalloc(len); |
349 | if (!buf) { | 359 | if (!buf) { |
350 | err = -ENOMEM; | 360 | err = -ENOMEM; |
351 | goto out_free_vidh; | 361 | goto out_free_vidh; |
@@ -355,7 +365,7 @@ static int compare_lebs(const struct ubi_device *ubi, | |||
355 | if (err && err != UBI_IO_BITFLIPS) | 365 | if (err && err != UBI_IO_BITFLIPS) |
356 | goto out_free_buf; | 366 | goto out_free_buf; |
357 | 367 | ||
358 | data_crc = ubi32_to_cpu(vid_hdr->data_crc); | 368 | data_crc = be32_to_cpu(vid_hdr->data_crc); |
359 | crc = crc32(UBI_CRC32_INIT, buf, len); | 369 | crc = crc32(UBI_CRC32_INIT, buf, len); |
360 | if (crc != data_crc) { | 370 | if (crc != data_crc) { |
361 | dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x", | 371 | dbg_bld("PEB %d CRC error: calculated %#08x, must be %#08x", |
@@ -368,7 +378,7 @@ static int compare_lebs(const struct ubi_device *ubi, | |||
368 | bitflips = !!err; | 378 | bitflips = !!err; |
369 | } | 379 | } |
370 | 380 | ||
371 | kfree(buf); | 381 | vfree(buf); |
372 | ubi_free_vid_hdr(ubi, vidh); | 382 | ubi_free_vid_hdr(ubi, vidh); |
373 | 383 | ||
374 | if (second_is_newer) | 384 | if (second_is_newer) |
@@ -379,7 +389,7 @@ static int compare_lebs(const struct ubi_device *ubi, | |||
379 | return second_is_newer | (bitflips << 1) | (corrupted << 2); | 389 | return second_is_newer | (bitflips << 1) | (corrupted << 2); |
380 | 390 | ||
381 | out_free_buf: | 391 | out_free_buf: |
382 | kfree(buf); | 392 | vfree(buf); |
383 | out_free_vidh: | 393 | out_free_vidh: |
384 | ubi_free_vid_hdr(ubi, vidh); | 394 | ubi_free_vid_hdr(ubi, vidh); |
385 | ubi_assert(err < 0); | 395 | ubi_assert(err < 0); |
@@ -396,8 +406,12 @@ out_free_vidh: | |||
396 | * @vid_hdr: the volume identifier header | 406 | * @vid_hdr: the volume identifier header |
397 | * @bitflips: if bit-flips were detected when this physical eraseblock was read | 407 | * @bitflips: if bit-flips were detected when this physical eraseblock was read |
398 | * | 408 | * |
399 | * This function returns zero in case of success and a negative error code in | 409 | * This function adds information about a used physical eraseblock to the |
400 | * case of failure. | 410 | * 'used' tree of the corresponding volume. The function is rather complex |
411 | * because it has to handle cases when this is not the first physical | ||
412 | * eraseblock belonging to the same logical eraseblock, and the newer one has | ||
413 | * to be picked, while the older one has to be dropped. This function returns | ||
414 | * zero in case of success and a negative error code in case of failure. | ||
401 | */ | 415 | */ |
402 | int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, | 416 | int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, |
403 | int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, | 417 | int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, |
@@ -410,10 +424,10 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, | |||
410 | struct ubi_scan_leb *seb; | 424 | struct ubi_scan_leb *seb; |
411 | struct rb_node **p, *parent = NULL; | 425 | struct rb_node **p, *parent = NULL; |
412 | 426 | ||
413 | vol_id = ubi32_to_cpu(vid_hdr->vol_id); | 427 | vol_id = be32_to_cpu(vid_hdr->vol_id); |
414 | lnum = ubi32_to_cpu(vid_hdr->lnum); | 428 | lnum = be32_to_cpu(vid_hdr->lnum); |
415 | sqnum = ubi64_to_cpu(vid_hdr->sqnum); | 429 | sqnum = be64_to_cpu(vid_hdr->sqnum); |
416 | leb_ver = ubi32_to_cpu(vid_hdr->leb_ver); | 430 | leb_ver = be32_to_cpu(vid_hdr->leb_ver); |
417 | 431 | ||
418 | dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, ver %u, bitflips %d", | 432 | dbg_bld("PEB %d, LEB %d:%d, EC %d, sqnum %llu, ver %u, bitflips %d", |
419 | pnum, vol_id, lnum, ec, sqnum, leb_ver, bitflips); | 433 | pnum, vol_id, lnum, ec, sqnum, leb_ver, bitflips); |
@@ -422,6 +436,9 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, | |||
422 | if (IS_ERR(sv) < 0) | 436 | if (IS_ERR(sv) < 0) |
423 | return PTR_ERR(sv); | 437 | return PTR_ERR(sv); |
424 | 438 | ||
439 | if (si->max_sqnum < sqnum) | ||
440 | si->max_sqnum = sqnum; | ||
441 | |||
425 | /* | 442 | /* |
426 | * Walk the RB-tree of logical eraseblocks of volume @vol_id to look | 443 | * Walk the RB-tree of logical eraseblocks of volume @vol_id to look |
427 | * if this is the first instance of this logical eraseblock or not. | 444 | * if this is the first instance of this logical eraseblock or not. |
@@ -492,11 +509,11 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, | |||
492 | return err; | 509 | return err; |
493 | 510 | ||
494 | if (cmp_res & 4) | 511 | if (cmp_res & 4) |
495 | err = ubi_scan_add_to_list(si, seb->pnum, | 512 | err = add_to_list(si, seb->pnum, seb->ec, |
496 | seb->ec, &si->corr); | 513 | &si->corr); |
497 | else | 514 | else |
498 | err = ubi_scan_add_to_list(si, seb->pnum, | 515 | err = add_to_list(si, seb->pnum, seb->ec, |
499 | seb->ec, &si->erase); | 516 | &si->erase); |
500 | if (err) | 517 | if (err) |
501 | return err; | 518 | return err; |
502 | 519 | ||
@@ -508,7 +525,7 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, | |||
508 | 525 | ||
509 | if (sv->highest_lnum == lnum) | 526 | if (sv->highest_lnum == lnum) |
510 | sv->last_data_size = | 527 | sv->last_data_size = |
511 | ubi32_to_cpu(vid_hdr->data_size); | 528 | be32_to_cpu(vid_hdr->data_size); |
512 | 529 | ||
513 | return 0; | 530 | return 0; |
514 | } else { | 531 | } else { |
@@ -517,11 +534,9 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, | |||
517 | * previously. | 534 | * previously. |
518 | */ | 535 | */ |
519 | if (cmp_res & 4) | 536 | if (cmp_res & 4) |
520 | return ubi_scan_add_to_list(si, pnum, ec, | 537 | return add_to_list(si, pnum, ec, &si->corr); |
521 | &si->corr); | ||
522 | else | 538 | else |
523 | return ubi_scan_add_to_list(si, pnum, ec, | 539 | return add_to_list(si, pnum, ec, &si->erase); |
524 | &si->erase); | ||
525 | } | 540 | } |
526 | } | 541 | } |
527 | 542 | ||
@@ -547,12 +562,9 @@ int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, | |||
547 | 562 | ||
548 | if (sv->highest_lnum <= lnum) { | 563 | if (sv->highest_lnum <= lnum) { |
549 | sv->highest_lnum = lnum; | 564 | sv->highest_lnum = lnum; |
550 | sv->last_data_size = ubi32_to_cpu(vid_hdr->data_size); | 565 | sv->last_data_size = be32_to_cpu(vid_hdr->data_size); |
551 | } | 566 | } |
552 | 567 | ||
553 | if (si->max_sqnum < sqnum) | ||
554 | si->max_sqnum = sqnum; | ||
555 | |||
556 | sv->leb_count += 1; | 568 | sv->leb_count += 1; |
557 | rb_link_node(&seb->u.rb, parent, p); | 569 | rb_link_node(&seb->u.rb, parent, p); |
558 | rb_insert_color(&seb->u.rb, &sv->root); | 570 | rb_insert_color(&seb->u.rb, &sv->root); |
@@ -674,7 +686,7 @@ int ubi_scan_erase_peb(const struct ubi_device *ubi, | |||
674 | return -EINVAL; | 686 | return -EINVAL; |
675 | } | 687 | } |
676 | 688 | ||
677 | ec_hdr->ec = cpu_to_ubi64(ec); | 689 | ec_hdr->ec = cpu_to_be64(ec); |
678 | 690 | ||
679 | err = ubi_io_sync_erase(ubi, pnum, 0); | 691 | err = ubi_io_sync_erase(ubi, pnum, 0); |
680 | if (err < 0) | 692 | if (err < 0) |
@@ -754,7 +766,7 @@ struct ubi_scan_leb *ubi_scan_get_free_peb(const struct ubi_device *ubi, | |||
754 | * @si: scanning information | 766 | * @si: scanning information |
755 | * @pnum: the physical eraseblock number | 767 | * @pnum: the physical eraseblock number |
756 | * | 768 | * |
757 | * This function returns a zero if the physical eraseblock was succesfully | 769 | * This function returns a zero if the physical eraseblock was successfully |
758 | * handled and a negative error code in case of failure. | 770 | * handled and a negative error code in case of failure. |
759 | */ | 771 | */ |
760 | static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum) | 772 | static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum) |
@@ -783,8 +795,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum | |||
783 | else if (err == UBI_IO_BITFLIPS) | 795 | else if (err == UBI_IO_BITFLIPS) |
784 | bitflips = 1; | 796 | bitflips = 1; |
785 | else if (err == UBI_IO_PEB_EMPTY) | 797 | else if (err == UBI_IO_PEB_EMPTY) |
786 | return ubi_scan_add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, | 798 | return add_to_list(si, pnum, UBI_SCAN_UNKNOWN_EC, &si->erase); |
787 | &si->erase); | ||
788 | else if (err == UBI_IO_BAD_EC_HDR) { | 799 | else if (err == UBI_IO_BAD_EC_HDR) { |
789 | /* | 800 | /* |
790 | * We have to also look at the VID header, possibly it is not | 801 | * We have to also look at the VID header, possibly it is not |
@@ -806,7 +817,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum | |||
806 | return -EINVAL; | 817 | return -EINVAL; |
807 | } | 818 | } |
808 | 819 | ||
809 | ec = ubi64_to_cpu(ech->ec); | 820 | ec = be64_to_cpu(ech->ec); |
810 | if (ec > UBI_MAX_ERASECOUNTER) { | 821 | if (ec > UBI_MAX_ERASECOUNTER) { |
811 | /* | 822 | /* |
812 | * Erase counter overflow. The EC headers have 64 bits | 823 | * Erase counter overflow. The EC headers have 64 bits |
@@ -832,28 +843,28 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum | |||
832 | else if (err == UBI_IO_BAD_VID_HDR || | 843 | else if (err == UBI_IO_BAD_VID_HDR || |
833 | (err == UBI_IO_PEB_FREE && ec_corr)) { | 844 | (err == UBI_IO_PEB_FREE && ec_corr)) { |
834 | /* VID header is corrupted */ | 845 | /* VID header is corrupted */ |
835 | err = ubi_scan_add_to_list(si, pnum, ec, &si->corr); | 846 | err = add_to_list(si, pnum, ec, &si->corr); |
836 | if (err) | 847 | if (err) |
837 | return err; | 848 | return err; |
838 | goto adjust_mean_ec; | 849 | goto adjust_mean_ec; |
839 | } else if (err == UBI_IO_PEB_FREE) { | 850 | } else if (err == UBI_IO_PEB_FREE) { |
840 | /* No VID header - the physical eraseblock is free */ | 851 | /* No VID header - the physical eraseblock is free */ |
841 | err = ubi_scan_add_to_list(si, pnum, ec, &si->free); | 852 | err = add_to_list(si, pnum, ec, &si->free); |
842 | if (err) | 853 | if (err) |
843 | return err; | 854 | return err; |
844 | goto adjust_mean_ec; | 855 | goto adjust_mean_ec; |
845 | } | 856 | } |
846 | 857 | ||
847 | vol_id = ubi32_to_cpu(vidh->vol_id); | 858 | vol_id = be32_to_cpu(vidh->vol_id); |
848 | if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOL_ID) { | 859 | if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOL_ID) { |
849 | int lnum = ubi32_to_cpu(vidh->lnum); | 860 | int lnum = be32_to_cpu(vidh->lnum); |
850 | 861 | ||
851 | /* Unsupported internal volume */ | 862 | /* Unsupported internal volume */ |
852 | switch (vidh->compat) { | 863 | switch (vidh->compat) { |
853 | case UBI_COMPAT_DELETE: | 864 | case UBI_COMPAT_DELETE: |
854 | ubi_msg("\"delete\" compatible internal volume %d:%d" | 865 | ubi_msg("\"delete\" compatible internal volume %d:%d" |
855 | " found, remove it", vol_id, lnum); | 866 | " found, remove it", vol_id, lnum); |
856 | err = ubi_scan_add_to_list(si, pnum, ec, &si->corr); | 867 | err = add_to_list(si, pnum, ec, &si->corr); |
857 | if (err) | 868 | if (err) |
858 | return err; | 869 | return err; |
859 | break; | 870 | break; |
@@ -868,7 +879,7 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, int pnum | |||
868 | case UBI_COMPAT_PRESERVE: | 879 | case UBI_COMPAT_PRESERVE: |
869 | ubi_msg("\"preserve\" compatible internal volume %d:%d" | 880 | ubi_msg("\"preserve\" compatible internal volume %d:%d" |
870 | " found", vol_id, lnum); | 881 | " found", vol_id, lnum); |
871 | err = ubi_scan_add_to_list(si, pnum, ec, &si->alien); | 882 | err = add_to_list(si, pnum, ec, &si->alien); |
872 | if (err) | 883 | if (err) |
873 | return err; | 884 | return err; |
874 | si->alien_peb_count += 1; | 885 | si->alien_peb_count += 1; |
@@ -1109,7 +1120,7 @@ static int paranoid_check_si(const struct ubi_device *ubi, | |||
1109 | uint8_t *buf; | 1120 | uint8_t *buf; |
1110 | 1121 | ||
1111 | /* | 1122 | /* |
1112 | * At first, check that scanning information is ok. | 1123 | * At first, check that scanning information is OK. |
1113 | */ | 1124 | */ |
1114 | ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { | 1125 | ubi_rb_for_each_entry(rb1, sv, &si->volumes, rb) { |
1115 | int leb_count = 0; | 1126 | int leb_count = 0; |
@@ -1249,12 +1260,12 @@ static int paranoid_check_si(const struct ubi_device *ubi, | |||
1249 | goto bad_vid_hdr; | 1260 | goto bad_vid_hdr; |
1250 | } | 1261 | } |
1251 | 1262 | ||
1252 | if (seb->sqnum != ubi64_to_cpu(vidh->sqnum)) { | 1263 | if (seb->sqnum != be64_to_cpu(vidh->sqnum)) { |
1253 | ubi_err("bad sqnum %llu", seb->sqnum); | 1264 | ubi_err("bad sqnum %llu", seb->sqnum); |
1254 | goto bad_vid_hdr; | 1265 | goto bad_vid_hdr; |
1255 | } | 1266 | } |
1256 | 1267 | ||
1257 | if (sv->vol_id != ubi32_to_cpu(vidh->vol_id)) { | 1268 | if (sv->vol_id != be32_to_cpu(vidh->vol_id)) { |
1258 | ubi_err("bad vol_id %d", sv->vol_id); | 1269 | ubi_err("bad vol_id %d", sv->vol_id); |
1259 | goto bad_vid_hdr; | 1270 | goto bad_vid_hdr; |
1260 | } | 1271 | } |
@@ -1264,22 +1275,22 @@ static int paranoid_check_si(const struct ubi_device *ubi, | |||
1264 | goto bad_vid_hdr; | 1275 | goto bad_vid_hdr; |
1265 | } | 1276 | } |
1266 | 1277 | ||
1267 | if (seb->lnum != ubi32_to_cpu(vidh->lnum)) { | 1278 | if (seb->lnum != be32_to_cpu(vidh->lnum)) { |
1268 | ubi_err("bad lnum %d", seb->lnum); | 1279 | ubi_err("bad lnum %d", seb->lnum); |
1269 | goto bad_vid_hdr; | 1280 | goto bad_vid_hdr; |
1270 | } | 1281 | } |
1271 | 1282 | ||
1272 | if (sv->used_ebs != ubi32_to_cpu(vidh->used_ebs)) { | 1283 | if (sv->used_ebs != be32_to_cpu(vidh->used_ebs)) { |
1273 | ubi_err("bad used_ebs %d", sv->used_ebs); | 1284 | ubi_err("bad used_ebs %d", sv->used_ebs); |
1274 | goto bad_vid_hdr; | 1285 | goto bad_vid_hdr; |
1275 | } | 1286 | } |
1276 | 1287 | ||
1277 | if (sv->data_pad != ubi32_to_cpu(vidh->data_pad)) { | 1288 | if (sv->data_pad != be32_to_cpu(vidh->data_pad)) { |
1278 | ubi_err("bad data_pad %d", sv->data_pad); | 1289 | ubi_err("bad data_pad %d", sv->data_pad); |
1279 | goto bad_vid_hdr; | 1290 | goto bad_vid_hdr; |
1280 | } | 1291 | } |
1281 | 1292 | ||
1282 | if (seb->leb_ver != ubi32_to_cpu(vidh->leb_ver)) { | 1293 | if (seb->leb_ver != be32_to_cpu(vidh->leb_ver)) { |
1283 | ubi_err("bad leb_ver %u", seb->leb_ver); | 1294 | ubi_err("bad leb_ver %u", seb->leb_ver); |
1284 | goto bad_vid_hdr; | 1295 | goto bad_vid_hdr; |
1285 | } | 1296 | } |
@@ -1288,12 +1299,12 @@ static int paranoid_check_si(const struct ubi_device *ubi, | |||
1288 | if (!last_seb) | 1299 | if (!last_seb) |
1289 | continue; | 1300 | continue; |
1290 | 1301 | ||
1291 | if (sv->highest_lnum != ubi32_to_cpu(vidh->lnum)) { | 1302 | if (sv->highest_lnum != be32_to_cpu(vidh->lnum)) { |
1292 | ubi_err("bad highest_lnum %d", sv->highest_lnum); | 1303 | ubi_err("bad highest_lnum %d", sv->highest_lnum); |
1293 | goto bad_vid_hdr; | 1304 | goto bad_vid_hdr; |
1294 | } | 1305 | } |
1295 | 1306 | ||
1296 | if (sv->last_data_size != ubi32_to_cpu(vidh->data_size)) { | 1307 | if (sv->last_data_size != be32_to_cpu(vidh->data_size)) { |
1297 | ubi_err("bad last_data_size %d", sv->last_data_size); | 1308 | ubi_err("bad last_data_size %d", sv->last_data_size); |
1298 | goto bad_vid_hdr; | 1309 | goto bad_vid_hdr; |
1299 | } | 1310 | } |
@@ -1310,8 +1321,10 @@ static int paranoid_check_si(const struct ubi_device *ubi, | |||
1310 | memset(buf, 1, ubi->peb_count); | 1321 | memset(buf, 1, ubi->peb_count); |
1311 | for (pnum = 0; pnum < ubi->peb_count; pnum++) { | 1322 | for (pnum = 0; pnum < ubi->peb_count; pnum++) { |
1312 | err = ubi_io_is_bad(ubi, pnum); | 1323 | err = ubi_io_is_bad(ubi, pnum); |
1313 | if (err < 0) | 1324 | if (err < 0) { |
1325 | kfree(buf); | ||
1314 | return err; | 1326 | return err; |
1327 | } | ||
1315 | else if (err) | 1328 | else if (err) |
1316 | buf[pnum] = 0; | 1329 | buf[pnum] = 0; |
1317 | } | 1330 | } |
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 3949f6192c76..140e82e26534 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h | |||
@@ -147,8 +147,6 @@ static inline void ubi_scan_move_to_list(struct ubi_scan_volume *sv, | |||
147 | list_add_tail(&seb->u.list, list); | 147 | list_add_tail(&seb->u.list, list); |
148 | } | 148 | } |
149 | 149 | ||
150 | int ubi_scan_add_to_list(struct ubi_scan_info *si, int pnum, int ec, | ||
151 | struct list_head *list); | ||
152 | int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, | 150 | int ubi_scan_add_used(const struct ubi_device *ubi, struct ubi_scan_info *si, |
153 | int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, | 151 | int pnum, int ec, const struct ubi_vid_hdr *vid_hdr, |
154 | int bitflips); | 152 | int bitflips); |
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index feb647f108f0..5959f91be240 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/cdev.h> | 35 | #include <linux/cdev.h> |
36 | #include <linux/device.h> | 36 | #include <linux/device.h> |
37 | #include <linux/string.h> | 37 | #include <linux/string.h> |
38 | #include <linux/vmalloc.h> | ||
38 | #include <linux/mtd/mtd.h> | 39 | #include <linux/mtd/mtd.h> |
39 | 40 | ||
40 | #include <mtd/ubi-header.h> | 41 | #include <mtd/ubi-header.h> |
@@ -374,9 +375,11 @@ void ubi_calculate_reserved(struct ubi_device *ubi); | |||
374 | #ifdef CONFIG_MTD_UBI_GLUEBI | 375 | #ifdef CONFIG_MTD_UBI_GLUEBI |
375 | int ubi_create_gluebi(struct ubi_device *ubi, struct ubi_volume *vol); | 376 | int ubi_create_gluebi(struct ubi_device *ubi, struct ubi_volume *vol); |
376 | int ubi_destroy_gluebi(struct ubi_volume *vol); | 377 | int ubi_destroy_gluebi(struct ubi_volume *vol); |
378 | void ubi_gluebi_updated(struct ubi_volume *vol); | ||
377 | #else | 379 | #else |
378 | #define ubi_create_gluebi(ubi, vol) 0 | 380 | #define ubi_create_gluebi(ubi, vol) 0 |
379 | #define ubi_destroy_gluebi(vol) 0 | 381 | #define ubi_destroy_gluebi(vol) 0 |
382 | #define ubi_gluebi_updated(vol) | ||
380 | #endif | 383 | #endif |
381 | 384 | ||
382 | /* eba.c */ | 385 | /* eba.c */ |
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index 8925b977e3dc..0efc586a8328 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c | |||
@@ -150,7 +150,7 @@ int ubi_start_update(struct ubi_device *ubi, int vol_id, long long bytes) | |||
150 | vol->updating = 0; | 150 | vol->updating = 0; |
151 | } | 151 | } |
152 | 152 | ||
153 | vol->upd_buf = kmalloc(ubi->leb_size, GFP_KERNEL); | 153 | vol->upd_buf = vmalloc(ubi->leb_size); |
154 | if (!vol->upd_buf) | 154 | if (!vol->upd_buf) |
155 | return -ENOMEM; | 155 | return -ENOMEM; |
156 | 156 | ||
@@ -339,7 +339,7 @@ int ubi_more_update_data(struct ubi_device *ubi, int vol_id, | |||
339 | err = ubi_wl_flush(ubi); | 339 | err = ubi_wl_flush(ubi); |
340 | if (err == 0) { | 340 | if (err == 0) { |
341 | err = to_write; | 341 | err = to_write; |
342 | kfree(vol->upd_buf); | 342 | vfree(vol->upd_buf); |
343 | vol->updating = 0; | 343 | vol->updating = 0; |
344 | } | 344 | } |
345 | } | 345 | } |
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 622d0d18952c..ea0d5c825ab4 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c | |||
@@ -228,7 +228,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | |||
228 | for (i = 0; i < ubi->vtbl_slots; i++) | 228 | for (i = 0; i < ubi->vtbl_slots; i++) |
229 | if (ubi->volumes[i] && | 229 | if (ubi->volumes[i] && |
230 | ubi->volumes[i]->name_len == req->name_len && | 230 | ubi->volumes[i]->name_len == req->name_len && |
231 | strcmp(ubi->volumes[i]->name, req->name) == 0) { | 231 | !strcmp(ubi->volumes[i]->name, req->name)) { |
232 | dbg_err("volume \"%s\" exists (ID %d)", req->name, i); | 232 | dbg_err("volume \"%s\" exists (ID %d)", req->name, i); |
233 | goto out_unlock; | 233 | goto out_unlock; |
234 | } | 234 | } |
@@ -243,7 +243,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | |||
243 | /* Reserve physical eraseblocks */ | 243 | /* Reserve physical eraseblocks */ |
244 | if (vol->reserved_pebs > ubi->avail_pebs) { | 244 | if (vol->reserved_pebs > ubi->avail_pebs) { |
245 | dbg_err("not enough PEBs, only %d available", ubi->avail_pebs); | 245 | dbg_err("not enough PEBs, only %d available", ubi->avail_pebs); |
246 | spin_unlock(&ubi->volumes_lock); | ||
247 | err = -ENOSPC; | 246 | err = -ENOSPC; |
248 | goto out_unlock; | 247 | goto out_unlock; |
249 | } | 248 | } |
@@ -281,7 +280,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | |||
281 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { | 280 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { |
282 | vol->used_ebs = vol->reserved_pebs; | 281 | vol->used_ebs = vol->reserved_pebs; |
283 | vol->last_eb_bytes = vol->usable_leb_size; | 282 | vol->last_eb_bytes = vol->usable_leb_size; |
284 | vol->used_bytes = vol->used_ebs * vol->usable_leb_size; | 283 | vol->used_bytes = |
284 | (long long)vol->used_ebs * vol->usable_leb_size; | ||
285 | } else { | 285 | } else { |
286 | bytes = vol->used_bytes; | 286 | bytes = vol->used_bytes; |
287 | vol->last_eb_bytes = do_div(bytes, vol->usable_leb_size); | 287 | vol->last_eb_bytes = do_div(bytes, vol->usable_leb_size); |
@@ -320,10 +320,10 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | |||
320 | 320 | ||
321 | /* Fill volume table record */ | 321 | /* Fill volume table record */ |
322 | memset(&vtbl_rec, 0, sizeof(struct ubi_vtbl_record)); | 322 | memset(&vtbl_rec, 0, sizeof(struct ubi_vtbl_record)); |
323 | vtbl_rec.reserved_pebs = cpu_to_ubi32(vol->reserved_pebs); | 323 | vtbl_rec.reserved_pebs = cpu_to_be32(vol->reserved_pebs); |
324 | vtbl_rec.alignment = cpu_to_ubi32(vol->alignment); | 324 | vtbl_rec.alignment = cpu_to_be32(vol->alignment); |
325 | vtbl_rec.data_pad = cpu_to_ubi32(vol->data_pad); | 325 | vtbl_rec.data_pad = cpu_to_be32(vol->data_pad); |
326 | vtbl_rec.name_len = cpu_to_ubi16(vol->name_len); | 326 | vtbl_rec.name_len = cpu_to_be16(vol->name_len); |
327 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) | 327 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) |
328 | vtbl_rec.vol_type = UBI_VID_DYNAMIC; | 328 | vtbl_rec.vol_type = UBI_VID_DYNAMIC; |
329 | else | 329 | else |
@@ -352,6 +352,7 @@ out_acc: | |||
352 | spin_lock(&ubi->volumes_lock); | 352 | spin_lock(&ubi->volumes_lock); |
353 | ubi->rsvd_pebs -= vol->reserved_pebs; | 353 | ubi->rsvd_pebs -= vol->reserved_pebs; |
354 | ubi->avail_pebs += vol->reserved_pebs; | 354 | ubi->avail_pebs += vol->reserved_pebs; |
355 | ubi->volumes[vol_id] = NULL; | ||
355 | out_unlock: | 356 | out_unlock: |
356 | spin_unlock(&ubi->volumes_lock); | 357 | spin_unlock(&ubi->volumes_lock); |
357 | kfree(vol); | 358 | kfree(vol); |
@@ -368,6 +369,7 @@ out_sysfs: | |||
368 | spin_lock(&ubi->volumes_lock); | 369 | spin_lock(&ubi->volumes_lock); |
369 | ubi->rsvd_pebs -= vol->reserved_pebs; | 370 | ubi->rsvd_pebs -= vol->reserved_pebs; |
370 | ubi->avail_pebs += vol->reserved_pebs; | 371 | ubi->avail_pebs += vol->reserved_pebs; |
372 | ubi->volumes[vol_id] = NULL; | ||
371 | spin_unlock(&ubi->volumes_lock); | 373 | spin_unlock(&ubi->volumes_lock); |
372 | volume_sysfs_close(vol); | 374 | volume_sysfs_close(vol); |
373 | return err; | 375 | return err; |
@@ -503,7 +505,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) | |||
503 | 505 | ||
504 | /* Change volume table record */ | 506 | /* Change volume table record */ |
505 | memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record)); | 507 | memcpy(&vtbl_rec, &ubi->vtbl[vol_id], sizeof(struct ubi_vtbl_record)); |
506 | vtbl_rec.reserved_pebs = cpu_to_ubi32(reserved_pebs); | 508 | vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs); |
507 | err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); | 509 | err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec); |
508 | if (err) | 510 | if (err) |
509 | goto out_acc; | 511 | goto out_acc; |
@@ -537,7 +539,8 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs) | |||
537 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { | 539 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { |
538 | vol->used_ebs = reserved_pebs; | 540 | vol->used_ebs = reserved_pebs; |
539 | vol->last_eb_bytes = vol->usable_leb_size; | 541 | vol->last_eb_bytes = vol->usable_leb_size; |
540 | vol->used_bytes = vol->used_ebs * vol->usable_leb_size; | 542 | vol->used_bytes = |
543 | (long long)vol->used_ebs * vol->usable_leb_size; | ||
541 | } | 544 | } |
542 | 545 | ||
543 | paranoid_check_volumes(ubi); | 546 | paranoid_check_volumes(ubi); |
@@ -643,21 +646,33 @@ void ubi_free_volume(struct ubi_device *ubi, int vol_id) | |||
643 | * @ubi: UBI device description object | 646 | * @ubi: UBI device description object |
644 | * @vol_id: volume ID | 647 | * @vol_id: volume ID |
645 | */ | 648 | */ |
646 | static void paranoid_check_volume(const struct ubi_device *ubi, int vol_id) | 649 | static void paranoid_check_volume(struct ubi_device *ubi, int vol_id) |
647 | { | 650 | { |
648 | int idx = vol_id2idx(ubi, vol_id); | 651 | int idx = vol_id2idx(ubi, vol_id); |
649 | int reserved_pebs, alignment, data_pad, vol_type, name_len, upd_marker; | 652 | int reserved_pebs, alignment, data_pad, vol_type, name_len, upd_marker; |
650 | const struct ubi_volume *vol = ubi->volumes[idx]; | 653 | const struct ubi_volume *vol; |
651 | long long n; | 654 | long long n; |
652 | const char *name; | 655 | const char *name; |
653 | 656 | ||
654 | reserved_pebs = ubi32_to_cpu(ubi->vtbl[vol_id].reserved_pebs); | 657 | spin_lock(&ubi->volumes_lock); |
658 | reserved_pebs = be32_to_cpu(ubi->vtbl[vol_id].reserved_pebs); | ||
659 | vol = ubi->volumes[idx]; | ||
655 | 660 | ||
656 | if (!vol) { | 661 | if (!vol) { |
657 | if (reserved_pebs) { | 662 | if (reserved_pebs) { |
658 | ubi_err("no volume info, but volume exists"); | 663 | ubi_err("no volume info, but volume exists"); |
659 | goto fail; | 664 | goto fail; |
660 | } | 665 | } |
666 | spin_unlock(&ubi->volumes_lock); | ||
667 | return; | ||
668 | } | ||
669 | |||
670 | if (vol->exclusive) { | ||
671 | /* | ||
672 | * The volume may be being created at the moment, do not check | ||
673 | * it (e.g., it may be in the middle of ubi_create_volume(). | ||
674 | */ | ||
675 | spin_unlock(&ubi->volumes_lock); | ||
661 | return; | 676 | return; |
662 | } | 677 | } |
663 | 678 | ||
@@ -726,7 +741,7 @@ static void paranoid_check_volume(const struct ubi_device *ubi, int vol_id) | |||
726 | goto fail; | 741 | goto fail; |
727 | } | 742 | } |
728 | 743 | ||
729 | n = vol->used_ebs * vol->usable_leb_size; | 744 | n = (long long)vol->used_ebs * vol->usable_leb_size; |
730 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { | 745 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { |
731 | if (vol->corrupted != 0) { | 746 | if (vol->corrupted != 0) { |
732 | ubi_err("corrupted dynamic volume"); | 747 | ubi_err("corrupted dynamic volume"); |
@@ -765,9 +780,9 @@ static void paranoid_check_volume(const struct ubi_device *ubi, int vol_id) | |||
765 | } | 780 | } |
766 | } | 781 | } |
767 | 782 | ||
768 | alignment = ubi32_to_cpu(ubi->vtbl[vol_id].alignment); | 783 | alignment = be32_to_cpu(ubi->vtbl[vol_id].alignment); |
769 | data_pad = ubi32_to_cpu(ubi->vtbl[vol_id].data_pad); | 784 | data_pad = be32_to_cpu(ubi->vtbl[vol_id].data_pad); |
770 | name_len = ubi16_to_cpu(ubi->vtbl[vol_id].name_len); | 785 | name_len = be16_to_cpu(ubi->vtbl[vol_id].name_len); |
771 | upd_marker = ubi->vtbl[vol_id].upd_marker; | 786 | upd_marker = ubi->vtbl[vol_id].upd_marker; |
772 | name = &ubi->vtbl[vol_id].name[0]; | 787 | name = &ubi->vtbl[vol_id].name[0]; |
773 | if (ubi->vtbl[vol_id].vol_type == UBI_VID_DYNAMIC) | 788 | if (ubi->vtbl[vol_id].vol_type == UBI_VID_DYNAMIC) |
@@ -782,12 +797,14 @@ static void paranoid_check_volume(const struct ubi_device *ubi, int vol_id) | |||
782 | goto fail; | 797 | goto fail; |
783 | } | 798 | } |
784 | 799 | ||
800 | spin_unlock(&ubi->volumes_lock); | ||
785 | return; | 801 | return; |
786 | 802 | ||
787 | fail: | 803 | fail: |
788 | ubi_err("paranoid check failed"); | 804 | ubi_err("paranoid check failed for volume %d", vol_id); |
789 | ubi_dbg_dump_vol_info(vol); | 805 | ubi_dbg_dump_vol_info(vol); |
790 | ubi_dbg_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id); | 806 | ubi_dbg_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id); |
807 | spin_unlock(&ubi->volumes_lock); | ||
791 | BUG(); | 808 | BUG(); |
792 | } | 809 | } |
793 | 810 | ||
@@ -800,10 +817,8 @@ static void paranoid_check_volumes(struct ubi_device *ubi) | |||
800 | int i; | 817 | int i; |
801 | 818 | ||
802 | mutex_lock(&ubi->vtbl_mutex); | 819 | mutex_lock(&ubi->vtbl_mutex); |
803 | spin_lock(&ubi->volumes_lock); | ||
804 | for (i = 0; i < ubi->vtbl_slots; i++) | 820 | for (i = 0; i < ubi->vtbl_slots; i++) |
805 | paranoid_check_volume(ubi, i); | 821 | paranoid_check_volume(ubi, i); |
806 | spin_unlock(&ubi->volumes_lock); | ||
807 | mutex_unlock(&ubi->vtbl_mutex); | 822 | mutex_unlock(&ubi->vtbl_mutex); |
808 | } | 823 | } |
809 | #endif | 824 | #endif |
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index b6fd6bbd941e..bc5df50813d6 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
@@ -93,12 +93,9 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, | |||
93 | vtbl_rec = &empty_vtbl_record; | 93 | vtbl_rec = &empty_vtbl_record; |
94 | else { | 94 | else { |
95 | crc = crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC); | 95 | crc = crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC); |
96 | vtbl_rec->crc = cpu_to_ubi32(crc); | 96 | vtbl_rec->crc = cpu_to_be32(crc); |
97 | } | 97 | } |
98 | 98 | ||
99 | dbg_msg("change record %d", idx); | ||
100 | ubi_dbg_dump_vtbl_record(vtbl_rec, idx); | ||
101 | |||
102 | mutex_lock(&ubi->vtbl_mutex); | 99 | mutex_lock(&ubi->vtbl_mutex); |
103 | memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); | 100 | memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); |
104 | for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { | 101 | for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { |
@@ -141,18 +138,18 @@ static int vtbl_check(const struct ubi_device *ubi, | |||
141 | for (i = 0; i < ubi->vtbl_slots; i++) { | 138 | for (i = 0; i < ubi->vtbl_slots; i++) { |
142 | cond_resched(); | 139 | cond_resched(); |
143 | 140 | ||
144 | reserved_pebs = ubi32_to_cpu(vtbl[i].reserved_pebs); | 141 | reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs); |
145 | alignment = ubi32_to_cpu(vtbl[i].alignment); | 142 | alignment = be32_to_cpu(vtbl[i].alignment); |
146 | data_pad = ubi32_to_cpu(vtbl[i].data_pad); | 143 | data_pad = be32_to_cpu(vtbl[i].data_pad); |
147 | upd_marker = vtbl[i].upd_marker; | 144 | upd_marker = vtbl[i].upd_marker; |
148 | vol_type = vtbl[i].vol_type; | 145 | vol_type = vtbl[i].vol_type; |
149 | name_len = ubi16_to_cpu(vtbl[i].name_len); | 146 | name_len = be16_to_cpu(vtbl[i].name_len); |
150 | name = &vtbl[i].name[0]; | 147 | name = &vtbl[i].name[0]; |
151 | 148 | ||
152 | crc = crc32(UBI_CRC32_INIT, &vtbl[i], UBI_VTBL_RECORD_SIZE_CRC); | 149 | crc = crc32(UBI_CRC32_INIT, &vtbl[i], UBI_VTBL_RECORD_SIZE_CRC); |
153 | if (ubi32_to_cpu(vtbl[i].crc) != crc) { | 150 | if (be32_to_cpu(vtbl[i].crc) != crc) { |
154 | ubi_err("bad CRC at record %u: %#08x, not %#08x", | 151 | ubi_err("bad CRC at record %u: %#08x, not %#08x", |
155 | i, crc, ubi32_to_cpu(vtbl[i].crc)); | 152 | i, crc, be32_to_cpu(vtbl[i].crc)); |
156 | ubi_dbg_dump_vtbl_record(&vtbl[i], i); | 153 | ubi_dbg_dump_vtbl_record(&vtbl[i], i); |
157 | return 1; | 154 | return 1; |
158 | } | 155 | } |
@@ -225,8 +222,8 @@ static int vtbl_check(const struct ubi_device *ubi, | |||
225 | /* Checks that all names are unique */ | 222 | /* Checks that all names are unique */ |
226 | for (i = 0; i < ubi->vtbl_slots - 1; i++) { | 223 | for (i = 0; i < ubi->vtbl_slots - 1; i++) { |
227 | for (n = i + 1; n < ubi->vtbl_slots; n++) { | 224 | for (n = i + 1; n < ubi->vtbl_slots; n++) { |
228 | int len1 = ubi16_to_cpu(vtbl[i].name_len); | 225 | int len1 = be16_to_cpu(vtbl[i].name_len); |
229 | int len2 = ubi16_to_cpu(vtbl[n].name_len); | 226 | int len2 = be16_to_cpu(vtbl[n].name_len); |
230 | 227 | ||
231 | if (len1 > 0 && len1 == len2 && | 228 | if (len1 > 0 && len1 == len2 && |
232 | !strncmp(vtbl[i].name, vtbl[n].name, len1)) { | 229 | !strncmp(vtbl[i].name, vtbl[n].name, len1)) { |
@@ -288,13 +285,13 @@ retry: | |||
288 | } | 285 | } |
289 | 286 | ||
290 | vid_hdr->vol_type = UBI_VID_DYNAMIC; | 287 | vid_hdr->vol_type = UBI_VID_DYNAMIC; |
291 | vid_hdr->vol_id = cpu_to_ubi32(UBI_LAYOUT_VOL_ID); | 288 | vid_hdr->vol_id = cpu_to_be32(UBI_LAYOUT_VOL_ID); |
292 | vid_hdr->compat = UBI_LAYOUT_VOLUME_COMPAT; | 289 | vid_hdr->compat = UBI_LAYOUT_VOLUME_COMPAT; |
293 | vid_hdr->data_size = vid_hdr->used_ebs = | 290 | vid_hdr->data_size = vid_hdr->used_ebs = |
294 | vid_hdr->data_pad = cpu_to_ubi32(0); | 291 | vid_hdr->data_pad = cpu_to_be32(0); |
295 | vid_hdr->lnum = cpu_to_ubi32(copy); | 292 | vid_hdr->lnum = cpu_to_be32(copy); |
296 | vid_hdr->sqnum = cpu_to_ubi64(++si->max_sqnum); | 293 | vid_hdr->sqnum = cpu_to_be64(++si->max_sqnum); |
297 | vid_hdr->leb_ver = cpu_to_ubi32(old_seb ? old_seb->leb_ver + 1: 0); | 294 | vid_hdr->leb_ver = cpu_to_be32(old_seb ? old_seb->leb_ver + 1: 0); |
298 | 295 | ||
299 | /* The EC header is already there, write the VID header */ | 296 | /* The EC header is already there, write the VID header */ |
300 | err = ubi_io_write_vid_hdr(ubi, new_seb->pnum, vid_hdr); | 297 | err = ubi_io_write_vid_hdr(ubi, new_seb->pnum, vid_hdr); |
@@ -317,14 +314,15 @@ retry: | |||
317 | return err; | 314 | return err; |
318 | 315 | ||
319 | write_error: | 316 | write_error: |
320 | kfree(new_seb); | 317 | if (err == -EIO && ++tries <= 5) { |
321 | /* May be this physical eraseblock went bad, try to pick another one */ | 318 | /* |
322 | if (++tries <= 5) { | 319 | * Probably this physical eraseblock went bad, try to pick |
323 | err = ubi_scan_add_to_list(si, new_seb->pnum, new_seb->ec, | 320 | * another one. |
324 | &si->corr); | 321 | */ |
325 | if (!err) | 322 | list_add_tail(&new_seb->u.list, &si->corr); |
326 | goto retry; | 323 | goto retry; |
327 | } | 324 | } |
325 | kfree(new_seb); | ||
328 | out_free: | 326 | out_free: |
329 | ubi_free_vid_hdr(ubi, vid_hdr); | 327 | ubi_free_vid_hdr(ubi, vid_hdr); |
330 | return err; | 328 | return err; |
@@ -380,11 +378,12 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi, | |||
380 | 378 | ||
381 | /* Read both LEB 0 and LEB 1 into memory */ | 379 | /* Read both LEB 0 and LEB 1 into memory */ |
382 | ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { | 380 | ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { |
383 | leb[seb->lnum] = kzalloc(ubi->vtbl_size, GFP_KERNEL); | 381 | leb[seb->lnum] = vmalloc(ubi->vtbl_size); |
384 | if (!leb[seb->lnum]) { | 382 | if (!leb[seb->lnum]) { |
385 | err = -ENOMEM; | 383 | err = -ENOMEM; |
386 | goto out_free; | 384 | goto out_free; |
387 | } | 385 | } |
386 | memset(leb[seb->lnum], 0, ubi->vtbl_size); | ||
388 | 387 | ||
389 | err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0, | 388 | err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0, |
390 | ubi->vtbl_size); | 389 | ubi->vtbl_size); |
@@ -415,7 +414,7 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi, | |||
415 | } | 414 | } |
416 | 415 | ||
417 | /* Both LEB 1 and LEB 2 are OK and consistent */ | 416 | /* Both LEB 1 and LEB 2 are OK and consistent */ |
418 | kfree(leb[1]); | 417 | vfree(leb[1]); |
419 | return leb[0]; | 418 | return leb[0]; |
420 | } else { | 419 | } else { |
421 | /* LEB 0 is corrupted or does not exist */ | 420 | /* LEB 0 is corrupted or does not exist */ |
@@ -436,13 +435,13 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi, | |||
436 | goto out_free; | 435 | goto out_free; |
437 | ubi_msg("volume table was restored"); | 436 | ubi_msg("volume table was restored"); |
438 | 437 | ||
439 | kfree(leb[0]); | 438 | vfree(leb[0]); |
440 | return leb[1]; | 439 | return leb[1]; |
441 | } | 440 | } |
442 | 441 | ||
443 | out_free: | 442 | out_free: |
444 | kfree(leb[0]); | 443 | vfree(leb[0]); |
445 | kfree(leb[1]); | 444 | vfree(leb[1]); |
446 | return ERR_PTR(err); | 445 | return ERR_PTR(err); |
447 | } | 446 | } |
448 | 447 | ||
@@ -460,9 +459,10 @@ static struct ubi_vtbl_record *create_empty_lvol(const struct ubi_device *ubi, | |||
460 | int i; | 459 | int i; |
461 | struct ubi_vtbl_record *vtbl; | 460 | struct ubi_vtbl_record *vtbl; |
462 | 461 | ||
463 | vtbl = kzalloc(ubi->vtbl_size, GFP_KERNEL); | 462 | vtbl = vmalloc(ubi->vtbl_size); |
464 | if (!vtbl) | 463 | if (!vtbl) |
465 | return ERR_PTR(-ENOMEM); | 464 | return ERR_PTR(-ENOMEM); |
465 | memset(vtbl, 0, ubi->vtbl_size); | ||
466 | 466 | ||
467 | for (i = 0; i < ubi->vtbl_slots; i++) | 467 | for (i = 0; i < ubi->vtbl_slots; i++) |
468 | memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE); | 468 | memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE); |
@@ -472,7 +472,7 @@ static struct ubi_vtbl_record *create_empty_lvol(const struct ubi_device *ubi, | |||
472 | 472 | ||
473 | err = create_vtbl(ubi, si, i, vtbl); | 473 | err = create_vtbl(ubi, si, i, vtbl); |
474 | if (err) { | 474 | if (err) { |
475 | kfree(vtbl); | 475 | vfree(vtbl); |
476 | return ERR_PTR(err); | 476 | return ERR_PTR(err); |
477 | } | 477 | } |
478 | } | 478 | } |
@@ -500,19 +500,19 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, | |||
500 | for (i = 0; i < ubi->vtbl_slots; i++) { | 500 | for (i = 0; i < ubi->vtbl_slots; i++) { |
501 | cond_resched(); | 501 | cond_resched(); |
502 | 502 | ||
503 | if (ubi32_to_cpu(vtbl[i].reserved_pebs) == 0) | 503 | if (be32_to_cpu(vtbl[i].reserved_pebs) == 0) |
504 | continue; /* Empty record */ | 504 | continue; /* Empty record */ |
505 | 505 | ||
506 | vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL); | 506 | vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL); |
507 | if (!vol) | 507 | if (!vol) |
508 | return -ENOMEM; | 508 | return -ENOMEM; |
509 | 509 | ||
510 | vol->reserved_pebs = ubi32_to_cpu(vtbl[i].reserved_pebs); | 510 | vol->reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs); |
511 | vol->alignment = ubi32_to_cpu(vtbl[i].alignment); | 511 | vol->alignment = be32_to_cpu(vtbl[i].alignment); |
512 | vol->data_pad = ubi32_to_cpu(vtbl[i].data_pad); | 512 | vol->data_pad = be32_to_cpu(vtbl[i].data_pad); |
513 | vol->vol_type = vtbl[i].vol_type == UBI_VID_DYNAMIC ? | 513 | vol->vol_type = vtbl[i].vol_type == UBI_VID_DYNAMIC ? |
514 | UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; | 514 | UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; |
515 | vol->name_len = ubi16_to_cpu(vtbl[i].name_len); | 515 | vol->name_len = be16_to_cpu(vtbl[i].name_len); |
516 | vol->usable_leb_size = ubi->leb_size - vol->data_pad; | 516 | vol->usable_leb_size = ubi->leb_size - vol->data_pad; |
517 | memcpy(vol->name, vtbl[i].name, vol->name_len); | 517 | memcpy(vol->name, vtbl[i].name, vol->name_len); |
518 | vol->name[vol->name_len] = '\0'; | 518 | vol->name[vol->name_len] = '\0'; |
@@ -531,7 +531,8 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, | |||
531 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { | 531 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { |
532 | vol->used_ebs = vol->reserved_pebs; | 532 | vol->used_ebs = vol->reserved_pebs; |
533 | vol->last_eb_bytes = vol->usable_leb_size; | 533 | vol->last_eb_bytes = vol->usable_leb_size; |
534 | vol->used_bytes = vol->used_ebs * vol->usable_leb_size; | 534 | vol->used_bytes = |
535 | (long long)vol->used_ebs * vol->usable_leb_size; | ||
535 | continue; | 536 | continue; |
536 | } | 537 | } |
537 | 538 | ||
@@ -561,7 +562,8 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, | |||
561 | } | 562 | } |
562 | 563 | ||
563 | vol->used_ebs = sv->used_ebs; | 564 | vol->used_ebs = sv->used_ebs; |
564 | vol->used_bytes = (vol->used_ebs - 1) * vol->usable_leb_size; | 565 | vol->used_bytes = |
566 | (long long)(vol->used_ebs - 1) * vol->usable_leb_size; | ||
565 | vol->used_bytes += sv->last_data_size; | 567 | vol->used_bytes += sv->last_data_size; |
566 | vol->last_eb_bytes = sv->last_data_size; | 568 | vol->last_eb_bytes = sv->last_data_size; |
567 | } | 569 | } |
@@ -578,7 +580,8 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, | |||
578 | vol->usable_leb_size = ubi->leb_size; | 580 | vol->usable_leb_size = ubi->leb_size; |
579 | vol->used_ebs = vol->reserved_pebs; | 581 | vol->used_ebs = vol->reserved_pebs; |
580 | vol->last_eb_bytes = vol->reserved_pebs; | 582 | vol->last_eb_bytes = vol->reserved_pebs; |
581 | vol->used_bytes = vol->used_ebs * (ubi->leb_size - vol->data_pad); | 583 | vol->used_bytes = |
584 | (long long)vol->used_ebs * (ubi->leb_size - vol->data_pad); | ||
582 | vol->vol_id = UBI_LAYOUT_VOL_ID; | 585 | vol->vol_id = UBI_LAYOUT_VOL_ID; |
583 | 586 | ||
584 | ubi_assert(!ubi->volumes[i]); | 587 | ubi_assert(!ubi->volumes[i]); |
@@ -718,7 +721,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
718 | int i, err; | 721 | int i, err; |
719 | struct ubi_scan_volume *sv; | 722 | struct ubi_scan_volume *sv; |
720 | 723 | ||
721 | empty_vtbl_record.crc = cpu_to_ubi32(0xf116c36b); | 724 | empty_vtbl_record.crc = cpu_to_be32(0xf116c36b); |
722 | 725 | ||
723 | /* | 726 | /* |
724 | * The number of supported volumes is limited by the eraseblock size | 727 | * The number of supported volumes is limited by the eraseblock size |
@@ -783,7 +786,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
783 | return 0; | 786 | return 0; |
784 | 787 | ||
785 | out_free: | 788 | out_free: |
786 | kfree(ubi->vtbl); | 789 | vfree(ubi->vtbl); |
787 | for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) | 790 | for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) |
788 | if (ubi->volumes[i]) { | 791 | if (ubi->volumes[i]) { |
789 | kfree(ubi->volumes[i]); | 792 | kfree(ubi->volumes[i]); |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index ab2174a56bc2..9de953762097 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -667,7 +667,7 @@ static int sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, int tortur | |||
667 | 667 | ||
668 | dbg_wl("erased PEB %d, new EC %llu", e->pnum, ec); | 668 | dbg_wl("erased PEB %d, new EC %llu", e->pnum, ec); |
669 | 669 | ||
670 | ec_hdr->ec = cpu_to_ubi64(ec); | 670 | ec_hdr->ec = cpu_to_be64(ec); |
671 | 671 | ||
672 | err = ubi_io_write_ec_hdr(ubi, e->pnum, ec_hdr); | 672 | err = ubi_io_write_ec_hdr(ubi, e->pnum, ec_hdr); |
673 | if (err) | 673 | if (err) |
@@ -1060,9 +1060,8 @@ out_unlock: | |||
1060 | static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | 1060 | static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, |
1061 | int cancel) | 1061 | int cancel) |
1062 | { | 1062 | { |
1063 | int err; | ||
1064 | struct ubi_wl_entry *e = wl_wrk->e; | 1063 | struct ubi_wl_entry *e = wl_wrk->e; |
1065 | int pnum = e->pnum; | 1064 | int pnum = e->pnum, err, need; |
1066 | 1065 | ||
1067 | if (cancel) { | 1066 | if (cancel) { |
1068 | dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); | 1067 | dbg_wl("cancel erasure of PEB %d EC %d", pnum, e->ec); |
@@ -1097,62 +1096,70 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk, | |||
1097 | kfree(wl_wrk); | 1096 | kfree(wl_wrk); |
1098 | kmem_cache_free(wl_entries_slab, e); | 1097 | kmem_cache_free(wl_entries_slab, e); |
1099 | 1098 | ||
1100 | if (err != -EIO) { | 1099 | if (err == -EINTR || err == -ENOMEM || err == -EAGAIN || |
1100 | err == -EBUSY) { | ||
1101 | int err1; | ||
1102 | |||
1103 | /* Re-schedule the LEB for erasure */ | ||
1104 | err1 = schedule_erase(ubi, e, 0); | ||
1105 | if (err1) { | ||
1106 | err = err1; | ||
1107 | goto out_ro; | ||
1108 | } | ||
1109 | return err; | ||
1110 | } else if (err != -EIO) { | ||
1101 | /* | 1111 | /* |
1102 | * If this is not %-EIO, we have no idea what to do. Scheduling | 1112 | * If this is not %-EIO, we have no idea what to do. Scheduling |
1103 | * this physical eraseblock for erasure again would cause | 1113 | * this physical eraseblock for erasure again would cause |
1104 | * errors again and again. Well, lets switch to RO mode. | 1114 | * errors again and again. Well, lets switch to RO mode. |
1105 | */ | 1115 | */ |
1106 | ubi_ro_mode(ubi); | 1116 | goto out_ro; |
1107 | return err; | ||
1108 | } | 1117 | } |
1109 | 1118 | ||
1110 | /* It is %-EIO, the PEB went bad */ | 1119 | /* It is %-EIO, the PEB went bad */ |
1111 | 1120 | ||
1112 | if (!ubi->bad_allowed) { | 1121 | if (!ubi->bad_allowed) { |
1113 | ubi_err("bad physical eraseblock %d detected", pnum); | 1122 | ubi_err("bad physical eraseblock %d detected", pnum); |
1114 | ubi_ro_mode(ubi); | 1123 | goto out_ro; |
1115 | err = -EIO; | 1124 | } |
1116 | } else { | ||
1117 | int need; | ||
1118 | |||
1119 | spin_lock(&ubi->volumes_lock); | ||
1120 | need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs + 1; | ||
1121 | if (need > 0) { | ||
1122 | need = ubi->avail_pebs >= need ? need : ubi->avail_pebs; | ||
1123 | ubi->avail_pebs -= need; | ||
1124 | ubi->rsvd_pebs += need; | ||
1125 | ubi->beb_rsvd_pebs += need; | ||
1126 | if (need > 0) | ||
1127 | ubi_msg("reserve more %d PEBs", need); | ||
1128 | } | ||
1129 | 1125 | ||
1130 | if (ubi->beb_rsvd_pebs == 0) { | 1126 | spin_lock(&ubi->volumes_lock); |
1131 | spin_unlock(&ubi->volumes_lock); | 1127 | need = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs + 1; |
1132 | ubi_err("no reserved physical eraseblocks"); | 1128 | if (need > 0) { |
1133 | ubi_ro_mode(ubi); | 1129 | need = ubi->avail_pebs >= need ? need : ubi->avail_pebs; |
1134 | return -EIO; | 1130 | ubi->avail_pebs -= need; |
1135 | } | 1131 | ubi->rsvd_pebs += need; |
1132 | ubi->beb_rsvd_pebs += need; | ||
1133 | if (need > 0) | ||
1134 | ubi_msg("reserve more %d PEBs", need); | ||
1135 | } | ||
1136 | 1136 | ||
1137 | if (ubi->beb_rsvd_pebs == 0) { | ||
1137 | spin_unlock(&ubi->volumes_lock); | 1138 | spin_unlock(&ubi->volumes_lock); |
1138 | ubi_msg("mark PEB %d as bad", pnum); | 1139 | ubi_err("no reserved physical eraseblocks"); |
1140 | goto out_ro; | ||
1141 | } | ||
1139 | 1142 | ||
1140 | err = ubi_io_mark_bad(ubi, pnum); | 1143 | spin_unlock(&ubi->volumes_lock); |
1141 | if (err) { | 1144 | ubi_msg("mark PEB %d as bad", pnum); |
1142 | ubi_ro_mode(ubi); | ||
1143 | return err; | ||
1144 | } | ||
1145 | 1145 | ||
1146 | spin_lock(&ubi->volumes_lock); | 1146 | err = ubi_io_mark_bad(ubi, pnum); |
1147 | ubi->beb_rsvd_pebs -= 1; | 1147 | if (err) |
1148 | ubi->bad_peb_count += 1; | 1148 | goto out_ro; |
1149 | ubi->good_peb_count -= 1; | 1149 | |
1150 | ubi_calculate_reserved(ubi); | 1150 | spin_lock(&ubi->volumes_lock); |
1151 | if (ubi->beb_rsvd_pebs == 0) | 1151 | ubi->beb_rsvd_pebs -= 1; |
1152 | ubi_warn("last PEB from the reserved pool was used"); | 1152 | ubi->bad_peb_count += 1; |
1153 | spin_unlock(&ubi->volumes_lock); | 1153 | ubi->good_peb_count -= 1; |
1154 | } | 1154 | ubi_calculate_reserved(ubi); |
1155 | if (ubi->beb_rsvd_pebs == 0) | ||
1156 | ubi_warn("last PEB from the reserved pool was used"); | ||
1157 | spin_unlock(&ubi->volumes_lock); | ||
1158 | |||
1159 | return err; | ||
1155 | 1160 | ||
1161 | out_ro: | ||
1162 | ubi_ro_mode(ubi); | ||
1156 | return err; | 1163 | return err; |
1157 | } | 1164 | } |
1158 | 1165 | ||
@@ -1634,7 +1641,7 @@ static int paranoid_check_ec(const struct ubi_device *ubi, int pnum, int ec) | |||
1634 | goto out_free; | 1641 | goto out_free; |
1635 | } | 1642 | } |
1636 | 1643 | ||
1637 | read_ec = ubi64_to_cpu(ec_hdr->ec); | 1644 | read_ec = be64_to_cpu(ec_hdr->ec); |
1638 | if (ec != read_ec) { | 1645 | if (ec != read_ec) { |
1639 | ubi_err("paranoid check failed for PEB %d", pnum); | 1646 | ubi_err("paranoid check failed for PEB %d", pnum); |
1640 | ubi_err("read EC is %lld, should be %d", read_ec, ec); | 1647 | ubi_err("read EC is %lld, should be %d", read_ec, ec); |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 43d03178064d..5fb659f8b20e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -2486,6 +2486,18 @@ source "drivers/atm/Kconfig" | |||
2486 | 2486 | ||
2487 | source "drivers/s390/net/Kconfig" | 2487 | source "drivers/s390/net/Kconfig" |
2488 | 2488 | ||
2489 | config XEN_NETDEV_FRONTEND | ||
2490 | tristate "Xen network device frontend driver" | ||
2491 | depends on XEN | ||
2492 | default y | ||
2493 | help | ||
2494 | The network device frontend driver allows the kernel to | ||
2495 | access network devices exported exported by a virtual | ||
2496 | machine containing a physical network device driver. The | ||
2497 | frontend driver is intended for unprivileged guest domains; | ||
2498 | if you are compiling a kernel for a Xen guest, you almost | ||
2499 | certainly want to enable this. | ||
2500 | |||
2489 | config ISERIES_VETH | 2501 | config ISERIES_VETH |
2490 | tristate "iSeries Virtual Ethernet driver support" | 2502 | tristate "iSeries Virtual Ethernet driver support" |
2491 | depends on PPC_ISERIES | 2503 | depends on PPC_ISERIES |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index eb4167622a6a..0e286ab8855a 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -127,6 +127,8 @@ obj-$(CONFIG_PPPOL2TP) += pppox.o pppol2tp.o | |||
127 | obj-$(CONFIG_SLIP) += slip.o | 127 | obj-$(CONFIG_SLIP) += slip.o |
128 | obj-$(CONFIG_SLHC) += slhc.o | 128 | obj-$(CONFIG_SLHC) += slhc.o |
129 | 129 | ||
130 | obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o | ||
131 | |||
130 | obj-$(CONFIG_DUMMY) += dummy.o | 132 | obj-$(CONFIG_DUMMY) += dummy.o |
131 | obj-$(CONFIG_IFB) += ifb.o | 133 | obj-$(CONFIG_IFB) += ifb.o |
132 | obj-$(CONFIG_MACVLAN) += macvlan.o | 134 | obj-$(CONFIG_MACVLAN) += macvlan.o |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index d23861c8658c..a729da061bbb 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -54,8 +54,8 @@ | |||
54 | 54 | ||
55 | #define DRV_MODULE_NAME "bnx2" | 55 | #define DRV_MODULE_NAME "bnx2" |
56 | #define PFX DRV_MODULE_NAME ": " | 56 | #define PFX DRV_MODULE_NAME ": " |
57 | #define DRV_MODULE_VERSION "1.6.2" | 57 | #define DRV_MODULE_VERSION "1.6.3" |
58 | #define DRV_MODULE_RELDATE "July 6, 2007" | 58 | #define DRV_MODULE_RELDATE "July 16, 2007" |
59 | 59 | ||
60 | #define RUN_AT(x) (jiffies + (x)) | 60 | #define RUN_AT(x) (jiffies + (x)) |
61 | 61 | ||
@@ -126,91 +126,102 @@ static struct pci_device_id bnx2_pci_tbl[] = { | |||
126 | 126 | ||
127 | static struct flash_spec flash_table[] = | 127 | static struct flash_spec flash_table[] = |
128 | { | 128 | { |
129 | #define BUFFERED_FLAGS (BNX2_NV_BUFFERED | BNX2_NV_TRANSLATE) | ||
130 | #define NONBUFFERED_FLAGS (BNX2_NV_WREN) | ||
129 | /* Slow EEPROM */ | 131 | /* Slow EEPROM */ |
130 | {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400, | 132 | {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400, |
131 | 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, | 133 | BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, |
132 | SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, | 134 | SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, |
133 | "EEPROM - slow"}, | 135 | "EEPROM - slow"}, |
134 | /* Expansion entry 0001 */ | 136 | /* Expansion entry 0001 */ |
135 | {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406, | 137 | {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406, |
136 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 138 | NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
137 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, | 139 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, |
138 | "Entry 0001"}, | 140 | "Entry 0001"}, |
139 | /* Saifun SA25F010 (non-buffered flash) */ | 141 | /* Saifun SA25F010 (non-buffered flash) */ |
140 | /* strap, cfg1, & write1 need updates */ | 142 | /* strap, cfg1, & write1 need updates */ |
141 | {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406, | 143 | {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406, |
142 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 144 | NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
143 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2, | 145 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2, |
144 | "Non-buffered flash (128kB)"}, | 146 | "Non-buffered flash (128kB)"}, |
145 | /* Saifun SA25F020 (non-buffered flash) */ | 147 | /* Saifun SA25F020 (non-buffered flash) */ |
146 | /* strap, cfg1, & write1 need updates */ | 148 | /* strap, cfg1, & write1 need updates */ |
147 | {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406, | 149 | {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406, |
148 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 150 | NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
149 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4, | 151 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4, |
150 | "Non-buffered flash (256kB)"}, | 152 | "Non-buffered flash (256kB)"}, |
151 | /* Expansion entry 0100 */ | 153 | /* Expansion entry 0100 */ |
152 | {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406, | 154 | {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406, |
153 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 155 | NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
154 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, | 156 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, |
155 | "Entry 0100"}, | 157 | "Entry 0100"}, |
156 | /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */ | 158 | /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */ |
157 | {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406, | 159 | {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406, |
158 | 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, | 160 | NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, |
159 | ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2, | 161 | ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2, |
160 | "Entry 0101: ST M45PE10 (128kB non-bufferred)"}, | 162 | "Entry 0101: ST M45PE10 (128kB non-bufferred)"}, |
161 | /* Entry 0110: ST M45PE20 (non-buffered flash)*/ | 163 | /* Entry 0110: ST M45PE20 (non-buffered flash)*/ |
162 | {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406, | 164 | {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406, |
163 | 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, | 165 | NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, |
164 | ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4, | 166 | ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4, |
165 | "Entry 0110: ST M45PE20 (256kB non-bufferred)"}, | 167 | "Entry 0110: ST M45PE20 (256kB non-bufferred)"}, |
166 | /* Saifun SA25F005 (non-buffered flash) */ | 168 | /* Saifun SA25F005 (non-buffered flash) */ |
167 | /* strap, cfg1, & write1 need updates */ | 169 | /* strap, cfg1, & write1 need updates */ |
168 | {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406, | 170 | {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406, |
169 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 171 | NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
170 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE, | 172 | SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE, |
171 | "Non-buffered flash (64kB)"}, | 173 | "Non-buffered flash (64kB)"}, |
172 | /* Fast EEPROM */ | 174 | /* Fast EEPROM */ |
173 | {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400, | 175 | {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400, |
174 | 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, | 176 | BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, |
175 | SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, | 177 | SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, |
176 | "EEPROM - fast"}, | 178 | "EEPROM - fast"}, |
177 | /* Expansion entry 1001 */ | 179 | /* Expansion entry 1001 */ |
178 | {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406, | 180 | {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406, |
179 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 181 | NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
180 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, | 182 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, |
181 | "Entry 1001"}, | 183 | "Entry 1001"}, |
182 | /* Expansion entry 1010 */ | 184 | /* Expansion entry 1010 */ |
183 | {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406, | 185 | {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406, |
184 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 186 | NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
185 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, | 187 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, |
186 | "Entry 1010"}, | 188 | "Entry 1010"}, |
187 | /* ATMEL AT45DB011B (buffered flash) */ | 189 | /* ATMEL AT45DB011B (buffered flash) */ |
188 | {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400, | 190 | {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400, |
189 | 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, | 191 | BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, |
190 | BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE, | 192 | BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE, |
191 | "Buffered flash (128kB)"}, | 193 | "Buffered flash (128kB)"}, |
192 | /* Expansion entry 1100 */ | 194 | /* Expansion entry 1100 */ |
193 | {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406, | 195 | {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406, |
194 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 196 | NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
195 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, | 197 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, |
196 | "Entry 1100"}, | 198 | "Entry 1100"}, |
197 | /* Expansion entry 1101 */ | 199 | /* Expansion entry 1101 */ |
198 | {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406, | 200 | {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406, |
199 | 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, | 201 | NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, |
200 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, | 202 | SAIFUN_FLASH_BYTE_ADDR_MASK, 0, |
201 | "Entry 1101"}, | 203 | "Entry 1101"}, |
202 | /* Ateml Expansion entry 1110 */ | 204 | /* Ateml Expansion entry 1110 */ |
203 | {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400, | 205 | {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400, |
204 | 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, | 206 | BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, |
205 | BUFFERED_FLASH_BYTE_ADDR_MASK, 0, | 207 | BUFFERED_FLASH_BYTE_ADDR_MASK, 0, |
206 | "Entry 1110 (Atmel)"}, | 208 | "Entry 1110 (Atmel)"}, |
207 | /* ATMEL AT45DB021B (buffered flash) */ | 209 | /* ATMEL AT45DB021B (buffered flash) */ |
208 | {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400, | 210 | {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400, |
209 | 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, | 211 | BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, |
210 | BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2, | 212 | BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2, |
211 | "Buffered flash (256kB)"}, | 213 | "Buffered flash (256kB)"}, |
212 | }; | 214 | }; |
213 | 215 | ||
216 | static struct flash_spec flash_5709 = { | ||
217 | .flags = BNX2_NV_BUFFERED, | ||
218 | .page_bits = BCM5709_FLASH_PAGE_BITS, | ||
219 | .page_size = BCM5709_FLASH_PAGE_SIZE, | ||
220 | .addr_mask = BCM5709_FLASH_BYTE_ADDR_MASK, | ||
221 | .total_size = BUFFERED_FLASH_TOTAL_SIZE*2, | ||
222 | .name = "5709 Buffered flash (256kB)", | ||
223 | }; | ||
224 | |||
214 | MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); | 225 | MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); |
215 | 226 | ||
216 | static inline u32 bnx2_tx_avail(struct bnx2 *bp) | 227 | static inline u32 bnx2_tx_avail(struct bnx2 *bp) |
@@ -3289,7 +3300,7 @@ bnx2_enable_nvram_write(struct bnx2 *bp) | |||
3289 | val = REG_RD(bp, BNX2_MISC_CFG); | 3300 | val = REG_RD(bp, BNX2_MISC_CFG); |
3290 | REG_WR(bp, BNX2_MISC_CFG, val | BNX2_MISC_CFG_NVM_WR_EN_PCI); | 3301 | REG_WR(bp, BNX2_MISC_CFG, val | BNX2_MISC_CFG_NVM_WR_EN_PCI); |
3291 | 3302 | ||
3292 | if (!bp->flash_info->buffered) { | 3303 | if (bp->flash_info->flags & BNX2_NV_WREN) { |
3293 | int j; | 3304 | int j; |
3294 | 3305 | ||
3295 | REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE); | 3306 | REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE); |
@@ -3349,7 +3360,7 @@ bnx2_nvram_erase_page(struct bnx2 *bp, u32 offset) | |||
3349 | u32 cmd; | 3360 | u32 cmd; |
3350 | int j; | 3361 | int j; |
3351 | 3362 | ||
3352 | if (bp->flash_info->buffered) | 3363 | if (bp->flash_info->flags & BNX2_NV_BUFFERED) |
3353 | /* Buffered flash, no erase needed */ | 3364 | /* Buffered flash, no erase needed */ |
3354 | return 0; | 3365 | return 0; |
3355 | 3366 | ||
@@ -3392,8 +3403,8 @@ bnx2_nvram_read_dword(struct bnx2 *bp, u32 offset, u8 *ret_val, u32 cmd_flags) | |||
3392 | /* Build the command word. */ | 3403 | /* Build the command word. */ |
3393 | cmd = BNX2_NVM_COMMAND_DOIT | cmd_flags; | 3404 | cmd = BNX2_NVM_COMMAND_DOIT | cmd_flags; |
3394 | 3405 | ||
3395 | /* Calculate an offset of a buffered flash. */ | 3406 | /* Calculate an offset of a buffered flash, not needed for 5709. */ |
3396 | if (bp->flash_info->buffered) { | 3407 | if (bp->flash_info->flags & BNX2_NV_TRANSLATE) { |
3397 | offset = ((offset / bp->flash_info->page_size) << | 3408 | offset = ((offset / bp->flash_info->page_size) << |
3398 | bp->flash_info->page_bits) + | 3409 | bp->flash_info->page_bits) + |
3399 | (offset % bp->flash_info->page_size); | 3410 | (offset % bp->flash_info->page_size); |
@@ -3439,8 +3450,8 @@ bnx2_nvram_write_dword(struct bnx2 *bp, u32 offset, u8 *val, u32 cmd_flags) | |||
3439 | /* Build the command word. */ | 3450 | /* Build the command word. */ |
3440 | cmd = BNX2_NVM_COMMAND_DOIT | BNX2_NVM_COMMAND_WR | cmd_flags; | 3451 | cmd = BNX2_NVM_COMMAND_DOIT | BNX2_NVM_COMMAND_WR | cmd_flags; |
3441 | 3452 | ||
3442 | /* Calculate an offset of a buffered flash. */ | 3453 | /* Calculate an offset of a buffered flash, not needed for 5709. */ |
3443 | if (bp->flash_info->buffered) { | 3454 | if (bp->flash_info->flags & BNX2_NV_TRANSLATE) { |
3444 | offset = ((offset / bp->flash_info->page_size) << | 3455 | offset = ((offset / bp->flash_info->page_size) << |
3445 | bp->flash_info->page_bits) + | 3456 | bp->flash_info->page_bits) + |
3446 | (offset % bp->flash_info->page_size); | 3457 | (offset % bp->flash_info->page_size); |
@@ -3478,15 +3489,19 @@ static int | |||
3478 | bnx2_init_nvram(struct bnx2 *bp) | 3489 | bnx2_init_nvram(struct bnx2 *bp) |
3479 | { | 3490 | { |
3480 | u32 val; | 3491 | u32 val; |
3481 | int j, entry_count, rc; | 3492 | int j, entry_count, rc = 0; |
3482 | struct flash_spec *flash; | 3493 | struct flash_spec *flash; |
3483 | 3494 | ||
3495 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { | ||
3496 | bp->flash_info = &flash_5709; | ||
3497 | goto get_flash_size; | ||
3498 | } | ||
3499 | |||
3484 | /* Determine the selected interface. */ | 3500 | /* Determine the selected interface. */ |
3485 | val = REG_RD(bp, BNX2_NVM_CFG1); | 3501 | val = REG_RD(bp, BNX2_NVM_CFG1); |
3486 | 3502 | ||
3487 | entry_count = sizeof(flash_table) / sizeof(struct flash_spec); | 3503 | entry_count = sizeof(flash_table) / sizeof(struct flash_spec); |
3488 | 3504 | ||
3489 | rc = 0; | ||
3490 | if (val & 0x40000000) { | 3505 | if (val & 0x40000000) { |
3491 | 3506 | ||
3492 | /* Flash interface has been reconfigured */ | 3507 | /* Flash interface has been reconfigured */ |
@@ -3542,6 +3557,7 @@ bnx2_init_nvram(struct bnx2 *bp) | |||
3542 | return -ENODEV; | 3557 | return -ENODEV; |
3543 | } | 3558 | } |
3544 | 3559 | ||
3560 | get_flash_size: | ||
3545 | val = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG2); | 3561 | val = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG2); |
3546 | val &= BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK; | 3562 | val &= BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK; |
3547 | if (val) | 3563 | if (val) |
@@ -3706,7 +3722,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, | |||
3706 | buf = align_buf; | 3722 | buf = align_buf; |
3707 | } | 3723 | } |
3708 | 3724 | ||
3709 | if (bp->flash_info->buffered == 0) { | 3725 | if (!(bp->flash_info->flags & BNX2_NV_BUFFERED)) { |
3710 | flash_buffer = kmalloc(264, GFP_KERNEL); | 3726 | flash_buffer = kmalloc(264, GFP_KERNEL); |
3711 | if (flash_buffer == NULL) { | 3727 | if (flash_buffer == NULL) { |
3712 | rc = -ENOMEM; | 3728 | rc = -ENOMEM; |
@@ -3739,7 +3755,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, | |||
3739 | bnx2_enable_nvram_access(bp); | 3755 | bnx2_enable_nvram_access(bp); |
3740 | 3756 | ||
3741 | cmd_flags = BNX2_NVM_COMMAND_FIRST; | 3757 | cmd_flags = BNX2_NVM_COMMAND_FIRST; |
3742 | if (bp->flash_info->buffered == 0) { | 3758 | if (!(bp->flash_info->flags & BNX2_NV_BUFFERED)) { |
3743 | int j; | 3759 | int j; |
3744 | 3760 | ||
3745 | /* Read the whole page into the buffer | 3761 | /* Read the whole page into the buffer |
@@ -3767,7 +3783,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, | |||
3767 | /* Loop to write back the buffer data from page_start to | 3783 | /* Loop to write back the buffer data from page_start to |
3768 | * data_start */ | 3784 | * data_start */ |
3769 | i = 0; | 3785 | i = 0; |
3770 | if (bp->flash_info->buffered == 0) { | 3786 | if (!(bp->flash_info->flags & BNX2_NV_BUFFERED)) { |
3771 | /* Erase the page */ | 3787 | /* Erase the page */ |
3772 | if ((rc = bnx2_nvram_erase_page(bp, page_start)) != 0) | 3788 | if ((rc = bnx2_nvram_erase_page(bp, page_start)) != 0) |
3773 | goto nvram_write_end; | 3789 | goto nvram_write_end; |
@@ -3791,7 +3807,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, | |||
3791 | /* Loop to write the new data from data_start to data_end */ | 3807 | /* Loop to write the new data from data_start to data_end */ |
3792 | for (addr = data_start; addr < data_end; addr += 4, i += 4) { | 3808 | for (addr = data_start; addr < data_end; addr += 4, i += 4) { |
3793 | if ((addr == page_end - 4) || | 3809 | if ((addr == page_end - 4) || |
3794 | ((bp->flash_info->buffered) && | 3810 | ((bp->flash_info->flags & BNX2_NV_BUFFERED) && |
3795 | (addr == data_end - 4))) { | 3811 | (addr == data_end - 4))) { |
3796 | 3812 | ||
3797 | cmd_flags |= BNX2_NVM_COMMAND_LAST; | 3813 | cmd_flags |= BNX2_NVM_COMMAND_LAST; |
@@ -3808,7 +3824,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, | |||
3808 | 3824 | ||
3809 | /* Loop to write back the buffer data from data_end | 3825 | /* Loop to write back the buffer data from data_end |
3810 | * to page_end */ | 3826 | * to page_end */ |
3811 | if (bp->flash_info->buffered == 0) { | 3827 | if (!(bp->flash_info->flags & BNX2_NV_BUFFERED)) { |
3812 | for (addr = data_end; addr < page_end; | 3828 | for (addr = data_end; addr < page_end; |
3813 | addr += 4, i += 4) { | 3829 | addr += 4, i += 4) { |
3814 | 3830 | ||
@@ -4107,7 +4123,7 @@ bnx2_init_chip(struct bnx2 *bp) | |||
4107 | if (CHIP_NUM(bp) == CHIP_NUM_5708) | 4123 | if (CHIP_NUM(bp) == CHIP_NUM_5708) |
4108 | REG_WR(bp, BNX2_HC_STATS_TICKS, 0); | 4124 | REG_WR(bp, BNX2_HC_STATS_TICKS, 0); |
4109 | else | 4125 | else |
4110 | REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00); | 4126 | REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks); |
4111 | REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ | 4127 | REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ |
4112 | 4128 | ||
4113 | if (CHIP_ID(bp) == CHIP_ID_5706_A1) | 4129 | if (CHIP_ID(bp) == CHIP_ID_5706_A1) |
@@ -4127,10 +4143,6 @@ bnx2_init_chip(struct bnx2 *bp) | |||
4127 | 4143 | ||
4128 | REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_EVENTS); | 4144 | REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_EVENTS); |
4129 | 4145 | ||
4130 | if (REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_FEATURE) & | ||
4131 | BNX2_PORT_FEATURE_ASF_ENABLED) | ||
4132 | bp->flags |= ASF_ENABLE_FLAG; | ||
4133 | |||
4134 | /* Initialize the receive filter. */ | 4146 | /* Initialize the receive filter. */ |
4135 | bnx2_set_rx_mode(bp->dev); | 4147 | bnx2_set_rx_mode(bp->dev); |
4136 | 4148 | ||
@@ -5786,8 +5798,9 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal) | |||
5786 | if (bp->stats_ticks != 0 && bp->stats_ticks != USEC_PER_SEC) | 5798 | if (bp->stats_ticks != 0 && bp->stats_ticks != USEC_PER_SEC) |
5787 | bp->stats_ticks = USEC_PER_SEC; | 5799 | bp->stats_ticks = USEC_PER_SEC; |
5788 | } | 5800 | } |
5789 | if (bp->stats_ticks > 0xffff00) bp->stats_ticks = 0xffff00; | 5801 | if (bp->stats_ticks > BNX2_HC_STATS_TICKS_HC_STAT_TICKS) |
5790 | bp->stats_ticks &= 0xffff00; | 5802 | bp->stats_ticks = BNX2_HC_STATS_TICKS_HC_STAT_TICKS; |
5803 | bp->stats_ticks &= BNX2_HC_STATS_TICKS_HC_STAT_TICKS; | ||
5791 | 5804 | ||
5792 | if (netif_running(bp->dev)) { | 5805 | if (netif_running(bp->dev)) { |
5793 | bnx2_netif_stop(bp); | 5806 | bnx2_netif_stop(bp); |
@@ -6629,6 +6642,18 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
6629 | if (i != 2) | 6642 | if (i != 2) |
6630 | bp->fw_version[j++] = '.'; | 6643 | bp->fw_version[j++] = '.'; |
6631 | } | 6644 | } |
6645 | if (REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_FEATURE) & | ||
6646 | BNX2_PORT_FEATURE_ASF_ENABLED) { | ||
6647 | bp->flags |= ASF_ENABLE_FLAG; | ||
6648 | |||
6649 | for (i = 0; i < 30; i++) { | ||
6650 | reg = REG_RD_IND(bp, bp->shmem_base + | ||
6651 | BNX2_BC_STATE_CONDITION); | ||
6652 | if (reg & BNX2_CONDITION_MFW_RUN_MASK) | ||
6653 | break; | ||
6654 | msleep(10); | ||
6655 | } | ||
6656 | } | ||
6632 | reg = REG_RD_IND(bp, bp->shmem_base + BNX2_BC_STATE_CONDITION); | 6657 | reg = REG_RD_IND(bp, bp->shmem_base + BNX2_BC_STATE_CONDITION); |
6633 | reg &= BNX2_CONDITION_MFW_RUN_MASK; | 6658 | reg &= BNX2_CONDITION_MFW_RUN_MASK; |
6634 | if (reg != BNX2_CONDITION_MFW_RUN_UNKNOWN && | 6659 | if (reg != BNX2_CONDITION_MFW_RUN_UNKNOWN && |
@@ -6672,7 +6697,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
6672 | bp->rx_ticks_int = 18; | 6697 | bp->rx_ticks_int = 18; |
6673 | bp->rx_ticks = 18; | 6698 | bp->rx_ticks = 18; |
6674 | 6699 | ||
6675 | bp->stats_ticks = 1000000 & 0xffff00; | 6700 | bp->stats_ticks = USEC_PER_SEC & BNX2_HC_STATS_TICKS_HC_STAT_TICKS; |
6676 | 6701 | ||
6677 | bp->timer_interval = HZ; | 6702 | bp->timer_interval = HZ; |
6678 | bp->current_interval = HZ; | 6703 | bp->current_interval = HZ; |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index d8cd1afeb23d..102adfe1e923 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
@@ -6433,6 +6433,11 @@ struct sw_bd { | |||
6433 | #define ST_MICRO_FLASH_PAGE_SIZE 256 | 6433 | #define ST_MICRO_FLASH_PAGE_SIZE 256 |
6434 | #define ST_MICRO_FLASH_BASE_TOTAL_SIZE 65536 | 6434 | #define ST_MICRO_FLASH_BASE_TOTAL_SIZE 65536 |
6435 | 6435 | ||
6436 | #define BCM5709_FLASH_PAGE_BITS 8 | ||
6437 | #define BCM5709_FLASH_PHY_PAGE_SIZE (1 << BCM5709_FLASH_PAGE_BITS) | ||
6438 | #define BCM5709_FLASH_BYTE_ADDR_MASK (BCM5709_FLASH_PHY_PAGE_SIZE-1) | ||
6439 | #define BCM5709_FLASH_PAGE_SIZE 256 | ||
6440 | |||
6436 | #define NVRAM_TIMEOUT_COUNT 30000 | 6441 | #define NVRAM_TIMEOUT_COUNT 30000 |
6437 | 6442 | ||
6438 | 6443 | ||
@@ -6449,7 +6454,10 @@ struct flash_spec { | |||
6449 | u32 config2; | 6454 | u32 config2; |
6450 | u32 config3; | 6455 | u32 config3; |
6451 | u32 write1; | 6456 | u32 write1; |
6452 | u32 buffered; | 6457 | u32 flags; |
6458 | #define BNX2_NV_BUFFERED 0x00000001 | ||
6459 | #define BNX2_NV_TRANSLATE 0x00000002 | ||
6460 | #define BNX2_NV_WREN 0x00000004 | ||
6453 | u32 page_bits; | 6461 | u32 page_bits; |
6454 | u32 page_size; | 6462 | u32 page_size; |
6455 | u32 addr_mask; | 6463 | u32 addr_mask; |
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 84aa2117c0ee..355c6cf3d112 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -320,7 +320,7 @@ static int eppconfig(struct baycom_state *bc) | |||
320 | sprintf(portarg, "%ld", bc->pdev->port->base); | 320 | sprintf(portarg, "%ld", bc->pdev->port->base); |
321 | printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg); | 321 | printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg); |
322 | 322 | ||
323 | return call_usermodehelper(eppconfig_path, argv, envp, 1); | 323 | return call_usermodehelper(eppconfig_path, argv, envp, UMH_WAIT_PROC); |
324 | } | 324 | } |
325 | 325 | ||
326 | /* ---------------------------------------------------------------------- */ | 326 | /* ---------------------------------------------------------------------- */ |
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 5891a0fbdc8b..f87176055d0e 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c | |||
@@ -824,6 +824,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
824 | struct pppol2tp_session *session; | 824 | struct pppol2tp_session *session; |
825 | struct pppol2tp_tunnel *tunnel; | 825 | struct pppol2tp_tunnel *tunnel; |
826 | struct udphdr *uh; | 826 | struct udphdr *uh; |
827 | unsigned int len; | ||
827 | 828 | ||
828 | error = -ENOTCONN; | 829 | error = -ENOTCONN; |
829 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) | 830 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) |
@@ -912,14 +913,15 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
912 | } | 913 | } |
913 | 914 | ||
914 | /* Queue the packet to IP for output */ | 915 | /* Queue the packet to IP for output */ |
916 | len = skb->len; | ||
915 | error = ip_queue_xmit(skb, 1); | 917 | error = ip_queue_xmit(skb, 1); |
916 | 918 | ||
917 | /* Update stats */ | 919 | /* Update stats */ |
918 | if (error >= 0) { | 920 | if (error >= 0) { |
919 | tunnel->stats.tx_packets++; | 921 | tunnel->stats.tx_packets++; |
920 | tunnel->stats.tx_bytes += skb->len; | 922 | tunnel->stats.tx_bytes += len; |
921 | session->stats.tx_packets++; | 923 | session->stats.tx_packets++; |
922 | session->stats.tx_bytes += skb->len; | 924 | session->stats.tx_bytes += len; |
923 | } else { | 925 | } else { |
924 | tunnel->stats.tx_errors++; | 926 | tunnel->stats.tx_errors++; |
925 | session->stats.tx_errors++; | 927 | session->stats.tx_errors++; |
@@ -958,6 +960,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
958 | __wsum csum = 0; | 960 | __wsum csum = 0; |
959 | struct sk_buff *skb2 = NULL; | 961 | struct sk_buff *skb2 = NULL; |
960 | struct udphdr *uh; | 962 | struct udphdr *uh; |
963 | unsigned int len; | ||
961 | 964 | ||
962 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) | 965 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) |
963 | goto abort; | 966 | goto abort; |
@@ -1046,18 +1049,25 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1046 | printk("\n"); | 1049 | printk("\n"); |
1047 | } | 1050 | } |
1048 | 1051 | ||
1052 | memset(&(IPCB(skb2)->opt), 0, sizeof(IPCB(skb2)->opt)); | ||
1053 | IPCB(skb2)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | | ||
1054 | IPSKB_REROUTED); | ||
1055 | nf_reset(skb2); | ||
1056 | |||
1049 | /* Get routing info from the tunnel socket */ | 1057 | /* Get routing info from the tunnel socket */ |
1058 | dst_release(skb2->dst); | ||
1050 | skb2->dst = sk_dst_get(sk_tun); | 1059 | skb2->dst = sk_dst_get(sk_tun); |
1051 | 1060 | ||
1052 | /* Queue the packet to IP for output */ | 1061 | /* Queue the packet to IP for output */ |
1062 | len = skb2->len; | ||
1053 | rc = ip_queue_xmit(skb2, 1); | 1063 | rc = ip_queue_xmit(skb2, 1); |
1054 | 1064 | ||
1055 | /* Update stats */ | 1065 | /* Update stats */ |
1056 | if (rc >= 0) { | 1066 | if (rc >= 0) { |
1057 | tunnel->stats.tx_packets++; | 1067 | tunnel->stats.tx_packets++; |
1058 | tunnel->stats.tx_bytes += skb2->len; | 1068 | tunnel->stats.tx_bytes += len; |
1059 | session->stats.tx_packets++; | 1069 | session->stats.tx_packets++; |
1060 | session->stats.tx_bytes += skb2->len; | 1070 | session->stats.tx_bytes += len; |
1061 | } else { | 1071 | } else { |
1062 | tunnel->stats.tx_errors++; | 1072 | tunnel->stats.tx_errors++; |
1063 | session->stats.tx_errors++; | 1073 | session->stats.tx_errors++; |
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c index 8a667c13faef..b801e3b3a11a 100644 --- a/drivers/net/sunvnet.c +++ b/drivers/net/sunvnet.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
13 | #include <linux/ethtool.h> | 13 | #include <linux/ethtool.h> |
14 | #include <linux/etherdevice.h> | 14 | #include <linux/etherdevice.h> |
15 | #include <linux/mutex.h> | ||
15 | 16 | ||
16 | #include <asm/vio.h> | 17 | #include <asm/vio.h> |
17 | #include <asm/ldc.h> | 18 | #include <asm/ldc.h> |
@@ -497,6 +498,8 @@ static void vnet_event(void *arg, int event) | |||
497 | vio_link_state_change(vio, event); | 498 | vio_link_state_change(vio, event); |
498 | spin_unlock_irqrestore(&vio->lock, flags); | 499 | spin_unlock_irqrestore(&vio->lock, flags); |
499 | 500 | ||
501 | if (event == LDC_EVENT_RESET) | ||
502 | vio_port_up(vio); | ||
500 | return; | 503 | return; |
501 | } | 504 | } |
502 | 505 | ||
@@ -875,6 +878,115 @@ err_out: | |||
875 | return err; | 878 | return err; |
876 | } | 879 | } |
877 | 880 | ||
881 | static LIST_HEAD(vnet_list); | ||
882 | static DEFINE_MUTEX(vnet_list_mutex); | ||
883 | |||
884 | static struct vnet * __devinit vnet_new(const u64 *local_mac) | ||
885 | { | ||
886 | struct net_device *dev; | ||
887 | struct vnet *vp; | ||
888 | int err, i; | ||
889 | |||
890 | dev = alloc_etherdev(sizeof(*vp)); | ||
891 | if (!dev) { | ||
892 | printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); | ||
893 | return ERR_PTR(-ENOMEM); | ||
894 | } | ||
895 | |||
896 | for (i = 0; i < ETH_ALEN; i++) | ||
897 | dev->dev_addr[i] = (*local_mac >> (5 - i) * 8) & 0xff; | ||
898 | |||
899 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | ||
900 | |||
901 | vp = netdev_priv(dev); | ||
902 | |||
903 | spin_lock_init(&vp->lock); | ||
904 | vp->dev = dev; | ||
905 | |||
906 | INIT_LIST_HEAD(&vp->port_list); | ||
907 | for (i = 0; i < VNET_PORT_HASH_SIZE; i++) | ||
908 | INIT_HLIST_HEAD(&vp->port_hash[i]); | ||
909 | INIT_LIST_HEAD(&vp->list); | ||
910 | vp->local_mac = *local_mac; | ||
911 | |||
912 | dev->open = vnet_open; | ||
913 | dev->stop = vnet_close; | ||
914 | dev->set_multicast_list = vnet_set_rx_mode; | ||
915 | dev->set_mac_address = vnet_set_mac_addr; | ||
916 | dev->tx_timeout = vnet_tx_timeout; | ||
917 | dev->ethtool_ops = &vnet_ethtool_ops; | ||
918 | dev->watchdog_timeo = VNET_TX_TIMEOUT; | ||
919 | dev->change_mtu = vnet_change_mtu; | ||
920 | dev->hard_start_xmit = vnet_start_xmit; | ||
921 | |||
922 | err = register_netdev(dev); | ||
923 | if (err) { | ||
924 | printk(KERN_ERR PFX "Cannot register net device, " | ||
925 | "aborting.\n"); | ||
926 | goto err_out_free_dev; | ||
927 | } | ||
928 | |||
929 | printk(KERN_INFO "%s: Sun LDOM vnet ", dev->name); | ||
930 | |||
931 | for (i = 0; i < 6; i++) | ||
932 | printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); | ||
933 | |||
934 | list_add(&vp->list, &vnet_list); | ||
935 | |||
936 | return vp; | ||
937 | |||
938 | err_out_free_dev: | ||
939 | free_netdev(dev); | ||
940 | |||
941 | return ERR_PTR(err); | ||
942 | } | ||
943 | |||
944 | static struct vnet * __devinit vnet_find_or_create(const u64 *local_mac) | ||
945 | { | ||
946 | struct vnet *iter, *vp; | ||
947 | |||
948 | mutex_lock(&vnet_list_mutex); | ||
949 | vp = NULL; | ||
950 | list_for_each_entry(iter, &vnet_list, list) { | ||
951 | if (iter->local_mac == *local_mac) { | ||
952 | vp = iter; | ||
953 | break; | ||
954 | } | ||
955 | } | ||
956 | if (!vp) | ||
957 | vp = vnet_new(local_mac); | ||
958 | mutex_unlock(&vnet_list_mutex); | ||
959 | |||
960 | return vp; | ||
961 | } | ||
962 | |||
963 | static const char *local_mac_prop = "local-mac-address"; | ||
964 | |||
965 | static struct vnet * __devinit vnet_find_parent(struct mdesc_handle *hp, | ||
966 | u64 port_node) | ||
967 | { | ||
968 | const u64 *local_mac = NULL; | ||
969 | u64 a; | ||
970 | |||
971 | mdesc_for_each_arc(a, hp, port_node, MDESC_ARC_TYPE_BACK) { | ||
972 | u64 target = mdesc_arc_target(hp, a); | ||
973 | const char *name; | ||
974 | |||
975 | name = mdesc_get_property(hp, target, "name", NULL); | ||
976 | if (!name || strcmp(name, "network")) | ||
977 | continue; | ||
978 | |||
979 | local_mac = mdesc_get_property(hp, target, | ||
980 | local_mac_prop, NULL); | ||
981 | if (local_mac) | ||
982 | break; | ||
983 | } | ||
984 | if (!local_mac) | ||
985 | return ERR_PTR(-ENODEV); | ||
986 | |||
987 | return vnet_find_or_create(local_mac); | ||
988 | } | ||
989 | |||
878 | static struct ldc_channel_config vnet_ldc_cfg = { | 990 | static struct ldc_channel_config vnet_ldc_cfg = { |
879 | .event = vnet_event, | 991 | .event = vnet_event, |
880 | .mtu = 64, | 992 | .mtu = 64, |
@@ -887,6 +999,14 @@ static struct vio_driver_ops vnet_vio_ops = { | |||
887 | .handshake_complete = vnet_handshake_complete, | 999 | .handshake_complete = vnet_handshake_complete, |
888 | }; | 1000 | }; |
889 | 1001 | ||
1002 | static void print_version(void) | ||
1003 | { | ||
1004 | static int version_printed; | ||
1005 | |||
1006 | if (version_printed++ == 0) | ||
1007 | printk(KERN_INFO "%s", version); | ||
1008 | } | ||
1009 | |||
890 | const char *remote_macaddr_prop = "remote-mac-address"; | 1010 | const char *remote_macaddr_prop = "remote-mac-address"; |
891 | 1011 | ||
892 | static int __devinit vnet_port_probe(struct vio_dev *vdev, | 1012 | static int __devinit vnet_port_probe(struct vio_dev *vdev, |
@@ -899,14 +1019,17 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev, | |||
899 | const u64 *rmac; | 1019 | const u64 *rmac; |
900 | int len, i, err, switch_port; | 1020 | int len, i, err, switch_port; |
901 | 1021 | ||
902 | vp = dev_get_drvdata(vdev->dev.parent); | 1022 | print_version(); |
903 | if (!vp) { | ||
904 | printk(KERN_ERR PFX "Cannot find port parent vnet.\n"); | ||
905 | return -ENODEV; | ||
906 | } | ||
907 | 1023 | ||
908 | hp = mdesc_grab(); | 1024 | hp = mdesc_grab(); |
909 | 1025 | ||
1026 | vp = vnet_find_parent(hp, vdev->mp); | ||
1027 | if (IS_ERR(vp)) { | ||
1028 | printk(KERN_ERR PFX "Cannot find port parent vnet.\n"); | ||
1029 | err = PTR_ERR(vp); | ||
1030 | goto err_out_put_mdesc; | ||
1031 | } | ||
1032 | |||
910 | rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len); | 1033 | rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len); |
911 | err = -ENODEV; | 1034 | err = -ENODEV; |
912 | if (!rmac) { | 1035 | if (!rmac) { |
@@ -1025,139 +1148,14 @@ static struct vio_driver vnet_port_driver = { | |||
1025 | } | 1148 | } |
1026 | }; | 1149 | }; |
1027 | 1150 | ||
1028 | const char *local_mac_prop = "local-mac-address"; | ||
1029 | |||
1030 | static int __devinit vnet_probe(struct vio_dev *vdev, | ||
1031 | const struct vio_device_id *id) | ||
1032 | { | ||
1033 | static int vnet_version_printed; | ||
1034 | struct mdesc_handle *hp; | ||
1035 | struct net_device *dev; | ||
1036 | struct vnet *vp; | ||
1037 | const u64 *mac; | ||
1038 | int err, i, len; | ||
1039 | |||
1040 | if (vnet_version_printed++ == 0) | ||
1041 | printk(KERN_INFO "%s", version); | ||
1042 | |||
1043 | hp = mdesc_grab(); | ||
1044 | |||
1045 | mac = mdesc_get_property(hp, vdev->mp, local_mac_prop, &len); | ||
1046 | if (!mac) { | ||
1047 | printk(KERN_ERR PFX "vnet lacks %s property.\n", | ||
1048 | local_mac_prop); | ||
1049 | err = -ENODEV; | ||
1050 | goto err_out; | ||
1051 | } | ||
1052 | |||
1053 | dev = alloc_etherdev(sizeof(*vp)); | ||
1054 | if (!dev) { | ||
1055 | printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); | ||
1056 | err = -ENOMEM; | ||
1057 | goto err_out; | ||
1058 | } | ||
1059 | |||
1060 | for (i = 0; i < ETH_ALEN; i++) | ||
1061 | dev->dev_addr[i] = (*mac >> (5 - i) * 8) & 0xff; | ||
1062 | |||
1063 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | ||
1064 | |||
1065 | SET_NETDEV_DEV(dev, &vdev->dev); | ||
1066 | |||
1067 | vp = netdev_priv(dev); | ||
1068 | |||
1069 | spin_lock_init(&vp->lock); | ||
1070 | vp->dev = dev; | ||
1071 | vp->vdev = vdev; | ||
1072 | |||
1073 | INIT_LIST_HEAD(&vp->port_list); | ||
1074 | for (i = 0; i < VNET_PORT_HASH_SIZE; i++) | ||
1075 | INIT_HLIST_HEAD(&vp->port_hash[i]); | ||
1076 | |||
1077 | dev->open = vnet_open; | ||
1078 | dev->stop = vnet_close; | ||
1079 | dev->set_multicast_list = vnet_set_rx_mode; | ||
1080 | dev->set_mac_address = vnet_set_mac_addr; | ||
1081 | dev->tx_timeout = vnet_tx_timeout; | ||
1082 | dev->ethtool_ops = &vnet_ethtool_ops; | ||
1083 | dev->watchdog_timeo = VNET_TX_TIMEOUT; | ||
1084 | dev->change_mtu = vnet_change_mtu; | ||
1085 | dev->hard_start_xmit = vnet_start_xmit; | ||
1086 | |||
1087 | err = register_netdev(dev); | ||
1088 | if (err) { | ||
1089 | printk(KERN_ERR PFX "Cannot register net device, " | ||
1090 | "aborting.\n"); | ||
1091 | goto err_out_free_dev; | ||
1092 | } | ||
1093 | |||
1094 | printk(KERN_INFO "%s: Sun LDOM vnet ", dev->name); | ||
1095 | |||
1096 | for (i = 0; i < 6; i++) | ||
1097 | printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); | ||
1098 | |||
1099 | dev_set_drvdata(&vdev->dev, vp); | ||
1100 | |||
1101 | mdesc_release(hp); | ||
1102 | |||
1103 | return 0; | ||
1104 | |||
1105 | err_out_free_dev: | ||
1106 | free_netdev(dev); | ||
1107 | |||
1108 | err_out: | ||
1109 | mdesc_release(hp); | ||
1110 | return err; | ||
1111 | } | ||
1112 | |||
1113 | static int vnet_remove(struct vio_dev *vdev) | ||
1114 | { | ||
1115 | |||
1116 | struct vnet *vp = dev_get_drvdata(&vdev->dev); | ||
1117 | |||
1118 | if (vp) { | ||
1119 | /* XXX unregister port, or at least check XXX */ | ||
1120 | unregister_netdevice(vp->dev); | ||
1121 | dev_set_drvdata(&vdev->dev, NULL); | ||
1122 | } | ||
1123 | return 0; | ||
1124 | } | ||
1125 | |||
1126 | static struct vio_device_id vnet_match[] = { | ||
1127 | { | ||
1128 | .type = "network", | ||
1129 | }, | ||
1130 | {}, | ||
1131 | }; | ||
1132 | MODULE_DEVICE_TABLE(vio, vnet_match); | ||
1133 | |||
1134 | static struct vio_driver vnet_driver = { | ||
1135 | .id_table = vnet_match, | ||
1136 | .probe = vnet_probe, | ||
1137 | .remove = vnet_remove, | ||
1138 | .driver = { | ||
1139 | .name = "vnet", | ||
1140 | .owner = THIS_MODULE, | ||
1141 | } | ||
1142 | }; | ||
1143 | |||
1144 | static int __init vnet_init(void) | 1151 | static int __init vnet_init(void) |
1145 | { | 1152 | { |
1146 | int err = vio_register_driver(&vnet_driver); | 1153 | return vio_register_driver(&vnet_port_driver); |
1147 | |||
1148 | if (!err) { | ||
1149 | err = vio_register_driver(&vnet_port_driver); | ||
1150 | if (err) | ||
1151 | vio_unregister_driver(&vnet_driver); | ||
1152 | } | ||
1153 | |||
1154 | return err; | ||
1155 | } | 1154 | } |
1156 | 1155 | ||
1157 | static void __exit vnet_exit(void) | 1156 | static void __exit vnet_exit(void) |
1158 | { | 1157 | { |
1159 | vio_unregister_driver(&vnet_port_driver); | 1158 | vio_unregister_driver(&vnet_port_driver); |
1160 | vio_unregister_driver(&vnet_driver); | ||
1161 | } | 1159 | } |
1162 | 1160 | ||
1163 | module_init(vnet_init); | 1161 | module_init(vnet_init); |
diff --git a/drivers/net/sunvnet.h b/drivers/net/sunvnet.h index 1c887302d46d..7d3a0cac727b 100644 --- a/drivers/net/sunvnet.h +++ b/drivers/net/sunvnet.h | |||
@@ -60,11 +60,13 @@ struct vnet { | |||
60 | struct net_device *dev; | 60 | struct net_device *dev; |
61 | 61 | ||
62 | u32 msg_enable; | 62 | u32 msg_enable; |
63 | struct vio_dev *vdev; | ||
64 | 63 | ||
65 | struct list_head port_list; | 64 | struct list_head port_list; |
66 | 65 | ||
67 | struct hlist_head port_hash[VNET_PORT_HASH_SIZE]; | 66 | struct hlist_head port_hash[VNET_PORT_HASH_SIZE]; |
67 | |||
68 | struct list_head list; | ||
69 | u64 local_mac; | ||
68 | }; | 70 | }; |
69 | 71 | ||
70 | #endif /* _SUNVNET_H */ | 72 | #endif /* _SUNVNET_H */ |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c new file mode 100644 index 000000000000..489f69c5d6ca --- /dev/null +++ b/drivers/net/xen-netfront.c | |||
@@ -0,0 +1,1863 @@ | |||
1 | /* | ||
2 | * Virtual network driver for conversing with remote driver backends. | ||
3 | * | ||
4 | * Copyright (c) 2002-2005, K A Fraser | ||
5 | * Copyright (c) 2005, XenSource Ltd | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License version 2 | ||
9 | * as published by the Free Software Foundation; or, when distributed | ||
10 | * separately from the Linux kernel or incorporated into other | ||
11 | * software packages, subject to the following license: | ||
12 | * | ||
13 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
14 | * of this source file (the "Software"), to deal in the Software without | ||
15 | * restriction, including without limitation the rights to use, copy, modify, | ||
16 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
17 | * and to permit persons to whom the Software is furnished to do so, subject to | ||
18 | * the following conditions: | ||
19 | * | ||
20 | * The above copyright notice and this permission notice shall be included in | ||
21 | * all copies or substantial portions of the Software. | ||
22 | * | ||
23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
24 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
25 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
26 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
27 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
28 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
29 | * IN THE SOFTWARE. | ||
30 | */ | ||
31 | |||
32 | #include <linux/module.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/netdevice.h> | ||
35 | #include <linux/etherdevice.h> | ||
36 | #include <linux/skbuff.h> | ||
37 | #include <linux/ethtool.h> | ||
38 | #include <linux/if_ether.h> | ||
39 | #include <linux/tcp.h> | ||
40 | #include <linux/udp.h> | ||
41 | #include <linux/moduleparam.h> | ||
42 | #include <linux/mm.h> | ||
43 | #include <net/ip.h> | ||
44 | |||
45 | #include <xen/xenbus.h> | ||
46 | #include <xen/events.h> | ||
47 | #include <xen/page.h> | ||
48 | #include <xen/grant_table.h> | ||
49 | |||
50 | #include <xen/interface/io/netif.h> | ||
51 | #include <xen/interface/memory.h> | ||
52 | #include <xen/interface/grant_table.h> | ||
53 | |||
54 | static struct ethtool_ops xennet_ethtool_ops; | ||
55 | |||
56 | struct netfront_cb { | ||
57 | struct page *page; | ||
58 | unsigned offset; | ||
59 | }; | ||
60 | |||
61 | #define NETFRONT_SKB_CB(skb) ((struct netfront_cb *)((skb)->cb)) | ||
62 | |||
63 | #define RX_COPY_THRESHOLD 256 | ||
64 | |||
65 | #define GRANT_INVALID_REF 0 | ||
66 | |||
67 | #define NET_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE) | ||
68 | #define NET_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE) | ||
69 | #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) | ||
70 | |||
71 | struct netfront_info { | ||
72 | struct list_head list; | ||
73 | struct net_device *netdev; | ||
74 | |||
75 | struct net_device_stats stats; | ||
76 | |||
77 | struct xen_netif_tx_front_ring tx; | ||
78 | struct xen_netif_rx_front_ring rx; | ||
79 | |||
80 | spinlock_t tx_lock; | ||
81 | spinlock_t rx_lock; | ||
82 | |||
83 | unsigned int evtchn; | ||
84 | |||
85 | /* Receive-ring batched refills. */ | ||
86 | #define RX_MIN_TARGET 8 | ||
87 | #define RX_DFL_MIN_TARGET 64 | ||
88 | #define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) | ||
89 | unsigned rx_min_target, rx_max_target, rx_target; | ||
90 | struct sk_buff_head rx_batch; | ||
91 | |||
92 | struct timer_list rx_refill_timer; | ||
93 | |||
94 | /* | ||
95 | * {tx,rx}_skbs store outstanding skbuffs. Free tx_skb entries | ||
96 | * are linked from tx_skb_freelist through skb_entry.link. | ||
97 | * | ||
98 | * NB. Freelist index entries are always going to be less than | ||
99 | * PAGE_OFFSET, whereas pointers to skbs will always be equal or | ||
100 | * greater than PAGE_OFFSET: we use this property to distinguish | ||
101 | * them. | ||
102 | */ | ||
103 | union skb_entry { | ||
104 | struct sk_buff *skb; | ||
105 | unsigned link; | ||
106 | } tx_skbs[NET_TX_RING_SIZE]; | ||
107 | grant_ref_t gref_tx_head; | ||
108 | grant_ref_t grant_tx_ref[NET_TX_RING_SIZE]; | ||
109 | unsigned tx_skb_freelist; | ||
110 | |||
111 | struct sk_buff *rx_skbs[NET_RX_RING_SIZE]; | ||
112 | grant_ref_t gref_rx_head; | ||
113 | grant_ref_t grant_rx_ref[NET_RX_RING_SIZE]; | ||
114 | |||
115 | struct xenbus_device *xbdev; | ||
116 | int tx_ring_ref; | ||
117 | int rx_ring_ref; | ||
118 | |||
119 | unsigned long rx_pfn_array[NET_RX_RING_SIZE]; | ||
120 | struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1]; | ||
121 | struct mmu_update rx_mmu[NET_RX_RING_SIZE]; | ||
122 | }; | ||
123 | |||
124 | struct netfront_rx_info { | ||
125 | struct xen_netif_rx_response rx; | ||
126 | struct xen_netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1]; | ||
127 | }; | ||
128 | |||
129 | /* | ||
130 | * Access macros for acquiring freeing slots in tx_skbs[]. | ||
131 | */ | ||
132 | |||
133 | static void add_id_to_freelist(unsigned *head, union skb_entry *list, | ||
134 | unsigned short id) | ||
135 | { | ||
136 | list[id].link = *head; | ||
137 | *head = id; | ||
138 | } | ||
139 | |||
140 | static unsigned short get_id_from_freelist(unsigned *head, | ||
141 | union skb_entry *list) | ||
142 | { | ||
143 | unsigned int id = *head; | ||
144 | *head = list[id].link; | ||
145 | return id; | ||
146 | } | ||
147 | |||
148 | static int xennet_rxidx(RING_IDX idx) | ||
149 | { | ||
150 | return idx & (NET_RX_RING_SIZE - 1); | ||
151 | } | ||
152 | |||
153 | static struct sk_buff *xennet_get_rx_skb(struct netfront_info *np, | ||
154 | RING_IDX ri) | ||
155 | { | ||
156 | int i = xennet_rxidx(ri); | ||
157 | struct sk_buff *skb = np->rx_skbs[i]; | ||
158 | np->rx_skbs[i] = NULL; | ||
159 | return skb; | ||
160 | } | ||
161 | |||
162 | static grant_ref_t xennet_get_rx_ref(struct netfront_info *np, | ||
163 | RING_IDX ri) | ||
164 | { | ||
165 | int i = xennet_rxidx(ri); | ||
166 | grant_ref_t ref = np->grant_rx_ref[i]; | ||
167 | np->grant_rx_ref[i] = GRANT_INVALID_REF; | ||
168 | return ref; | ||
169 | } | ||
170 | |||
171 | #ifdef CONFIG_SYSFS | ||
172 | static int xennet_sysfs_addif(struct net_device *netdev); | ||
173 | static void xennet_sysfs_delif(struct net_device *netdev); | ||
174 | #else /* !CONFIG_SYSFS */ | ||
175 | #define xennet_sysfs_addif(dev) (0) | ||
176 | #define xennet_sysfs_delif(dev) do { } while (0) | ||
177 | #endif | ||
178 | |||
179 | static int xennet_can_sg(struct net_device *dev) | ||
180 | { | ||
181 | return dev->features & NETIF_F_SG; | ||
182 | } | ||
183 | |||
184 | |||
185 | static void rx_refill_timeout(unsigned long data) | ||
186 | { | ||
187 | struct net_device *dev = (struct net_device *)data; | ||
188 | netif_rx_schedule(dev); | ||
189 | } | ||
190 | |||
191 | static int netfront_tx_slot_available(struct netfront_info *np) | ||
192 | { | ||
193 | return ((np->tx.req_prod_pvt - np->tx.rsp_cons) < | ||
194 | (TX_MAX_TARGET - MAX_SKB_FRAGS - 2)); | ||
195 | } | ||
196 | |||
197 | static void xennet_maybe_wake_tx(struct net_device *dev) | ||
198 | { | ||
199 | struct netfront_info *np = netdev_priv(dev); | ||
200 | |||
201 | if (unlikely(netif_queue_stopped(dev)) && | ||
202 | netfront_tx_slot_available(np) && | ||
203 | likely(netif_running(dev))) | ||
204 | netif_wake_queue(dev); | ||
205 | } | ||
206 | |||
207 | static void xennet_alloc_rx_buffers(struct net_device *dev) | ||
208 | { | ||
209 | unsigned short id; | ||
210 | struct netfront_info *np = netdev_priv(dev); | ||
211 | struct sk_buff *skb; | ||
212 | struct page *page; | ||
213 | int i, batch_target, notify; | ||
214 | RING_IDX req_prod = np->rx.req_prod_pvt; | ||
215 | struct xen_memory_reservation reservation; | ||
216 | grant_ref_t ref; | ||
217 | unsigned long pfn; | ||
218 | void *vaddr; | ||
219 | int nr_flips; | ||
220 | struct xen_netif_rx_request *req; | ||
221 | |||
222 | if (unlikely(!netif_carrier_ok(dev))) | ||
223 | return; | ||
224 | |||
225 | /* | ||
226 | * Allocate skbuffs greedily, even though we batch updates to the | ||
227 | * receive ring. This creates a less bursty demand on the memory | ||
228 | * allocator, so should reduce the chance of failed allocation requests | ||
229 | * both for ourself and for other kernel subsystems. | ||
230 | */ | ||
231 | batch_target = np->rx_target - (req_prod - np->rx.rsp_cons); | ||
232 | for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) { | ||
233 | skb = __netdev_alloc_skb(dev, RX_COPY_THRESHOLD, | ||
234 | GFP_ATOMIC | __GFP_NOWARN); | ||
235 | if (unlikely(!skb)) | ||
236 | goto no_skb; | ||
237 | |||
238 | page = alloc_page(GFP_ATOMIC | __GFP_NOWARN); | ||
239 | if (!page) { | ||
240 | kfree_skb(skb); | ||
241 | no_skb: | ||
242 | /* Any skbuffs queued for refill? Force them out. */ | ||
243 | if (i != 0) | ||
244 | goto refill; | ||
245 | /* Could not allocate any skbuffs. Try again later. */ | ||
246 | mod_timer(&np->rx_refill_timer, | ||
247 | jiffies + (HZ/10)); | ||
248 | break; | ||
249 | } | ||
250 | |||
251 | skb_shinfo(skb)->frags[0].page = page; | ||
252 | skb_shinfo(skb)->nr_frags = 1; | ||
253 | __skb_queue_tail(&np->rx_batch, skb); | ||
254 | } | ||
255 | |||
256 | /* Is the batch large enough to be worthwhile? */ | ||
257 | if (i < (np->rx_target/2)) { | ||
258 | if (req_prod > np->rx.sring->req_prod) | ||
259 | goto push; | ||
260 | return; | ||
261 | } | ||
262 | |||
263 | /* Adjust our fill target if we risked running out of buffers. */ | ||
264 | if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) && | ||
265 | ((np->rx_target *= 2) > np->rx_max_target)) | ||
266 | np->rx_target = np->rx_max_target; | ||
267 | |||
268 | refill: | ||
269 | for (nr_flips = i = 0; ; i++) { | ||
270 | skb = __skb_dequeue(&np->rx_batch); | ||
271 | if (skb == NULL) | ||
272 | break; | ||
273 | |||
274 | skb->dev = dev; | ||
275 | |||
276 | id = xennet_rxidx(req_prod + i); | ||
277 | |||
278 | BUG_ON(np->rx_skbs[id]); | ||
279 | np->rx_skbs[id] = skb; | ||
280 | |||
281 | ref = gnttab_claim_grant_reference(&np->gref_rx_head); | ||
282 | BUG_ON((signed short)ref < 0); | ||
283 | np->grant_rx_ref[id] = ref; | ||
284 | |||
285 | pfn = page_to_pfn(skb_shinfo(skb)->frags[0].page); | ||
286 | vaddr = page_address(skb_shinfo(skb)->frags[0].page); | ||
287 | |||
288 | req = RING_GET_REQUEST(&np->rx, req_prod + i); | ||
289 | gnttab_grant_foreign_access_ref(ref, | ||
290 | np->xbdev->otherend_id, | ||
291 | pfn_to_mfn(pfn), | ||
292 | 0); | ||
293 | |||
294 | req->id = id; | ||
295 | req->gref = ref; | ||
296 | } | ||
297 | |||
298 | if (nr_flips != 0) { | ||
299 | reservation.extent_start = np->rx_pfn_array; | ||
300 | reservation.nr_extents = nr_flips; | ||
301 | reservation.extent_order = 0; | ||
302 | reservation.address_bits = 0; | ||
303 | reservation.domid = DOMID_SELF; | ||
304 | |||
305 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { | ||
306 | /* After all PTEs have been zapped, flush the TLB. */ | ||
307 | np->rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] = | ||
308 | UVMF_TLB_FLUSH|UVMF_ALL; | ||
309 | |||
310 | /* Give away a batch of pages. */ | ||
311 | np->rx_mcl[i].op = __HYPERVISOR_memory_op; | ||
312 | np->rx_mcl[i].args[0] = XENMEM_decrease_reservation; | ||
313 | np->rx_mcl[i].args[1] = (unsigned long)&reservation; | ||
314 | |||
315 | /* Zap PTEs and give away pages in one big | ||
316 | * multicall. */ | ||
317 | (void)HYPERVISOR_multicall(np->rx_mcl, i+1); | ||
318 | |||
319 | /* Check return status of HYPERVISOR_memory_op(). */ | ||
320 | if (unlikely(np->rx_mcl[i].result != i)) | ||
321 | panic("Unable to reduce memory reservation\n"); | ||
322 | } else { | ||
323 | if (HYPERVISOR_memory_op(XENMEM_decrease_reservation, | ||
324 | &reservation) != i) | ||
325 | panic("Unable to reduce memory reservation\n"); | ||
326 | } | ||
327 | } else { | ||
328 | wmb(); /* barrier so backend seens requests */ | ||
329 | } | ||
330 | |||
331 | /* Above is a suitable barrier to ensure backend will see requests. */ | ||
332 | np->rx.req_prod_pvt = req_prod + i; | ||
333 | push: | ||
334 | RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify); | ||
335 | if (notify) | ||
336 | notify_remote_via_irq(np->netdev->irq); | ||
337 | } | ||
338 | |||
339 | static int xennet_open(struct net_device *dev) | ||
340 | { | ||
341 | struct netfront_info *np = netdev_priv(dev); | ||
342 | |||
343 | memset(&np->stats, 0, sizeof(np->stats)); | ||
344 | |||
345 | spin_lock_bh(&np->rx_lock); | ||
346 | if (netif_carrier_ok(dev)) { | ||
347 | xennet_alloc_rx_buffers(dev); | ||
348 | np->rx.sring->rsp_event = np->rx.rsp_cons + 1; | ||
349 | if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) | ||
350 | netif_rx_schedule(dev); | ||
351 | } | ||
352 | spin_unlock_bh(&np->rx_lock); | ||
353 | |||
354 | xennet_maybe_wake_tx(dev); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static void xennet_tx_buf_gc(struct net_device *dev) | ||
360 | { | ||
361 | RING_IDX cons, prod; | ||
362 | unsigned short id; | ||
363 | struct netfront_info *np = netdev_priv(dev); | ||
364 | struct sk_buff *skb; | ||
365 | |||
366 | BUG_ON(!netif_carrier_ok(dev)); | ||
367 | |||
368 | do { | ||
369 | prod = np->tx.sring->rsp_prod; | ||
370 | rmb(); /* Ensure we see responses up to 'rp'. */ | ||
371 | |||
372 | for (cons = np->tx.rsp_cons; cons != prod; cons++) { | ||
373 | struct xen_netif_tx_response *txrsp; | ||
374 | |||
375 | txrsp = RING_GET_RESPONSE(&np->tx, cons); | ||
376 | if (txrsp->status == NETIF_RSP_NULL) | ||
377 | continue; | ||
378 | |||
379 | id = txrsp->id; | ||
380 | skb = np->tx_skbs[id].skb; | ||
381 | if (unlikely(gnttab_query_foreign_access( | ||
382 | np->grant_tx_ref[id]) != 0)) { | ||
383 | printk(KERN_ALERT "xennet_tx_buf_gc: warning " | ||
384 | "-- grant still in use by backend " | ||
385 | "domain.\n"); | ||
386 | BUG(); | ||
387 | } | ||
388 | gnttab_end_foreign_access_ref( | ||
389 | np->grant_tx_ref[id], GNTMAP_readonly); | ||
390 | gnttab_release_grant_reference( | ||
391 | &np->gref_tx_head, np->grant_tx_ref[id]); | ||
392 | np->grant_tx_ref[id] = GRANT_INVALID_REF; | ||
393 | add_id_to_freelist(&np->tx_skb_freelist, np->tx_skbs, id); | ||
394 | dev_kfree_skb_irq(skb); | ||
395 | } | ||
396 | |||
397 | np->tx.rsp_cons = prod; | ||
398 | |||
399 | /* | ||
400 | * Set a new event, then check for race with update of tx_cons. | ||
401 | * Note that it is essential to schedule a callback, no matter | ||
402 | * how few buffers are pending. Even if there is space in the | ||
403 | * transmit ring, higher layers may be blocked because too much | ||
404 | * data is outstanding: in such cases notification from Xen is | ||
405 | * likely to be the only kick that we'll get. | ||
406 | */ | ||
407 | np->tx.sring->rsp_event = | ||
408 | prod + ((np->tx.sring->req_prod - prod) >> 1) + 1; | ||
409 | mb(); /* update shared area */ | ||
410 | } while ((cons == prod) && (prod != np->tx.sring->rsp_prod)); | ||
411 | |||
412 | xennet_maybe_wake_tx(dev); | ||
413 | } | ||
414 | |||
415 | static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, | ||
416 | struct xen_netif_tx_request *tx) | ||
417 | { | ||
418 | struct netfront_info *np = netdev_priv(dev); | ||
419 | char *data = skb->data; | ||
420 | unsigned long mfn; | ||
421 | RING_IDX prod = np->tx.req_prod_pvt; | ||
422 | int frags = skb_shinfo(skb)->nr_frags; | ||
423 | unsigned int offset = offset_in_page(data); | ||
424 | unsigned int len = skb_headlen(skb); | ||
425 | unsigned int id; | ||
426 | grant_ref_t ref; | ||
427 | int i; | ||
428 | |||
429 | /* While the header overlaps a page boundary (including being | ||
430 | larger than a page), split it it into page-sized chunks. */ | ||
431 | while (len > PAGE_SIZE - offset) { | ||
432 | tx->size = PAGE_SIZE - offset; | ||
433 | tx->flags |= NETTXF_more_data; | ||
434 | len -= tx->size; | ||
435 | data += tx->size; | ||
436 | offset = 0; | ||
437 | |||
438 | id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs); | ||
439 | np->tx_skbs[id].skb = skb_get(skb); | ||
440 | tx = RING_GET_REQUEST(&np->tx, prod++); | ||
441 | tx->id = id; | ||
442 | ref = gnttab_claim_grant_reference(&np->gref_tx_head); | ||
443 | BUG_ON((signed short)ref < 0); | ||
444 | |||
445 | mfn = virt_to_mfn(data); | ||
446 | gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, | ||
447 | mfn, GNTMAP_readonly); | ||
448 | |||
449 | tx->gref = np->grant_tx_ref[id] = ref; | ||
450 | tx->offset = offset; | ||
451 | tx->size = len; | ||
452 | tx->flags = 0; | ||
453 | } | ||
454 | |||
455 | /* Grant backend access to each skb fragment page. */ | ||
456 | for (i = 0; i < frags; i++) { | ||
457 | skb_frag_t *frag = skb_shinfo(skb)->frags + i; | ||
458 | |||
459 | tx->flags |= NETTXF_more_data; | ||
460 | |||
461 | id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs); | ||
462 | np->tx_skbs[id].skb = skb_get(skb); | ||
463 | tx = RING_GET_REQUEST(&np->tx, prod++); | ||
464 | tx->id = id; | ||
465 | ref = gnttab_claim_grant_reference(&np->gref_tx_head); | ||
466 | BUG_ON((signed short)ref < 0); | ||
467 | |||
468 | mfn = pfn_to_mfn(page_to_pfn(frag->page)); | ||
469 | gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id, | ||
470 | mfn, GNTMAP_readonly); | ||
471 | |||
472 | tx->gref = np->grant_tx_ref[id] = ref; | ||
473 | tx->offset = frag->page_offset; | ||
474 | tx->size = frag->size; | ||
475 | tx->flags = 0; | ||
476 | } | ||
477 | |||
478 | np->tx.req_prod_pvt = prod; | ||
479 | } | ||
480 | |||
481 | static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
482 | { | ||
483 | unsigned short id; | ||
484 | struct netfront_info *np = netdev_priv(dev); | ||
485 | struct xen_netif_tx_request *tx; | ||
486 | struct xen_netif_extra_info *extra; | ||
487 | char *data = skb->data; | ||
488 | RING_IDX i; | ||
489 | grant_ref_t ref; | ||
490 | unsigned long mfn; | ||
491 | int notify; | ||
492 | int frags = skb_shinfo(skb)->nr_frags; | ||
493 | unsigned int offset = offset_in_page(data); | ||
494 | unsigned int len = skb_headlen(skb); | ||
495 | |||
496 | frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE; | ||
497 | if (unlikely(frags > MAX_SKB_FRAGS + 1)) { | ||
498 | printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n", | ||
499 | frags); | ||
500 | dump_stack(); | ||
501 | goto drop; | ||
502 | } | ||
503 | |||
504 | spin_lock_irq(&np->tx_lock); | ||
505 | |||
506 | if (unlikely(!netif_carrier_ok(dev) || | ||
507 | (frags > 1 && !xennet_can_sg(dev)) || | ||
508 | netif_needs_gso(dev, skb))) { | ||
509 | spin_unlock_irq(&np->tx_lock); | ||
510 | goto drop; | ||
511 | } | ||
512 | |||
513 | i = np->tx.req_prod_pvt; | ||
514 | |||
515 | id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs); | ||
516 | np->tx_skbs[id].skb = skb; | ||
517 | |||
518 | tx = RING_GET_REQUEST(&np->tx, i); | ||
519 | |||
520 | tx->id = id; | ||
521 | ref = gnttab_claim_grant_reference(&np->gref_tx_head); | ||
522 | BUG_ON((signed short)ref < 0); | ||
523 | mfn = virt_to_mfn(data); | ||
524 | gnttab_grant_foreign_access_ref( | ||
525 | ref, np->xbdev->otherend_id, mfn, GNTMAP_readonly); | ||
526 | tx->gref = np->grant_tx_ref[id] = ref; | ||
527 | tx->offset = offset; | ||
528 | tx->size = len; | ||
529 | extra = NULL; | ||
530 | |||
531 | tx->flags = 0; | ||
532 | if (skb->ip_summed == CHECKSUM_PARTIAL) | ||
533 | /* local packet? */ | ||
534 | tx->flags |= NETTXF_csum_blank | NETTXF_data_validated; | ||
535 | else if (skb->ip_summed == CHECKSUM_UNNECESSARY) | ||
536 | /* remote but checksummed. */ | ||
537 | tx->flags |= NETTXF_data_validated; | ||
538 | |||
539 | if (skb_shinfo(skb)->gso_size) { | ||
540 | struct xen_netif_extra_info *gso; | ||
541 | |||
542 | gso = (struct xen_netif_extra_info *) | ||
543 | RING_GET_REQUEST(&np->tx, ++i); | ||
544 | |||
545 | if (extra) | ||
546 | extra->flags |= XEN_NETIF_EXTRA_FLAG_MORE; | ||
547 | else | ||
548 | tx->flags |= NETTXF_extra_info; | ||
549 | |||
550 | gso->u.gso.size = skb_shinfo(skb)->gso_size; | ||
551 | gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4; | ||
552 | gso->u.gso.pad = 0; | ||
553 | gso->u.gso.features = 0; | ||
554 | |||
555 | gso->type = XEN_NETIF_EXTRA_TYPE_GSO; | ||
556 | gso->flags = 0; | ||
557 | extra = gso; | ||
558 | } | ||
559 | |||
560 | np->tx.req_prod_pvt = i + 1; | ||
561 | |||
562 | xennet_make_frags(skb, dev, tx); | ||
563 | tx->size = skb->len; | ||
564 | |||
565 | RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify); | ||
566 | if (notify) | ||
567 | notify_remote_via_irq(np->netdev->irq); | ||
568 | |||
569 | xennet_tx_buf_gc(dev); | ||
570 | |||
571 | if (!netfront_tx_slot_available(np)) | ||
572 | netif_stop_queue(dev); | ||
573 | |||
574 | spin_unlock_irq(&np->tx_lock); | ||
575 | |||
576 | np->stats.tx_bytes += skb->len; | ||
577 | np->stats.tx_packets++; | ||
578 | |||
579 | return 0; | ||
580 | |||
581 | drop: | ||
582 | np->stats.tx_dropped++; | ||
583 | dev_kfree_skb(skb); | ||
584 | return 0; | ||
585 | } | ||
586 | |||
587 | static int xennet_close(struct net_device *dev) | ||
588 | { | ||
589 | struct netfront_info *np = netdev_priv(dev); | ||
590 | netif_stop_queue(np->netdev); | ||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | static struct net_device_stats *xennet_get_stats(struct net_device *dev) | ||
595 | { | ||
596 | struct netfront_info *np = netdev_priv(dev); | ||
597 | return &np->stats; | ||
598 | } | ||
599 | |||
600 | static void xennet_move_rx_slot(struct netfront_info *np, struct sk_buff *skb, | ||
601 | grant_ref_t ref) | ||
602 | { | ||
603 | int new = xennet_rxidx(np->rx.req_prod_pvt); | ||
604 | |||
605 | BUG_ON(np->rx_skbs[new]); | ||
606 | np->rx_skbs[new] = skb; | ||
607 | np->grant_rx_ref[new] = ref; | ||
608 | RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->id = new; | ||
609 | RING_GET_REQUEST(&np->rx, np->rx.req_prod_pvt)->gref = ref; | ||
610 | np->rx.req_prod_pvt++; | ||
611 | } | ||
612 | |||
613 | static int xennet_get_extras(struct netfront_info *np, | ||
614 | struct xen_netif_extra_info *extras, | ||
615 | RING_IDX rp) | ||
616 | |||
617 | { | ||
618 | struct xen_netif_extra_info *extra; | ||
619 | struct device *dev = &np->netdev->dev; | ||
620 | RING_IDX cons = np->rx.rsp_cons; | ||
621 | int err = 0; | ||
622 | |||
623 | do { | ||
624 | struct sk_buff *skb; | ||
625 | grant_ref_t ref; | ||
626 | |||
627 | if (unlikely(cons + 1 == rp)) { | ||
628 | if (net_ratelimit()) | ||
629 | dev_warn(dev, "Missing extra info\n"); | ||
630 | err = -EBADR; | ||
631 | break; | ||
632 | } | ||
633 | |||
634 | extra = (struct xen_netif_extra_info *) | ||
635 | RING_GET_RESPONSE(&np->rx, ++cons); | ||
636 | |||
637 | if (unlikely(!extra->type || | ||
638 | extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) { | ||
639 | if (net_ratelimit()) | ||
640 | dev_warn(dev, "Invalid extra type: %d\n", | ||
641 | extra->type); | ||
642 | err = -EINVAL; | ||
643 | } else { | ||
644 | memcpy(&extras[extra->type - 1], extra, | ||
645 | sizeof(*extra)); | ||
646 | } | ||
647 | |||
648 | skb = xennet_get_rx_skb(np, cons); | ||
649 | ref = xennet_get_rx_ref(np, cons); | ||
650 | xennet_move_rx_slot(np, skb, ref); | ||
651 | } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE); | ||
652 | |||
653 | np->rx.rsp_cons = cons; | ||
654 | return err; | ||
655 | } | ||
656 | |||
657 | static int xennet_get_responses(struct netfront_info *np, | ||
658 | struct netfront_rx_info *rinfo, RING_IDX rp, | ||
659 | struct sk_buff_head *list) | ||
660 | { | ||
661 | struct xen_netif_rx_response *rx = &rinfo->rx; | ||
662 | struct xen_netif_extra_info *extras = rinfo->extras; | ||
663 | struct device *dev = &np->netdev->dev; | ||
664 | RING_IDX cons = np->rx.rsp_cons; | ||
665 | struct sk_buff *skb = xennet_get_rx_skb(np, cons); | ||
666 | grant_ref_t ref = xennet_get_rx_ref(np, cons); | ||
667 | int max = MAX_SKB_FRAGS + (rx->status <= RX_COPY_THRESHOLD); | ||
668 | int frags = 1; | ||
669 | int err = 0; | ||
670 | unsigned long ret; | ||
671 | |||
672 | if (rx->flags & NETRXF_extra_info) { | ||
673 | err = xennet_get_extras(np, extras, rp); | ||
674 | cons = np->rx.rsp_cons; | ||
675 | } | ||
676 | |||
677 | for (;;) { | ||
678 | if (unlikely(rx->status < 0 || | ||
679 | rx->offset + rx->status > PAGE_SIZE)) { | ||
680 | if (net_ratelimit()) | ||
681 | dev_warn(dev, "rx->offset: %x, size: %u\n", | ||
682 | rx->offset, rx->status); | ||
683 | xennet_move_rx_slot(np, skb, ref); | ||
684 | err = -EINVAL; | ||
685 | goto next; | ||
686 | } | ||
687 | |||
688 | /* | ||
689 | * This definitely indicates a bug, either in this driver or in | ||
690 | * the backend driver. In future this should flag the bad | ||
691 | * situation to the system controller to reboot the backed. | ||
692 | */ | ||
693 | if (ref == GRANT_INVALID_REF) { | ||
694 | if (net_ratelimit()) | ||
695 | dev_warn(dev, "Bad rx response id %d.\n", | ||
696 | rx->id); | ||
697 | err = -EINVAL; | ||
698 | goto next; | ||
699 | } | ||
700 | |||
701 | ret = gnttab_end_foreign_access_ref(ref, 0); | ||
702 | BUG_ON(!ret); | ||
703 | |||
704 | gnttab_release_grant_reference(&np->gref_rx_head, ref); | ||
705 | |||
706 | __skb_queue_tail(list, skb); | ||
707 | |||
708 | next: | ||
709 | if (!(rx->flags & NETRXF_more_data)) | ||
710 | break; | ||
711 | |||
712 | if (cons + frags == rp) { | ||
713 | if (net_ratelimit()) | ||
714 | dev_warn(dev, "Need more frags\n"); | ||
715 | err = -ENOENT; | ||
716 | break; | ||
717 | } | ||
718 | |||
719 | rx = RING_GET_RESPONSE(&np->rx, cons + frags); | ||
720 | skb = xennet_get_rx_skb(np, cons + frags); | ||
721 | ref = xennet_get_rx_ref(np, cons + frags); | ||
722 | frags++; | ||
723 | } | ||
724 | |||
725 | if (unlikely(frags > max)) { | ||
726 | if (net_ratelimit()) | ||
727 | dev_warn(dev, "Too many frags\n"); | ||
728 | err = -E2BIG; | ||
729 | } | ||
730 | |||
731 | if (unlikely(err)) | ||
732 | np->rx.rsp_cons = cons + frags; | ||
733 | |||
734 | return err; | ||
735 | } | ||
736 | |||
737 | static int xennet_set_skb_gso(struct sk_buff *skb, | ||
738 | struct xen_netif_extra_info *gso) | ||
739 | { | ||
740 | if (!gso->u.gso.size) { | ||
741 | if (net_ratelimit()) | ||
742 | printk(KERN_WARNING "GSO size must not be zero.\n"); | ||
743 | return -EINVAL; | ||
744 | } | ||
745 | |||
746 | /* Currently only TCPv4 S.O. is supported. */ | ||
747 | if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) { | ||
748 | if (net_ratelimit()) | ||
749 | printk(KERN_WARNING "Bad GSO type %d.\n", gso->u.gso.type); | ||
750 | return -EINVAL; | ||
751 | } | ||
752 | |||
753 | skb_shinfo(skb)->gso_size = gso->u.gso.size; | ||
754 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4; | ||
755 | |||
756 | /* Header must be checked, and gso_segs computed. */ | ||
757 | skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; | ||
758 | skb_shinfo(skb)->gso_segs = 0; | ||
759 | |||
760 | return 0; | ||
761 | } | ||
762 | |||
763 | static RING_IDX xennet_fill_frags(struct netfront_info *np, | ||
764 | struct sk_buff *skb, | ||
765 | struct sk_buff_head *list) | ||
766 | { | ||
767 | struct skb_shared_info *shinfo = skb_shinfo(skb); | ||
768 | int nr_frags = shinfo->nr_frags; | ||
769 | RING_IDX cons = np->rx.rsp_cons; | ||
770 | skb_frag_t *frag = shinfo->frags + nr_frags; | ||
771 | struct sk_buff *nskb; | ||
772 | |||
773 | while ((nskb = __skb_dequeue(list))) { | ||
774 | struct xen_netif_rx_response *rx = | ||
775 | RING_GET_RESPONSE(&np->rx, ++cons); | ||
776 | |||
777 | frag->page = skb_shinfo(nskb)->frags[0].page; | ||
778 | frag->page_offset = rx->offset; | ||
779 | frag->size = rx->status; | ||
780 | |||
781 | skb->data_len += rx->status; | ||
782 | |||
783 | skb_shinfo(nskb)->nr_frags = 0; | ||
784 | kfree_skb(nskb); | ||
785 | |||
786 | frag++; | ||
787 | nr_frags++; | ||
788 | } | ||
789 | |||
790 | shinfo->nr_frags = nr_frags; | ||
791 | return cons; | ||
792 | } | ||
793 | |||
794 | static int skb_checksum_setup(struct sk_buff *skb) | ||
795 | { | ||
796 | struct iphdr *iph; | ||
797 | unsigned char *th; | ||
798 | int err = -EPROTO; | ||
799 | |||
800 | if (skb->protocol != htons(ETH_P_IP)) | ||
801 | goto out; | ||
802 | |||
803 | iph = (void *)skb->data; | ||
804 | th = skb->data + 4 * iph->ihl; | ||
805 | if (th >= skb_tail_pointer(skb)) | ||
806 | goto out; | ||
807 | |||
808 | skb->csum_start = th - skb->head; | ||
809 | switch (iph->protocol) { | ||
810 | case IPPROTO_TCP: | ||
811 | skb->csum_offset = offsetof(struct tcphdr, check); | ||
812 | break; | ||
813 | case IPPROTO_UDP: | ||
814 | skb->csum_offset = offsetof(struct udphdr, check); | ||
815 | break; | ||
816 | default: | ||
817 | if (net_ratelimit()) | ||
818 | printk(KERN_ERR "Attempting to checksum a non-" | ||
819 | "TCP/UDP packet, dropping a protocol" | ||
820 | " %d packet", iph->protocol); | ||
821 | goto out; | ||
822 | } | ||
823 | |||
824 | if ((th + skb->csum_offset + 2) > skb_tail_pointer(skb)) | ||
825 | goto out; | ||
826 | |||
827 | err = 0; | ||
828 | |||
829 | out: | ||
830 | return err; | ||
831 | } | ||
832 | |||
833 | static int handle_incoming_queue(struct net_device *dev, | ||
834 | struct sk_buff_head *rxq) | ||
835 | { | ||
836 | struct netfront_info *np = netdev_priv(dev); | ||
837 | int packets_dropped = 0; | ||
838 | struct sk_buff *skb; | ||
839 | |||
840 | while ((skb = __skb_dequeue(rxq)) != NULL) { | ||
841 | struct page *page = NETFRONT_SKB_CB(skb)->page; | ||
842 | void *vaddr = page_address(page); | ||
843 | unsigned offset = NETFRONT_SKB_CB(skb)->offset; | ||
844 | |||
845 | memcpy(skb->data, vaddr + offset, | ||
846 | skb_headlen(skb)); | ||
847 | |||
848 | if (page != skb_shinfo(skb)->frags[0].page) | ||
849 | __free_page(page); | ||
850 | |||
851 | /* Ethernet work: Delayed to here as it peeks the header. */ | ||
852 | skb->protocol = eth_type_trans(skb, dev); | ||
853 | |||
854 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
855 | if (skb_checksum_setup(skb)) { | ||
856 | kfree_skb(skb); | ||
857 | packets_dropped++; | ||
858 | np->stats.rx_errors++; | ||
859 | continue; | ||
860 | } | ||
861 | } | ||
862 | |||
863 | np->stats.rx_packets++; | ||
864 | np->stats.rx_bytes += skb->len; | ||
865 | |||
866 | /* Pass it up. */ | ||
867 | netif_receive_skb(skb); | ||
868 | dev->last_rx = jiffies; | ||
869 | } | ||
870 | |||
871 | return packets_dropped; | ||
872 | } | ||
873 | |||
874 | static int xennet_poll(struct net_device *dev, int *pbudget) | ||
875 | { | ||
876 | struct netfront_info *np = netdev_priv(dev); | ||
877 | struct sk_buff *skb; | ||
878 | struct netfront_rx_info rinfo; | ||
879 | struct xen_netif_rx_response *rx = &rinfo.rx; | ||
880 | struct xen_netif_extra_info *extras = rinfo.extras; | ||
881 | RING_IDX i, rp; | ||
882 | int work_done, budget, more_to_do = 1; | ||
883 | struct sk_buff_head rxq; | ||
884 | struct sk_buff_head errq; | ||
885 | struct sk_buff_head tmpq; | ||
886 | unsigned long flags; | ||
887 | unsigned int len; | ||
888 | int err; | ||
889 | |||
890 | spin_lock(&np->rx_lock); | ||
891 | |||
892 | if (unlikely(!netif_carrier_ok(dev))) { | ||
893 | spin_unlock(&np->rx_lock); | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | skb_queue_head_init(&rxq); | ||
898 | skb_queue_head_init(&errq); | ||
899 | skb_queue_head_init(&tmpq); | ||
900 | |||
901 | budget = *pbudget; | ||
902 | if (budget > dev->quota) | ||
903 | budget = dev->quota; | ||
904 | rp = np->rx.sring->rsp_prod; | ||
905 | rmb(); /* Ensure we see queued responses up to 'rp'. */ | ||
906 | |||
907 | i = np->rx.rsp_cons; | ||
908 | work_done = 0; | ||
909 | while ((i != rp) && (work_done < budget)) { | ||
910 | memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx)); | ||
911 | memset(extras, 0, sizeof(rinfo.extras)); | ||
912 | |||
913 | err = xennet_get_responses(np, &rinfo, rp, &tmpq); | ||
914 | |||
915 | if (unlikely(err)) { | ||
916 | err: | ||
917 | while ((skb = __skb_dequeue(&tmpq))) | ||
918 | __skb_queue_tail(&errq, skb); | ||
919 | np->stats.rx_errors++; | ||
920 | i = np->rx.rsp_cons; | ||
921 | continue; | ||
922 | } | ||
923 | |||
924 | skb = __skb_dequeue(&tmpq); | ||
925 | |||
926 | if (extras[XEN_NETIF_EXTRA_TYPE_GSO - 1].type) { | ||
927 | struct xen_netif_extra_info *gso; | ||
928 | gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1]; | ||
929 | |||
930 | if (unlikely(xennet_set_skb_gso(skb, gso))) { | ||
931 | __skb_queue_head(&tmpq, skb); | ||
932 | np->rx.rsp_cons += skb_queue_len(&tmpq); | ||
933 | goto err; | ||
934 | } | ||
935 | } | ||
936 | |||
937 | NETFRONT_SKB_CB(skb)->page = skb_shinfo(skb)->frags[0].page; | ||
938 | NETFRONT_SKB_CB(skb)->offset = rx->offset; | ||
939 | |||
940 | len = rx->status; | ||
941 | if (len > RX_COPY_THRESHOLD) | ||
942 | len = RX_COPY_THRESHOLD; | ||
943 | skb_put(skb, len); | ||
944 | |||
945 | if (rx->status > len) { | ||
946 | skb_shinfo(skb)->frags[0].page_offset = | ||
947 | rx->offset + len; | ||
948 | skb_shinfo(skb)->frags[0].size = rx->status - len; | ||
949 | skb->data_len = rx->status - len; | ||
950 | } else { | ||
951 | skb_shinfo(skb)->frags[0].page = NULL; | ||
952 | skb_shinfo(skb)->nr_frags = 0; | ||
953 | } | ||
954 | |||
955 | i = xennet_fill_frags(np, skb, &tmpq); | ||
956 | |||
957 | /* | ||
958 | * Truesize approximates the size of true data plus | ||
959 | * any supervisor overheads. Adding hypervisor | ||
960 | * overheads has been shown to significantly reduce | ||
961 | * achievable bandwidth with the default receive | ||
962 | * buffer size. It is therefore not wise to account | ||
963 | * for it here. | ||
964 | * | ||
965 | * After alloc_skb(RX_COPY_THRESHOLD), truesize is set | ||
966 | * to RX_COPY_THRESHOLD + the supervisor | ||
967 | * overheads. Here, we add the size of the data pulled | ||
968 | * in xennet_fill_frags(). | ||
969 | * | ||
970 | * We also adjust for any unused space in the main | ||
971 | * data area by subtracting (RX_COPY_THRESHOLD - | ||
972 | * len). This is especially important with drivers | ||
973 | * which split incoming packets into header and data, | ||
974 | * using only 66 bytes of the main data area (see the | ||
975 | * e1000 driver for example.) On such systems, | ||
976 | * without this last adjustement, our achievable | ||
977 | * receive throughout using the standard receive | ||
978 | * buffer size was cut by 25%(!!!). | ||
979 | */ | ||
980 | skb->truesize += skb->data_len - (RX_COPY_THRESHOLD - len); | ||
981 | skb->len += skb->data_len; | ||
982 | |||
983 | if (rx->flags & NETRXF_csum_blank) | ||
984 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
985 | else if (rx->flags & NETRXF_data_validated) | ||
986 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
987 | |||
988 | __skb_queue_tail(&rxq, skb); | ||
989 | |||
990 | np->rx.rsp_cons = ++i; | ||
991 | work_done++; | ||
992 | } | ||
993 | |||
994 | while ((skb = __skb_dequeue(&errq))) | ||
995 | kfree_skb(skb); | ||
996 | |||
997 | work_done -= handle_incoming_queue(dev, &rxq); | ||
998 | |||
999 | /* If we get a callback with very few responses, reduce fill target. */ | ||
1000 | /* NB. Note exponential increase, linear decrease. */ | ||
1001 | if (((np->rx.req_prod_pvt - np->rx.sring->rsp_prod) > | ||
1002 | ((3*np->rx_target) / 4)) && | ||
1003 | (--np->rx_target < np->rx_min_target)) | ||
1004 | np->rx_target = np->rx_min_target; | ||
1005 | |||
1006 | xennet_alloc_rx_buffers(dev); | ||
1007 | |||
1008 | *pbudget -= work_done; | ||
1009 | dev->quota -= work_done; | ||
1010 | |||
1011 | if (work_done < budget) { | ||
1012 | local_irq_save(flags); | ||
1013 | |||
1014 | RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, more_to_do); | ||
1015 | if (!more_to_do) | ||
1016 | __netif_rx_complete(dev); | ||
1017 | |||
1018 | local_irq_restore(flags); | ||
1019 | } | ||
1020 | |||
1021 | spin_unlock(&np->rx_lock); | ||
1022 | |||
1023 | return more_to_do; | ||
1024 | } | ||
1025 | |||
1026 | static int xennet_change_mtu(struct net_device *dev, int mtu) | ||
1027 | { | ||
1028 | int max = xennet_can_sg(dev) ? 65535 - ETH_HLEN : ETH_DATA_LEN; | ||
1029 | |||
1030 | if (mtu > max) | ||
1031 | return -EINVAL; | ||
1032 | dev->mtu = mtu; | ||
1033 | return 0; | ||
1034 | } | ||
1035 | |||
1036 | static void xennet_release_tx_bufs(struct netfront_info *np) | ||
1037 | { | ||
1038 | struct sk_buff *skb; | ||
1039 | int i; | ||
1040 | |||
1041 | for (i = 0; i < NET_TX_RING_SIZE; i++) { | ||
1042 | /* Skip over entries which are actually freelist references */ | ||
1043 | if ((unsigned long)np->tx_skbs[i].skb < PAGE_OFFSET) | ||
1044 | continue; | ||
1045 | |||
1046 | skb = np->tx_skbs[i].skb; | ||
1047 | gnttab_end_foreign_access_ref(np->grant_tx_ref[i], | ||
1048 | GNTMAP_readonly); | ||
1049 | gnttab_release_grant_reference(&np->gref_tx_head, | ||
1050 | np->grant_tx_ref[i]); | ||
1051 | np->grant_tx_ref[i] = GRANT_INVALID_REF; | ||
1052 | add_id_to_freelist(&np->tx_skb_freelist, np->tx_skbs, i); | ||
1053 | dev_kfree_skb_irq(skb); | ||
1054 | } | ||
1055 | } | ||
1056 | |||
1057 | static void xennet_release_rx_bufs(struct netfront_info *np) | ||
1058 | { | ||
1059 | struct mmu_update *mmu = np->rx_mmu; | ||
1060 | struct multicall_entry *mcl = np->rx_mcl; | ||
1061 | struct sk_buff_head free_list; | ||
1062 | struct sk_buff *skb; | ||
1063 | unsigned long mfn; | ||
1064 | int xfer = 0, noxfer = 0, unused = 0; | ||
1065 | int id, ref; | ||
1066 | |||
1067 | dev_warn(&np->netdev->dev, "%s: fix me for copying receiver.\n", | ||
1068 | __func__); | ||
1069 | return; | ||
1070 | |||
1071 | skb_queue_head_init(&free_list); | ||
1072 | |||
1073 | spin_lock_bh(&np->rx_lock); | ||
1074 | |||
1075 | for (id = 0; id < NET_RX_RING_SIZE; id++) { | ||
1076 | ref = np->grant_rx_ref[id]; | ||
1077 | if (ref == GRANT_INVALID_REF) { | ||
1078 | unused++; | ||
1079 | continue; | ||
1080 | } | ||
1081 | |||
1082 | skb = np->rx_skbs[id]; | ||
1083 | mfn = gnttab_end_foreign_transfer_ref(ref); | ||
1084 | gnttab_release_grant_reference(&np->gref_rx_head, ref); | ||
1085 | np->grant_rx_ref[id] = GRANT_INVALID_REF; | ||
1086 | |||
1087 | if (0 == mfn) { | ||
1088 | skb_shinfo(skb)->nr_frags = 0; | ||
1089 | dev_kfree_skb(skb); | ||
1090 | noxfer++; | ||
1091 | continue; | ||
1092 | } | ||
1093 | |||
1094 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { | ||
1095 | /* Remap the page. */ | ||
1096 | struct page *page = skb_shinfo(skb)->frags[0].page; | ||
1097 | unsigned long pfn = page_to_pfn(page); | ||
1098 | void *vaddr = page_address(page); | ||
1099 | |||
1100 | MULTI_update_va_mapping(mcl, (unsigned long)vaddr, | ||
1101 | mfn_pte(mfn, PAGE_KERNEL), | ||
1102 | 0); | ||
1103 | mcl++; | ||
1104 | mmu->ptr = ((u64)mfn << PAGE_SHIFT) | ||
1105 | | MMU_MACHPHYS_UPDATE; | ||
1106 | mmu->val = pfn; | ||
1107 | mmu++; | ||
1108 | |||
1109 | set_phys_to_machine(pfn, mfn); | ||
1110 | } | ||
1111 | __skb_queue_tail(&free_list, skb); | ||
1112 | xfer++; | ||
1113 | } | ||
1114 | |||
1115 | dev_info(&np->netdev->dev, "%s: %d xfer, %d noxfer, %d unused\n", | ||
1116 | __func__, xfer, noxfer, unused); | ||
1117 | |||
1118 | if (xfer) { | ||
1119 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { | ||
1120 | /* Do all the remapping work and M2P updates. */ | ||
1121 | MULTI_mmu_update(mcl, np->rx_mmu, mmu - np->rx_mmu, | ||
1122 | 0, DOMID_SELF); | ||
1123 | mcl++; | ||
1124 | HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl); | ||
1125 | } | ||
1126 | } | ||
1127 | |||
1128 | while ((skb = __skb_dequeue(&free_list)) != NULL) | ||
1129 | dev_kfree_skb(skb); | ||
1130 | |||
1131 | spin_unlock_bh(&np->rx_lock); | ||
1132 | } | ||
1133 | |||
1134 | static void xennet_uninit(struct net_device *dev) | ||
1135 | { | ||
1136 | struct netfront_info *np = netdev_priv(dev); | ||
1137 | xennet_release_tx_bufs(np); | ||
1138 | xennet_release_rx_bufs(np); | ||
1139 | gnttab_free_grant_references(np->gref_tx_head); | ||
1140 | gnttab_free_grant_references(np->gref_rx_head); | ||
1141 | } | ||
1142 | |||
1143 | static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev) | ||
1144 | { | ||
1145 | int i, err; | ||
1146 | struct net_device *netdev; | ||
1147 | struct netfront_info *np; | ||
1148 | |||
1149 | netdev = alloc_etherdev(sizeof(struct netfront_info)); | ||
1150 | if (!netdev) { | ||
1151 | printk(KERN_WARNING "%s> alloc_etherdev failed.\n", | ||
1152 | __func__); | ||
1153 | return ERR_PTR(-ENOMEM); | ||
1154 | } | ||
1155 | |||
1156 | np = netdev_priv(netdev); | ||
1157 | np->xbdev = dev; | ||
1158 | |||
1159 | spin_lock_init(&np->tx_lock); | ||
1160 | spin_lock_init(&np->rx_lock); | ||
1161 | |||
1162 | skb_queue_head_init(&np->rx_batch); | ||
1163 | np->rx_target = RX_DFL_MIN_TARGET; | ||
1164 | np->rx_min_target = RX_DFL_MIN_TARGET; | ||
1165 | np->rx_max_target = RX_MAX_TARGET; | ||
1166 | |||
1167 | init_timer(&np->rx_refill_timer); | ||
1168 | np->rx_refill_timer.data = (unsigned long)netdev; | ||
1169 | np->rx_refill_timer.function = rx_refill_timeout; | ||
1170 | |||
1171 | /* Initialise tx_skbs as a free chain containing every entry. */ | ||
1172 | np->tx_skb_freelist = 0; | ||
1173 | for (i = 0; i < NET_TX_RING_SIZE; i++) { | ||
1174 | np->tx_skbs[i].link = i+1; | ||
1175 | np->grant_tx_ref[i] = GRANT_INVALID_REF; | ||
1176 | } | ||
1177 | |||
1178 | /* Clear out rx_skbs */ | ||
1179 | for (i = 0; i < NET_RX_RING_SIZE; i++) { | ||
1180 | np->rx_skbs[i] = NULL; | ||
1181 | np->grant_rx_ref[i] = GRANT_INVALID_REF; | ||
1182 | } | ||
1183 | |||
1184 | /* A grant for every tx ring slot */ | ||
1185 | if (gnttab_alloc_grant_references(TX_MAX_TARGET, | ||
1186 | &np->gref_tx_head) < 0) { | ||
1187 | printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n"); | ||
1188 | err = -ENOMEM; | ||
1189 | goto exit; | ||
1190 | } | ||
1191 | /* A grant for every rx ring slot */ | ||
1192 | if (gnttab_alloc_grant_references(RX_MAX_TARGET, | ||
1193 | &np->gref_rx_head) < 0) { | ||
1194 | printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n"); | ||
1195 | err = -ENOMEM; | ||
1196 | goto exit_free_tx; | ||
1197 | } | ||
1198 | |||
1199 | netdev->open = xennet_open; | ||
1200 | netdev->hard_start_xmit = xennet_start_xmit; | ||
1201 | netdev->stop = xennet_close; | ||
1202 | netdev->get_stats = xennet_get_stats; | ||
1203 | netdev->poll = xennet_poll; | ||
1204 | netdev->uninit = xennet_uninit; | ||
1205 | netdev->change_mtu = xennet_change_mtu; | ||
1206 | netdev->weight = 64; | ||
1207 | netdev->features = NETIF_F_IP_CSUM; | ||
1208 | |||
1209 | SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops); | ||
1210 | SET_MODULE_OWNER(netdev); | ||
1211 | SET_NETDEV_DEV(netdev, &dev->dev); | ||
1212 | |||
1213 | np->netdev = netdev; | ||
1214 | |||
1215 | netif_carrier_off(netdev); | ||
1216 | |||
1217 | return netdev; | ||
1218 | |||
1219 | exit_free_tx: | ||
1220 | gnttab_free_grant_references(np->gref_tx_head); | ||
1221 | exit: | ||
1222 | free_netdev(netdev); | ||
1223 | return ERR_PTR(err); | ||
1224 | } | ||
1225 | |||
1226 | /** | ||
1227 | * Entry point to this code when a new device is created. Allocate the basic | ||
1228 | * structures and the ring buffers for communication with the backend, and | ||
1229 | * inform the backend of the appropriate details for those. | ||
1230 | */ | ||
1231 | static int __devinit netfront_probe(struct xenbus_device *dev, | ||
1232 | const struct xenbus_device_id *id) | ||
1233 | { | ||
1234 | int err; | ||
1235 | struct net_device *netdev; | ||
1236 | struct netfront_info *info; | ||
1237 | |||
1238 | netdev = xennet_create_dev(dev); | ||
1239 | if (IS_ERR(netdev)) { | ||
1240 | err = PTR_ERR(netdev); | ||
1241 | xenbus_dev_fatal(dev, err, "creating netdev"); | ||
1242 | return err; | ||
1243 | } | ||
1244 | |||
1245 | info = netdev_priv(netdev); | ||
1246 | dev->dev.driver_data = info; | ||
1247 | |||
1248 | err = register_netdev(info->netdev); | ||
1249 | if (err) { | ||
1250 | printk(KERN_WARNING "%s: register_netdev err=%d\n", | ||
1251 | __func__, err); | ||
1252 | goto fail; | ||
1253 | } | ||
1254 | |||
1255 | err = xennet_sysfs_addif(info->netdev); | ||
1256 | if (err) { | ||
1257 | unregister_netdev(info->netdev); | ||
1258 | printk(KERN_WARNING "%s: add sysfs failed err=%d\n", | ||
1259 | __func__, err); | ||
1260 | goto fail; | ||
1261 | } | ||
1262 | |||
1263 | return 0; | ||
1264 | |||
1265 | fail: | ||
1266 | free_netdev(netdev); | ||
1267 | dev->dev.driver_data = NULL; | ||
1268 | return err; | ||
1269 | } | ||
1270 | |||
1271 | static void xennet_end_access(int ref, void *page) | ||
1272 | { | ||
1273 | /* This frees the page as a side-effect */ | ||
1274 | if (ref != GRANT_INVALID_REF) | ||
1275 | gnttab_end_foreign_access(ref, 0, (unsigned long)page); | ||
1276 | } | ||
1277 | |||
1278 | static void xennet_disconnect_backend(struct netfront_info *info) | ||
1279 | { | ||
1280 | /* Stop old i/f to prevent errors whilst we rebuild the state. */ | ||
1281 | spin_lock_bh(&info->rx_lock); | ||
1282 | spin_lock_irq(&info->tx_lock); | ||
1283 | netif_carrier_off(info->netdev); | ||
1284 | spin_unlock_irq(&info->tx_lock); | ||
1285 | spin_unlock_bh(&info->rx_lock); | ||
1286 | |||
1287 | if (info->netdev->irq) | ||
1288 | unbind_from_irqhandler(info->netdev->irq, info->netdev); | ||
1289 | info->evtchn = info->netdev->irq = 0; | ||
1290 | |||
1291 | /* End access and free the pages */ | ||
1292 | xennet_end_access(info->tx_ring_ref, info->tx.sring); | ||
1293 | xennet_end_access(info->rx_ring_ref, info->rx.sring); | ||
1294 | |||
1295 | info->tx_ring_ref = GRANT_INVALID_REF; | ||
1296 | info->rx_ring_ref = GRANT_INVALID_REF; | ||
1297 | info->tx.sring = NULL; | ||
1298 | info->rx.sring = NULL; | ||
1299 | } | ||
1300 | |||
1301 | /** | ||
1302 | * We are reconnecting to the backend, due to a suspend/resume, or a backend | ||
1303 | * driver restart. We tear down our netif structure and recreate it, but | ||
1304 | * leave the device-layer structures intact so that this is transparent to the | ||
1305 | * rest of the kernel. | ||
1306 | */ | ||
1307 | static int netfront_resume(struct xenbus_device *dev) | ||
1308 | { | ||
1309 | struct netfront_info *info = dev->dev.driver_data; | ||
1310 | |||
1311 | dev_dbg(&dev->dev, "%s\n", dev->nodename); | ||
1312 | |||
1313 | xennet_disconnect_backend(info); | ||
1314 | return 0; | ||
1315 | } | ||
1316 | |||
1317 | static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[]) | ||
1318 | { | ||
1319 | char *s, *e, *macstr; | ||
1320 | int i; | ||
1321 | |||
1322 | macstr = s = xenbus_read(XBT_NIL, dev->nodename, "mac", NULL); | ||
1323 | if (IS_ERR(macstr)) | ||
1324 | return PTR_ERR(macstr); | ||
1325 | |||
1326 | for (i = 0; i < ETH_ALEN; i++) { | ||
1327 | mac[i] = simple_strtoul(s, &e, 16); | ||
1328 | if ((s == e) || (*e != ((i == ETH_ALEN-1) ? '\0' : ':'))) { | ||
1329 | kfree(macstr); | ||
1330 | return -ENOENT; | ||
1331 | } | ||
1332 | s = e+1; | ||
1333 | } | ||
1334 | |||
1335 | kfree(macstr); | ||
1336 | return 0; | ||
1337 | } | ||
1338 | |||
1339 | static irqreturn_t xennet_interrupt(int irq, void *dev_id) | ||
1340 | { | ||
1341 | struct net_device *dev = dev_id; | ||
1342 | struct netfront_info *np = netdev_priv(dev); | ||
1343 | unsigned long flags; | ||
1344 | |||
1345 | spin_lock_irqsave(&np->tx_lock, flags); | ||
1346 | |||
1347 | if (likely(netif_carrier_ok(dev))) { | ||
1348 | xennet_tx_buf_gc(dev); | ||
1349 | /* Under tx_lock: protects access to rx shared-ring indexes. */ | ||
1350 | if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) | ||
1351 | netif_rx_schedule(dev); | ||
1352 | } | ||
1353 | |||
1354 | spin_unlock_irqrestore(&np->tx_lock, flags); | ||
1355 | |||
1356 | return IRQ_HANDLED; | ||
1357 | } | ||
1358 | |||
1359 | static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) | ||
1360 | { | ||
1361 | struct xen_netif_tx_sring *txs; | ||
1362 | struct xen_netif_rx_sring *rxs; | ||
1363 | int err; | ||
1364 | struct net_device *netdev = info->netdev; | ||
1365 | |||
1366 | info->tx_ring_ref = GRANT_INVALID_REF; | ||
1367 | info->rx_ring_ref = GRANT_INVALID_REF; | ||
1368 | info->rx.sring = NULL; | ||
1369 | info->tx.sring = NULL; | ||
1370 | netdev->irq = 0; | ||
1371 | |||
1372 | err = xen_net_read_mac(dev, netdev->dev_addr); | ||
1373 | if (err) { | ||
1374 | xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename); | ||
1375 | goto fail; | ||
1376 | } | ||
1377 | |||
1378 | txs = (struct xen_netif_tx_sring *)get_zeroed_page(GFP_KERNEL); | ||
1379 | if (!txs) { | ||
1380 | err = -ENOMEM; | ||
1381 | xenbus_dev_fatal(dev, err, "allocating tx ring page"); | ||
1382 | goto fail; | ||
1383 | } | ||
1384 | SHARED_RING_INIT(txs); | ||
1385 | FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE); | ||
1386 | |||
1387 | err = xenbus_grant_ring(dev, virt_to_mfn(txs)); | ||
1388 | if (err < 0) { | ||
1389 | free_page((unsigned long)txs); | ||
1390 | goto fail; | ||
1391 | } | ||
1392 | |||
1393 | info->tx_ring_ref = err; | ||
1394 | rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_KERNEL); | ||
1395 | if (!rxs) { | ||
1396 | err = -ENOMEM; | ||
1397 | xenbus_dev_fatal(dev, err, "allocating rx ring page"); | ||
1398 | goto fail; | ||
1399 | } | ||
1400 | SHARED_RING_INIT(rxs); | ||
1401 | FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE); | ||
1402 | |||
1403 | err = xenbus_grant_ring(dev, virt_to_mfn(rxs)); | ||
1404 | if (err < 0) { | ||
1405 | free_page((unsigned long)rxs); | ||
1406 | goto fail; | ||
1407 | } | ||
1408 | info->rx_ring_ref = err; | ||
1409 | |||
1410 | err = xenbus_alloc_evtchn(dev, &info->evtchn); | ||
1411 | if (err) | ||
1412 | goto fail; | ||
1413 | |||
1414 | err = bind_evtchn_to_irqhandler(info->evtchn, xennet_interrupt, | ||
1415 | IRQF_SAMPLE_RANDOM, netdev->name, | ||
1416 | netdev); | ||
1417 | if (err < 0) | ||
1418 | goto fail; | ||
1419 | netdev->irq = err; | ||
1420 | return 0; | ||
1421 | |||
1422 | fail: | ||
1423 | return err; | ||
1424 | } | ||
1425 | |||
1426 | /* Common code used when first setting up, and when resuming. */ | ||
1427 | static int talk_to_backend(struct xenbus_device *dev, | ||
1428 | struct netfront_info *info) | ||
1429 | { | ||
1430 | const char *message; | ||
1431 | struct xenbus_transaction xbt; | ||
1432 | int err; | ||
1433 | |||
1434 | /* Create shared ring, alloc event channel. */ | ||
1435 | err = setup_netfront(dev, info); | ||
1436 | if (err) | ||
1437 | goto out; | ||
1438 | |||
1439 | again: | ||
1440 | err = xenbus_transaction_start(&xbt); | ||
1441 | if (err) { | ||
1442 | xenbus_dev_fatal(dev, err, "starting transaction"); | ||
1443 | goto destroy_ring; | ||
1444 | } | ||
1445 | |||
1446 | err = xenbus_printf(xbt, dev->nodename, "tx-ring-ref", "%u", | ||
1447 | info->tx_ring_ref); | ||
1448 | if (err) { | ||
1449 | message = "writing tx ring-ref"; | ||
1450 | goto abort_transaction; | ||
1451 | } | ||
1452 | err = xenbus_printf(xbt, dev->nodename, "rx-ring-ref", "%u", | ||
1453 | info->rx_ring_ref); | ||
1454 | if (err) { | ||
1455 | message = "writing rx ring-ref"; | ||
1456 | goto abort_transaction; | ||
1457 | } | ||
1458 | err = xenbus_printf(xbt, dev->nodename, | ||
1459 | "event-channel", "%u", info->evtchn); | ||
1460 | if (err) { | ||
1461 | message = "writing event-channel"; | ||
1462 | goto abort_transaction; | ||
1463 | } | ||
1464 | |||
1465 | err = xenbus_printf(xbt, dev->nodename, "request-rx-copy", "%u", | ||
1466 | 1); | ||
1467 | if (err) { | ||
1468 | message = "writing request-rx-copy"; | ||
1469 | goto abort_transaction; | ||
1470 | } | ||
1471 | |||
1472 | err = xenbus_printf(xbt, dev->nodename, "feature-rx-notify", "%d", 1); | ||
1473 | if (err) { | ||
1474 | message = "writing feature-rx-notify"; | ||
1475 | goto abort_transaction; | ||
1476 | } | ||
1477 | |||
1478 | err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", 1); | ||
1479 | if (err) { | ||
1480 | message = "writing feature-sg"; | ||
1481 | goto abort_transaction; | ||
1482 | } | ||
1483 | |||
1484 | err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4", "%d", 1); | ||
1485 | if (err) { | ||
1486 | message = "writing feature-gso-tcpv4"; | ||
1487 | goto abort_transaction; | ||
1488 | } | ||
1489 | |||
1490 | err = xenbus_transaction_end(xbt, 0); | ||
1491 | if (err) { | ||
1492 | if (err == -EAGAIN) | ||
1493 | goto again; | ||
1494 | xenbus_dev_fatal(dev, err, "completing transaction"); | ||
1495 | goto destroy_ring; | ||
1496 | } | ||
1497 | |||
1498 | return 0; | ||
1499 | |||
1500 | abort_transaction: | ||
1501 | xenbus_transaction_end(xbt, 1); | ||
1502 | xenbus_dev_fatal(dev, err, "%s", message); | ||
1503 | destroy_ring: | ||
1504 | xennet_disconnect_backend(info); | ||
1505 | out: | ||
1506 | return err; | ||
1507 | } | ||
1508 | |||
1509 | static int xennet_set_sg(struct net_device *dev, u32 data) | ||
1510 | { | ||
1511 | if (data) { | ||
1512 | struct netfront_info *np = netdev_priv(dev); | ||
1513 | int val; | ||
1514 | |||
1515 | if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg", | ||
1516 | "%d", &val) < 0) | ||
1517 | val = 0; | ||
1518 | if (!val) | ||
1519 | return -ENOSYS; | ||
1520 | } else if (dev->mtu > ETH_DATA_LEN) | ||
1521 | dev->mtu = ETH_DATA_LEN; | ||
1522 | |||
1523 | return ethtool_op_set_sg(dev, data); | ||
1524 | } | ||
1525 | |||
1526 | static int xennet_set_tso(struct net_device *dev, u32 data) | ||
1527 | { | ||
1528 | if (data) { | ||
1529 | struct netfront_info *np = netdev_priv(dev); | ||
1530 | int val; | ||
1531 | |||
1532 | if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, | ||
1533 | "feature-gso-tcpv4", "%d", &val) < 0) | ||
1534 | val = 0; | ||
1535 | if (!val) | ||
1536 | return -ENOSYS; | ||
1537 | } | ||
1538 | |||
1539 | return ethtool_op_set_tso(dev, data); | ||
1540 | } | ||
1541 | |||
1542 | static void xennet_set_features(struct net_device *dev) | ||
1543 | { | ||
1544 | /* Turn off all GSO bits except ROBUST. */ | ||
1545 | dev->features &= (1 << NETIF_F_GSO_SHIFT) - 1; | ||
1546 | dev->features |= NETIF_F_GSO_ROBUST; | ||
1547 | xennet_set_sg(dev, 0); | ||
1548 | |||
1549 | /* We need checksum offload to enable scatter/gather and TSO. */ | ||
1550 | if (!(dev->features & NETIF_F_IP_CSUM)) | ||
1551 | return; | ||
1552 | |||
1553 | if (!xennet_set_sg(dev, 1)) | ||
1554 | xennet_set_tso(dev, 1); | ||
1555 | } | ||
1556 | |||
1557 | static int xennet_connect(struct net_device *dev) | ||
1558 | { | ||
1559 | struct netfront_info *np = netdev_priv(dev); | ||
1560 | int i, requeue_idx, err; | ||
1561 | struct sk_buff *skb; | ||
1562 | grant_ref_t ref; | ||
1563 | struct xen_netif_rx_request *req; | ||
1564 | unsigned int feature_rx_copy; | ||
1565 | |||
1566 | err = xenbus_scanf(XBT_NIL, np->xbdev->otherend, | ||
1567 | "feature-rx-copy", "%u", &feature_rx_copy); | ||
1568 | if (err != 1) | ||
1569 | feature_rx_copy = 0; | ||
1570 | |||
1571 | if (!feature_rx_copy) { | ||
1572 | dev_info(&dev->dev, | ||
1573 | "backend does not support copying recieve path"); | ||
1574 | return -ENODEV; | ||
1575 | } | ||
1576 | |||
1577 | err = talk_to_backend(np->xbdev, np); | ||
1578 | if (err) | ||
1579 | return err; | ||
1580 | |||
1581 | xennet_set_features(dev); | ||
1582 | |||
1583 | spin_lock_bh(&np->rx_lock); | ||
1584 | spin_lock_irq(&np->tx_lock); | ||
1585 | |||
1586 | /* Step 1: Discard all pending TX packet fragments. */ | ||
1587 | xennet_release_tx_bufs(np); | ||
1588 | |||
1589 | /* Step 2: Rebuild the RX buffer freelist and the RX ring itself. */ | ||
1590 | for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) { | ||
1591 | if (!np->rx_skbs[i]) | ||
1592 | continue; | ||
1593 | |||
1594 | skb = np->rx_skbs[requeue_idx] = xennet_get_rx_skb(np, i); | ||
1595 | ref = np->grant_rx_ref[requeue_idx] = xennet_get_rx_ref(np, i); | ||
1596 | req = RING_GET_REQUEST(&np->rx, requeue_idx); | ||
1597 | |||
1598 | gnttab_grant_foreign_access_ref( | ||
1599 | ref, np->xbdev->otherend_id, | ||
1600 | pfn_to_mfn(page_to_pfn(skb_shinfo(skb)-> | ||
1601 | frags->page)), | ||
1602 | 0); | ||
1603 | req->gref = ref; | ||
1604 | req->id = requeue_idx; | ||
1605 | |||
1606 | requeue_idx++; | ||
1607 | } | ||
1608 | |||
1609 | np->rx.req_prod_pvt = requeue_idx; | ||
1610 | |||
1611 | /* | ||
1612 | * Step 3: All public and private state should now be sane. Get | ||
1613 | * ready to start sending and receiving packets and give the driver | ||
1614 | * domain a kick because we've probably just requeued some | ||
1615 | * packets. | ||
1616 | */ | ||
1617 | netif_carrier_on(np->netdev); | ||
1618 | notify_remote_via_irq(np->netdev->irq); | ||
1619 | xennet_tx_buf_gc(dev); | ||
1620 | xennet_alloc_rx_buffers(dev); | ||
1621 | |||
1622 | spin_unlock_irq(&np->tx_lock); | ||
1623 | spin_unlock_bh(&np->rx_lock); | ||
1624 | |||
1625 | return 0; | ||
1626 | } | ||
1627 | |||
1628 | /** | ||
1629 | * Callback received when the backend's state changes. | ||
1630 | */ | ||
1631 | static void backend_changed(struct xenbus_device *dev, | ||
1632 | enum xenbus_state backend_state) | ||
1633 | { | ||
1634 | struct netfront_info *np = dev->dev.driver_data; | ||
1635 | struct net_device *netdev = np->netdev; | ||
1636 | |||
1637 | dev_dbg(&dev->dev, "%s\n", xenbus_strstate(backend_state)); | ||
1638 | |||
1639 | switch (backend_state) { | ||
1640 | case XenbusStateInitialising: | ||
1641 | case XenbusStateInitialised: | ||
1642 | case XenbusStateConnected: | ||
1643 | case XenbusStateUnknown: | ||
1644 | case XenbusStateClosed: | ||
1645 | break; | ||
1646 | |||
1647 | case XenbusStateInitWait: | ||
1648 | if (dev->state != XenbusStateInitialising) | ||
1649 | break; | ||
1650 | if (xennet_connect(netdev) != 0) | ||
1651 | break; | ||
1652 | xenbus_switch_state(dev, XenbusStateConnected); | ||
1653 | break; | ||
1654 | |||
1655 | case XenbusStateClosing: | ||
1656 | xenbus_frontend_closed(dev); | ||
1657 | break; | ||
1658 | } | ||
1659 | } | ||
1660 | |||
1661 | static struct ethtool_ops xennet_ethtool_ops = | ||
1662 | { | ||
1663 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
1664 | .set_tx_csum = ethtool_op_set_tx_csum, | ||
1665 | .get_sg = ethtool_op_get_sg, | ||
1666 | .set_sg = xennet_set_sg, | ||
1667 | .get_tso = ethtool_op_get_tso, | ||
1668 | .set_tso = xennet_set_tso, | ||
1669 | .get_link = ethtool_op_get_link, | ||
1670 | }; | ||
1671 | |||
1672 | #ifdef CONFIG_SYSFS | ||
1673 | static ssize_t show_rxbuf_min(struct device *dev, | ||
1674 | struct device_attribute *attr, char *buf) | ||
1675 | { | ||
1676 | struct net_device *netdev = to_net_dev(dev); | ||
1677 | struct netfront_info *info = netdev_priv(netdev); | ||
1678 | |||
1679 | return sprintf(buf, "%u\n", info->rx_min_target); | ||
1680 | } | ||
1681 | |||
1682 | static ssize_t store_rxbuf_min(struct device *dev, | ||
1683 | struct device_attribute *attr, | ||
1684 | const char *buf, size_t len) | ||
1685 | { | ||
1686 | struct net_device *netdev = to_net_dev(dev); | ||
1687 | struct netfront_info *np = netdev_priv(netdev); | ||
1688 | char *endp; | ||
1689 | unsigned long target; | ||
1690 | |||
1691 | if (!capable(CAP_NET_ADMIN)) | ||
1692 | return -EPERM; | ||
1693 | |||
1694 | target = simple_strtoul(buf, &endp, 0); | ||
1695 | if (endp == buf) | ||
1696 | return -EBADMSG; | ||
1697 | |||
1698 | if (target < RX_MIN_TARGET) | ||
1699 | target = RX_MIN_TARGET; | ||
1700 | if (target > RX_MAX_TARGET) | ||
1701 | target = RX_MAX_TARGET; | ||
1702 | |||
1703 | spin_lock_bh(&np->rx_lock); | ||
1704 | if (target > np->rx_max_target) | ||
1705 | np->rx_max_target = target; | ||
1706 | np->rx_min_target = target; | ||
1707 | if (target > np->rx_target) | ||
1708 | np->rx_target = target; | ||
1709 | |||
1710 | xennet_alloc_rx_buffers(netdev); | ||
1711 | |||
1712 | spin_unlock_bh(&np->rx_lock); | ||
1713 | return len; | ||
1714 | } | ||
1715 | |||
1716 | static ssize_t show_rxbuf_max(struct device *dev, | ||
1717 | struct device_attribute *attr, char *buf) | ||
1718 | { | ||
1719 | struct net_device *netdev = to_net_dev(dev); | ||
1720 | struct netfront_info *info = netdev_priv(netdev); | ||
1721 | |||
1722 | return sprintf(buf, "%u\n", info->rx_max_target); | ||
1723 | } | ||
1724 | |||
1725 | static ssize_t store_rxbuf_max(struct device *dev, | ||
1726 | struct device_attribute *attr, | ||
1727 | const char *buf, size_t len) | ||
1728 | { | ||
1729 | struct net_device *netdev = to_net_dev(dev); | ||
1730 | struct netfront_info *np = netdev_priv(netdev); | ||
1731 | char *endp; | ||
1732 | unsigned long target; | ||
1733 | |||
1734 | if (!capable(CAP_NET_ADMIN)) | ||
1735 | return -EPERM; | ||
1736 | |||
1737 | target = simple_strtoul(buf, &endp, 0); | ||
1738 | if (endp == buf) | ||
1739 | return -EBADMSG; | ||
1740 | |||
1741 | if (target < RX_MIN_TARGET) | ||
1742 | target = RX_MIN_TARGET; | ||
1743 | if (target > RX_MAX_TARGET) | ||
1744 | target = RX_MAX_TARGET; | ||
1745 | |||
1746 | spin_lock_bh(&np->rx_lock); | ||
1747 | if (target < np->rx_min_target) | ||
1748 | np->rx_min_target = target; | ||
1749 | np->rx_max_target = target; | ||
1750 | if (target < np->rx_target) | ||
1751 | np->rx_target = target; | ||
1752 | |||
1753 | xennet_alloc_rx_buffers(netdev); | ||
1754 | |||
1755 | spin_unlock_bh(&np->rx_lock); | ||
1756 | return len; | ||
1757 | } | ||
1758 | |||
1759 | static ssize_t show_rxbuf_cur(struct device *dev, | ||
1760 | struct device_attribute *attr, char *buf) | ||
1761 | { | ||
1762 | struct net_device *netdev = to_net_dev(dev); | ||
1763 | struct netfront_info *info = netdev_priv(netdev); | ||
1764 | |||
1765 | return sprintf(buf, "%u\n", info->rx_target); | ||
1766 | } | ||
1767 | |||
1768 | static struct device_attribute xennet_attrs[] = { | ||
1769 | __ATTR(rxbuf_min, S_IRUGO|S_IWUSR, show_rxbuf_min, store_rxbuf_min), | ||
1770 | __ATTR(rxbuf_max, S_IRUGO|S_IWUSR, show_rxbuf_max, store_rxbuf_max), | ||
1771 | __ATTR(rxbuf_cur, S_IRUGO, show_rxbuf_cur, NULL), | ||
1772 | }; | ||
1773 | |||
1774 | static int xennet_sysfs_addif(struct net_device *netdev) | ||
1775 | { | ||
1776 | int i; | ||
1777 | int err; | ||
1778 | |||
1779 | for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) { | ||
1780 | err = device_create_file(&netdev->dev, | ||
1781 | &xennet_attrs[i]); | ||
1782 | if (err) | ||
1783 | goto fail; | ||
1784 | } | ||
1785 | return 0; | ||
1786 | |||
1787 | fail: | ||
1788 | while (--i >= 0) | ||
1789 | device_remove_file(&netdev->dev, &xennet_attrs[i]); | ||
1790 | return err; | ||
1791 | } | ||
1792 | |||
1793 | static void xennet_sysfs_delif(struct net_device *netdev) | ||
1794 | { | ||
1795 | int i; | ||
1796 | |||
1797 | for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) | ||
1798 | device_remove_file(&netdev->dev, &xennet_attrs[i]); | ||
1799 | } | ||
1800 | |||
1801 | #endif /* CONFIG_SYSFS */ | ||
1802 | |||
1803 | static struct xenbus_device_id netfront_ids[] = { | ||
1804 | { "vif" }, | ||
1805 | { "" } | ||
1806 | }; | ||
1807 | |||
1808 | |||
1809 | static int __devexit xennet_remove(struct xenbus_device *dev) | ||
1810 | { | ||
1811 | struct netfront_info *info = dev->dev.driver_data; | ||
1812 | |||
1813 | dev_dbg(&dev->dev, "%s\n", dev->nodename); | ||
1814 | |||
1815 | unregister_netdev(info->netdev); | ||
1816 | |||
1817 | xennet_disconnect_backend(info); | ||
1818 | |||
1819 | del_timer_sync(&info->rx_refill_timer); | ||
1820 | |||
1821 | xennet_sysfs_delif(info->netdev); | ||
1822 | |||
1823 | free_netdev(info->netdev); | ||
1824 | |||
1825 | return 0; | ||
1826 | } | ||
1827 | |||
1828 | static struct xenbus_driver netfront = { | ||
1829 | .name = "vif", | ||
1830 | .owner = THIS_MODULE, | ||
1831 | .ids = netfront_ids, | ||
1832 | .probe = netfront_probe, | ||
1833 | .remove = __devexit_p(xennet_remove), | ||
1834 | .resume = netfront_resume, | ||
1835 | .otherend_changed = backend_changed, | ||
1836 | }; | ||
1837 | |||
1838 | static int __init netif_init(void) | ||
1839 | { | ||
1840 | if (!is_running_on_xen()) | ||
1841 | return -ENODEV; | ||
1842 | |||
1843 | if (is_initial_xendomain()) | ||
1844 | return 0; | ||
1845 | |||
1846 | printk(KERN_INFO "Initialising Xen virtual ethernet driver.\n"); | ||
1847 | |||
1848 | return xenbus_register_frontend(&netfront); | ||
1849 | } | ||
1850 | module_init(netif_init); | ||
1851 | |||
1852 | |||
1853 | static void __exit netif_exit(void) | ||
1854 | { | ||
1855 | if (is_initial_xendomain()) | ||
1856 | return; | ||
1857 | |||
1858 | return xenbus_unregister_driver(&netfront); | ||
1859 | } | ||
1860 | module_exit(netif_exit); | ||
1861 | |||
1862 | MODULE_DESCRIPTION("Xen virtual network device frontend"); | ||
1863 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index 03baf1c64a2e..ed112ee16012 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c | |||
@@ -147,7 +147,7 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info) | |||
147 | info->location_id, info->serial, info->capabilities); | 147 | info->location_id, info->serial, info->capabilities); |
148 | envp[i] = NULL; | 148 | envp[i] = NULL; |
149 | 149 | ||
150 | value = call_usermodehelper (argv [0], argv, envp, 0); | 150 | value = call_usermodehelper (argv [0], argv, envp, UMH_WAIT_EXEC); |
151 | kfree (buf); | 151 | kfree (buf); |
152 | kfree (envp); | 152 | kfree (envp); |
153 | return 0; | 153 | return 0; |
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index a54e4140683a..e821a155b658 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/kthread.h> | 7 | #include <linux/kthread.h> |
8 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
9 | #include <linux/kmod.h> | 9 | #include <linux/kmod.h> |
10 | #include <linux/reboot.h> | ||
10 | #include <asm/oplib.h> | 11 | #include <asm/oplib.h> |
11 | #include <asm/ebus.h> | 12 | #include <asm/ebus.h> |
12 | 13 | ||
@@ -170,8 +171,6 @@ static void get_current_temps(struct bbc_cpu_temperature *tp) | |||
170 | static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp) | 171 | static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp) |
171 | { | 172 | { |
172 | static int shutting_down = 0; | 173 | static int shutting_down = 0; |
173 | static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; | ||
174 | char *argv[] = { "/sbin/shutdown", "-h", "now", NULL }; | ||
175 | char *type = "???"; | 174 | char *type = "???"; |
176 | s8 val = -1; | 175 | s8 val = -1; |
177 | 176 | ||
@@ -195,7 +194,7 @@ static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp) | |||
195 | printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n"); | 194 | printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n"); |
196 | 195 | ||
197 | shutting_down = 1; | 196 | shutting_down = 1; |
198 | if (call_usermodehelper("/sbin/shutdown", argv, envp, 0) < 0) | 197 | if (orderly_poweroff(true) < 0) |
199 | printk(KERN_CRIT "envctrl: shutdown execution failed\n"); | 198 | printk(KERN_CRIT "envctrl: shutdown execution failed\n"); |
200 | } | 199 | } |
201 | 200 | ||
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index 8328acab47fd..dadabef116b6 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/ioport.h> | 26 | #include <linux/ioport.h> |
27 | #include <linux/miscdevice.h> | 27 | #include <linux/miscdevice.h> |
28 | #include <linux/kmod.h> | 28 | #include <linux/kmod.h> |
29 | #include <linux/reboot.h> | ||
29 | 30 | ||
30 | #include <asm/ebus.h> | 31 | #include <asm/ebus.h> |
31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
@@ -966,10 +967,6 @@ static struct i2c_child_t *envctrl_get_i2c_child(unsigned char mon_type) | |||
966 | static void envctrl_do_shutdown(void) | 967 | static void envctrl_do_shutdown(void) |
967 | { | 968 | { |
968 | static int inprog = 0; | 969 | static int inprog = 0; |
969 | static char *envp[] = { | ||
970 | "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; | ||
971 | char *argv[] = { | ||
972 | "/sbin/shutdown", "-h", "now", NULL }; | ||
973 | int ret; | 970 | int ret; |
974 | 971 | ||
975 | if (inprog != 0) | 972 | if (inprog != 0) |
@@ -977,7 +974,7 @@ static void envctrl_do_shutdown(void) | |||
977 | 974 | ||
978 | inprog = 1; | 975 | inprog = 1; |
979 | printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n"); | 976 | printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n"); |
980 | ret = call_usermodehelper("/sbin/shutdown", argv, envp, 0); | 977 | ret = orderly_poweroff(true); |
981 | if (ret < 0) { | 978 | if (ret < 0) { |
982 | printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); | 979 | printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); |
983 | inprog = 0; /* unlikely to succeed, but we could try again */ | 980 | inprog = 0; /* unlikely to succeed, but we could try again */ |
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile new file mode 100644 index 000000000000..56592f0d6cef --- /dev/null +++ b/drivers/xen/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | obj-y += grant-table.o | ||
2 | obj-y += xenbus/ | ||
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c new file mode 100644 index 000000000000..ea94dbabf9a9 --- /dev/null +++ b/drivers/xen/grant-table.c | |||
@@ -0,0 +1,582 @@ | |||
1 | /****************************************************************************** | ||
2 | * grant_table.c | ||
3 | * | ||
4 | * Granting foreign access to our memory reservation. | ||
5 | * | ||
6 | * Copyright (c) 2005-2006, Christopher Clark | ||
7 | * Copyright (c) 2004-2005, K A Fraser | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License version 2 | ||
11 | * as published by the Free Software Foundation; or, when distributed | ||
12 | * separately from the Linux kernel or incorporated into other | ||
13 | * software packages, subject to the following license: | ||
14 | * | ||
15 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
16 | * of this source file (the "Software"), to deal in the Software without | ||
17 | * restriction, including without limitation the rights to use, copy, modify, | ||
18 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
19 | * and to permit persons to whom the Software is furnished to do so, subject to | ||
20 | * the following conditions: | ||
21 | * | ||
22 | * The above copyright notice and this permission notice shall be included in | ||
23 | * all copies or substantial portions of the Software. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
26 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
27 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
28 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
29 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
30 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
31 | * IN THE SOFTWARE. | ||
32 | */ | ||
33 | |||
34 | #include <linux/module.h> | ||
35 | #include <linux/sched.h> | ||
36 | #include <linux/mm.h> | ||
37 | #include <linux/vmalloc.h> | ||
38 | #include <linux/uaccess.h> | ||
39 | |||
40 | #include <xen/interface/xen.h> | ||
41 | #include <xen/page.h> | ||
42 | #include <xen/grant_table.h> | ||
43 | |||
44 | #include <asm/pgtable.h> | ||
45 | #include <asm/sync_bitops.h> | ||
46 | |||
47 | |||
48 | /* External tools reserve first few grant table entries. */ | ||
49 | #define NR_RESERVED_ENTRIES 8 | ||
50 | #define GNTTAB_LIST_END 0xffffffff | ||
51 | #define GREFS_PER_GRANT_FRAME (PAGE_SIZE / sizeof(struct grant_entry)) | ||
52 | |||
53 | static grant_ref_t **gnttab_list; | ||
54 | static unsigned int nr_grant_frames; | ||
55 | static unsigned int boot_max_nr_grant_frames; | ||
56 | static int gnttab_free_count; | ||
57 | static grant_ref_t gnttab_free_head; | ||
58 | static DEFINE_SPINLOCK(gnttab_list_lock); | ||
59 | |||
60 | static struct grant_entry *shared; | ||
61 | |||
62 | static struct gnttab_free_callback *gnttab_free_callback_list; | ||
63 | |||
64 | static int gnttab_expand(unsigned int req_entries); | ||
65 | |||
66 | #define RPP (PAGE_SIZE / sizeof(grant_ref_t)) | ||
67 | |||
68 | static inline grant_ref_t *__gnttab_entry(grant_ref_t entry) | ||
69 | { | ||
70 | return &gnttab_list[(entry) / RPP][(entry) % RPP]; | ||
71 | } | ||
72 | /* This can be used as an l-value */ | ||
73 | #define gnttab_entry(entry) (*__gnttab_entry(entry)) | ||
74 | |||
75 | static int get_free_entries(unsigned count) | ||
76 | { | ||
77 | unsigned long flags; | ||
78 | int ref, rc; | ||
79 | grant_ref_t head; | ||
80 | |||
81 | spin_lock_irqsave(&gnttab_list_lock, flags); | ||
82 | |||
83 | if ((gnttab_free_count < count) && | ||
84 | ((rc = gnttab_expand(count - gnttab_free_count)) < 0)) { | ||
85 | spin_unlock_irqrestore(&gnttab_list_lock, flags); | ||
86 | return rc; | ||
87 | } | ||
88 | |||
89 | ref = head = gnttab_free_head; | ||
90 | gnttab_free_count -= count; | ||
91 | while (count-- > 1) | ||
92 | head = gnttab_entry(head); | ||
93 | gnttab_free_head = gnttab_entry(head); | ||
94 | gnttab_entry(head) = GNTTAB_LIST_END; | ||
95 | |||
96 | spin_unlock_irqrestore(&gnttab_list_lock, flags); | ||
97 | |||
98 | return ref; | ||
99 | } | ||
100 | |||
101 | static void do_free_callbacks(void) | ||
102 | { | ||
103 | struct gnttab_free_callback *callback, *next; | ||
104 | |||
105 | callback = gnttab_free_callback_list; | ||
106 | gnttab_free_callback_list = NULL; | ||
107 | |||
108 | while (callback != NULL) { | ||
109 | next = callback->next; | ||
110 | if (gnttab_free_count >= callback->count) { | ||
111 | callback->next = NULL; | ||
112 | callback->fn(callback->arg); | ||
113 | } else { | ||
114 | callback->next = gnttab_free_callback_list; | ||
115 | gnttab_free_callback_list = callback; | ||
116 | } | ||
117 | callback = next; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | static inline void check_free_callbacks(void) | ||
122 | { | ||
123 | if (unlikely(gnttab_free_callback_list)) | ||
124 | do_free_callbacks(); | ||
125 | } | ||
126 | |||
127 | static void put_free_entry(grant_ref_t ref) | ||
128 | { | ||
129 | unsigned long flags; | ||
130 | spin_lock_irqsave(&gnttab_list_lock, flags); | ||
131 | gnttab_entry(ref) = gnttab_free_head; | ||
132 | gnttab_free_head = ref; | ||
133 | gnttab_free_count++; | ||
134 | check_free_callbacks(); | ||
135 | spin_unlock_irqrestore(&gnttab_list_lock, flags); | ||
136 | } | ||
137 | |||
138 | static void update_grant_entry(grant_ref_t ref, domid_t domid, | ||
139 | unsigned long frame, unsigned flags) | ||
140 | { | ||
141 | /* | ||
142 | * Introducing a valid entry into the grant table: | ||
143 | * 1. Write ent->domid. | ||
144 | * 2. Write ent->frame: | ||
145 | * GTF_permit_access: Frame to which access is permitted. | ||
146 | * GTF_accept_transfer: Pseudo-phys frame slot being filled by new | ||
147 | * frame, or zero if none. | ||
148 | * 3. Write memory barrier (WMB). | ||
149 | * 4. Write ent->flags, inc. valid type. | ||
150 | */ | ||
151 | shared[ref].frame = frame; | ||
152 | shared[ref].domid = domid; | ||
153 | wmb(); | ||
154 | shared[ref].flags = flags; | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Public grant-issuing interface functions | ||
159 | */ | ||
160 | void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, | ||
161 | unsigned long frame, int readonly) | ||
162 | { | ||
163 | update_grant_entry(ref, domid, frame, | ||
164 | GTF_permit_access | (readonly ? GTF_readonly : 0)); | ||
165 | } | ||
166 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access_ref); | ||
167 | |||
168 | int gnttab_grant_foreign_access(domid_t domid, unsigned long frame, | ||
169 | int readonly) | ||
170 | { | ||
171 | int ref; | ||
172 | |||
173 | ref = get_free_entries(1); | ||
174 | if (unlikely(ref < 0)) | ||
175 | return -ENOSPC; | ||
176 | |||
177 | gnttab_grant_foreign_access_ref(ref, domid, frame, readonly); | ||
178 | |||
179 | return ref; | ||
180 | } | ||
181 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_access); | ||
182 | |||
183 | int gnttab_query_foreign_access(grant_ref_t ref) | ||
184 | { | ||
185 | u16 nflags; | ||
186 | |||
187 | nflags = shared[ref].flags; | ||
188 | |||
189 | return (nflags & (GTF_reading|GTF_writing)); | ||
190 | } | ||
191 | EXPORT_SYMBOL_GPL(gnttab_query_foreign_access); | ||
192 | |||
193 | int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) | ||
194 | { | ||
195 | u16 flags, nflags; | ||
196 | |||
197 | nflags = shared[ref].flags; | ||
198 | do { | ||
199 | flags = nflags; | ||
200 | if (flags & (GTF_reading|GTF_writing)) { | ||
201 | printk(KERN_ALERT "WARNING: g.e. still in use!\n"); | ||
202 | return 0; | ||
203 | } | ||
204 | } while ((nflags = sync_cmpxchg(&shared[ref].flags, flags, 0)) != flags); | ||
205 | |||
206 | return 1; | ||
207 | } | ||
208 | EXPORT_SYMBOL_GPL(gnttab_end_foreign_access_ref); | ||
209 | |||
210 | void gnttab_end_foreign_access(grant_ref_t ref, int readonly, | ||
211 | unsigned long page) | ||
212 | { | ||
213 | if (gnttab_end_foreign_access_ref(ref, readonly)) { | ||
214 | put_free_entry(ref); | ||
215 | if (page != 0) | ||
216 | free_page(page); | ||
217 | } else { | ||
218 | /* XXX This needs to be fixed so that the ref and page are | ||
219 | placed on a list to be freed up later. */ | ||
220 | printk(KERN_WARNING | ||
221 | "WARNING: leaking g.e. and page still in use!\n"); | ||
222 | } | ||
223 | } | ||
224 | EXPORT_SYMBOL_GPL(gnttab_end_foreign_access); | ||
225 | |||
226 | int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn) | ||
227 | { | ||
228 | int ref; | ||
229 | |||
230 | ref = get_free_entries(1); | ||
231 | if (unlikely(ref < 0)) | ||
232 | return -ENOSPC; | ||
233 | gnttab_grant_foreign_transfer_ref(ref, domid, pfn); | ||
234 | |||
235 | return ref; | ||
236 | } | ||
237 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer); | ||
238 | |||
239 | void gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid, | ||
240 | unsigned long pfn) | ||
241 | { | ||
242 | update_grant_entry(ref, domid, pfn, GTF_accept_transfer); | ||
243 | } | ||
244 | EXPORT_SYMBOL_GPL(gnttab_grant_foreign_transfer_ref); | ||
245 | |||
246 | unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref) | ||
247 | { | ||
248 | unsigned long frame; | ||
249 | u16 flags; | ||
250 | |||
251 | /* | ||
252 | * If a transfer is not even yet started, try to reclaim the grant | ||
253 | * reference and return failure (== 0). | ||
254 | */ | ||
255 | while (!((flags = shared[ref].flags) & GTF_transfer_committed)) { | ||
256 | if (sync_cmpxchg(&shared[ref].flags, flags, 0) == flags) | ||
257 | return 0; | ||
258 | cpu_relax(); | ||
259 | } | ||
260 | |||
261 | /* If a transfer is in progress then wait until it is completed. */ | ||
262 | while (!(flags & GTF_transfer_completed)) { | ||
263 | flags = shared[ref].flags; | ||
264 | cpu_relax(); | ||
265 | } | ||
266 | |||
267 | rmb(); /* Read the frame number /after/ reading completion status. */ | ||
268 | frame = shared[ref].frame; | ||
269 | BUG_ON(frame == 0); | ||
270 | |||
271 | return frame; | ||
272 | } | ||
273 | EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer_ref); | ||
274 | |||
275 | unsigned long gnttab_end_foreign_transfer(grant_ref_t ref) | ||
276 | { | ||
277 | unsigned long frame = gnttab_end_foreign_transfer_ref(ref); | ||
278 | put_free_entry(ref); | ||
279 | return frame; | ||
280 | } | ||
281 | EXPORT_SYMBOL_GPL(gnttab_end_foreign_transfer); | ||
282 | |||
283 | void gnttab_free_grant_reference(grant_ref_t ref) | ||
284 | { | ||
285 | put_free_entry(ref); | ||
286 | } | ||
287 | EXPORT_SYMBOL_GPL(gnttab_free_grant_reference); | ||
288 | |||
289 | void gnttab_free_grant_references(grant_ref_t head) | ||
290 | { | ||
291 | grant_ref_t ref; | ||
292 | unsigned long flags; | ||
293 | int count = 1; | ||
294 | if (head == GNTTAB_LIST_END) | ||
295 | return; | ||
296 | spin_lock_irqsave(&gnttab_list_lock, flags); | ||
297 | ref = head; | ||
298 | while (gnttab_entry(ref) != GNTTAB_LIST_END) { | ||
299 | ref = gnttab_entry(ref); | ||
300 | count++; | ||
301 | } | ||
302 | gnttab_entry(ref) = gnttab_free_head; | ||
303 | gnttab_free_head = head; | ||
304 | gnttab_free_count += count; | ||
305 | check_free_callbacks(); | ||
306 | spin_unlock_irqrestore(&gnttab_list_lock, flags); | ||
307 | } | ||
308 | EXPORT_SYMBOL_GPL(gnttab_free_grant_references); | ||
309 | |||
310 | int gnttab_alloc_grant_references(u16 count, grant_ref_t *head) | ||
311 | { | ||
312 | int h = get_free_entries(count); | ||
313 | |||
314 | if (h < 0) | ||
315 | return -ENOSPC; | ||
316 | |||
317 | *head = h; | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | EXPORT_SYMBOL_GPL(gnttab_alloc_grant_references); | ||
322 | |||
323 | int gnttab_empty_grant_references(const grant_ref_t *private_head) | ||
324 | { | ||
325 | return (*private_head == GNTTAB_LIST_END); | ||
326 | } | ||
327 | EXPORT_SYMBOL_GPL(gnttab_empty_grant_references); | ||
328 | |||
329 | int gnttab_claim_grant_reference(grant_ref_t *private_head) | ||
330 | { | ||
331 | grant_ref_t g = *private_head; | ||
332 | if (unlikely(g == GNTTAB_LIST_END)) | ||
333 | return -ENOSPC; | ||
334 | *private_head = gnttab_entry(g); | ||
335 | return g; | ||
336 | } | ||
337 | EXPORT_SYMBOL_GPL(gnttab_claim_grant_reference); | ||
338 | |||
339 | void gnttab_release_grant_reference(grant_ref_t *private_head, | ||
340 | grant_ref_t release) | ||
341 | { | ||
342 | gnttab_entry(release) = *private_head; | ||
343 | *private_head = release; | ||
344 | } | ||
345 | EXPORT_SYMBOL_GPL(gnttab_release_grant_reference); | ||
346 | |||
347 | void gnttab_request_free_callback(struct gnttab_free_callback *callback, | ||
348 | void (*fn)(void *), void *arg, u16 count) | ||
349 | { | ||
350 | unsigned long flags; | ||
351 | spin_lock_irqsave(&gnttab_list_lock, flags); | ||
352 | if (callback->next) | ||
353 | goto out; | ||
354 | callback->fn = fn; | ||
355 | callback->arg = arg; | ||
356 | callback->count = count; | ||
357 | callback->next = gnttab_free_callback_list; | ||
358 | gnttab_free_callback_list = callback; | ||
359 | check_free_callbacks(); | ||
360 | out: | ||
361 | spin_unlock_irqrestore(&gnttab_list_lock, flags); | ||
362 | } | ||
363 | EXPORT_SYMBOL_GPL(gnttab_request_free_callback); | ||
364 | |||
365 | void gnttab_cancel_free_callback(struct gnttab_free_callback *callback) | ||
366 | { | ||
367 | struct gnttab_free_callback **pcb; | ||
368 | unsigned long flags; | ||
369 | |||
370 | spin_lock_irqsave(&gnttab_list_lock, flags); | ||
371 | for (pcb = &gnttab_free_callback_list; *pcb; pcb = &(*pcb)->next) { | ||
372 | if (*pcb == callback) { | ||
373 | *pcb = callback->next; | ||
374 | break; | ||
375 | } | ||
376 | } | ||
377 | spin_unlock_irqrestore(&gnttab_list_lock, flags); | ||
378 | } | ||
379 | EXPORT_SYMBOL_GPL(gnttab_cancel_free_callback); | ||
380 | |||
381 | static int grow_gnttab_list(unsigned int more_frames) | ||
382 | { | ||
383 | unsigned int new_nr_grant_frames, extra_entries, i; | ||
384 | |||
385 | new_nr_grant_frames = nr_grant_frames + more_frames; | ||
386 | extra_entries = more_frames * GREFS_PER_GRANT_FRAME; | ||
387 | |||
388 | for (i = nr_grant_frames; i < new_nr_grant_frames; i++) { | ||
389 | gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_ATOMIC); | ||
390 | if (!gnttab_list[i]) | ||
391 | goto grow_nomem; | ||
392 | } | ||
393 | |||
394 | |||
395 | for (i = GREFS_PER_GRANT_FRAME * nr_grant_frames; | ||
396 | i < GREFS_PER_GRANT_FRAME * new_nr_grant_frames - 1; i++) | ||
397 | gnttab_entry(i) = i + 1; | ||
398 | |||
399 | gnttab_entry(i) = gnttab_free_head; | ||
400 | gnttab_free_head = GREFS_PER_GRANT_FRAME * nr_grant_frames; | ||
401 | gnttab_free_count += extra_entries; | ||
402 | |||
403 | nr_grant_frames = new_nr_grant_frames; | ||
404 | |||
405 | check_free_callbacks(); | ||
406 | |||
407 | return 0; | ||
408 | |||
409 | grow_nomem: | ||
410 | for ( ; i >= nr_grant_frames; i--) | ||
411 | free_page((unsigned long) gnttab_list[i]); | ||
412 | return -ENOMEM; | ||
413 | } | ||
414 | |||
415 | static unsigned int __max_nr_grant_frames(void) | ||
416 | { | ||
417 | struct gnttab_query_size query; | ||
418 | int rc; | ||
419 | |||
420 | query.dom = DOMID_SELF; | ||
421 | |||
422 | rc = HYPERVISOR_grant_table_op(GNTTABOP_query_size, &query, 1); | ||
423 | if ((rc < 0) || (query.status != GNTST_okay)) | ||
424 | return 4; /* Legacy max supported number of frames */ | ||
425 | |||
426 | return query.max_nr_frames; | ||
427 | } | ||
428 | |||
429 | static inline unsigned int max_nr_grant_frames(void) | ||
430 | { | ||
431 | unsigned int xen_max = __max_nr_grant_frames(); | ||
432 | |||
433 | if (xen_max > boot_max_nr_grant_frames) | ||
434 | return boot_max_nr_grant_frames; | ||
435 | return xen_max; | ||
436 | } | ||
437 | |||
438 | static int map_pte_fn(pte_t *pte, struct page *pmd_page, | ||
439 | unsigned long addr, void *data) | ||
440 | { | ||
441 | unsigned long **frames = (unsigned long **)data; | ||
442 | |||
443 | set_pte_at(&init_mm, addr, pte, mfn_pte((*frames)[0], PAGE_KERNEL)); | ||
444 | (*frames)++; | ||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | static int unmap_pte_fn(pte_t *pte, struct page *pmd_page, | ||
449 | unsigned long addr, void *data) | ||
450 | { | ||
451 | |||
452 | set_pte_at(&init_mm, addr, pte, __pte(0)); | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static int gnttab_map(unsigned int start_idx, unsigned int end_idx) | ||
457 | { | ||
458 | struct gnttab_setup_table setup; | ||
459 | unsigned long *frames; | ||
460 | unsigned int nr_gframes = end_idx + 1; | ||
461 | int rc; | ||
462 | |||
463 | frames = kmalloc(nr_gframes * sizeof(unsigned long), GFP_ATOMIC); | ||
464 | if (!frames) | ||
465 | return -ENOMEM; | ||
466 | |||
467 | setup.dom = DOMID_SELF; | ||
468 | setup.nr_frames = nr_gframes; | ||
469 | setup.frame_list = frames; | ||
470 | |||
471 | rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1); | ||
472 | if (rc == -ENOSYS) { | ||
473 | kfree(frames); | ||
474 | return -ENOSYS; | ||
475 | } | ||
476 | |||
477 | BUG_ON(rc || setup.status); | ||
478 | |||
479 | if (shared == NULL) { | ||
480 | struct vm_struct *area; | ||
481 | area = alloc_vm_area(PAGE_SIZE * max_nr_grant_frames()); | ||
482 | BUG_ON(area == NULL); | ||
483 | shared = area->addr; | ||
484 | } | ||
485 | rc = apply_to_page_range(&init_mm, (unsigned long)shared, | ||
486 | PAGE_SIZE * nr_gframes, | ||
487 | map_pte_fn, &frames); | ||
488 | BUG_ON(rc); | ||
489 | frames -= nr_gframes; /* adjust after map_pte_fn() */ | ||
490 | |||
491 | kfree(frames); | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | static int gnttab_resume(void) | ||
497 | { | ||
498 | if (max_nr_grant_frames() < nr_grant_frames) | ||
499 | return -ENOSYS; | ||
500 | return gnttab_map(0, nr_grant_frames - 1); | ||
501 | } | ||
502 | |||
503 | static int gnttab_suspend(void) | ||
504 | { | ||
505 | apply_to_page_range(&init_mm, (unsigned long)shared, | ||
506 | PAGE_SIZE * nr_grant_frames, | ||
507 | unmap_pte_fn, NULL); | ||
508 | |||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | static int gnttab_expand(unsigned int req_entries) | ||
513 | { | ||
514 | int rc; | ||
515 | unsigned int cur, extra; | ||
516 | |||
517 | cur = nr_grant_frames; | ||
518 | extra = ((req_entries + (GREFS_PER_GRANT_FRAME-1)) / | ||
519 | GREFS_PER_GRANT_FRAME); | ||
520 | if (cur + extra > max_nr_grant_frames()) | ||
521 | return -ENOSPC; | ||
522 | |||
523 | rc = gnttab_map(cur, cur + extra - 1); | ||
524 | if (rc == 0) | ||
525 | rc = grow_gnttab_list(extra); | ||
526 | |||
527 | return rc; | ||
528 | } | ||
529 | |||
530 | static int __devinit gnttab_init(void) | ||
531 | { | ||
532 | int i; | ||
533 | unsigned int max_nr_glist_frames; | ||
534 | unsigned int nr_init_grefs; | ||
535 | |||
536 | if (!is_running_on_xen()) | ||
537 | return -ENODEV; | ||
538 | |||
539 | nr_grant_frames = 1; | ||
540 | boot_max_nr_grant_frames = __max_nr_grant_frames(); | ||
541 | |||
542 | /* Determine the maximum number of frames required for the | ||
543 | * grant reference free list on the current hypervisor. | ||
544 | */ | ||
545 | max_nr_glist_frames = (boot_max_nr_grant_frames * | ||
546 | GREFS_PER_GRANT_FRAME / | ||
547 | (PAGE_SIZE / sizeof(grant_ref_t))); | ||
548 | |||
549 | gnttab_list = kmalloc(max_nr_glist_frames * sizeof(grant_ref_t *), | ||
550 | GFP_KERNEL); | ||
551 | if (gnttab_list == NULL) | ||
552 | return -ENOMEM; | ||
553 | |||
554 | for (i = 0; i < nr_grant_frames; i++) { | ||
555 | gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); | ||
556 | if (gnttab_list[i] == NULL) | ||
557 | goto ini_nomem; | ||
558 | } | ||
559 | |||
560 | if (gnttab_resume() < 0) | ||
561 | return -ENODEV; | ||
562 | |||
563 | nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME; | ||
564 | |||
565 | for (i = NR_RESERVED_ENTRIES; i < nr_init_grefs - 1; i++) | ||
566 | gnttab_entry(i) = i + 1; | ||
567 | |||
568 | gnttab_entry(nr_init_grefs - 1) = GNTTAB_LIST_END; | ||
569 | gnttab_free_count = nr_init_grefs - NR_RESERVED_ENTRIES; | ||
570 | gnttab_free_head = NR_RESERVED_ENTRIES; | ||
571 | |||
572 | printk("Grant table initialized\n"); | ||
573 | return 0; | ||
574 | |||
575 | ini_nomem: | ||
576 | for (i--; i >= 0; i--) | ||
577 | free_page((unsigned long)gnttab_list[i]); | ||
578 | kfree(gnttab_list); | ||
579 | return -ENOMEM; | ||
580 | } | ||
581 | |||
582 | core_initcall(gnttab_init); | ||
diff --git a/drivers/xen/xenbus/Makefile b/drivers/xen/xenbus/Makefile new file mode 100644 index 000000000000..5571f5b84223 --- /dev/null +++ b/drivers/xen/xenbus/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | obj-y += xenbus.o | ||
2 | |||
3 | xenbus-objs = | ||
4 | xenbus-objs += xenbus_client.o | ||
5 | xenbus-objs += xenbus_comms.o | ||
6 | xenbus-objs += xenbus_xs.o | ||
7 | xenbus-objs += xenbus_probe.o | ||
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c new file mode 100644 index 000000000000..9fd2f70ab46d --- /dev/null +++ b/drivers/xen/xenbus/xenbus_client.c | |||
@@ -0,0 +1,569 @@ | |||
1 | /****************************************************************************** | ||
2 | * Client-facing interface for the Xenbus driver. In other words, the | ||
3 | * interface between the Xenbus and the device-specific code, be it the | ||
4 | * frontend or the backend of that driver. | ||
5 | * | ||
6 | * Copyright (C) 2005 XenSource Ltd | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version 2 | ||
10 | * as published by the Free Software Foundation; or, when distributed | ||
11 | * separately from the Linux kernel or incorporated into other | ||
12 | * software packages, subject to the following license: | ||
13 | * | ||
14 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
15 | * of this source file (the "Software"), to deal in the Software without | ||
16 | * restriction, including without limitation the rights to use, copy, modify, | ||
17 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
18 | * and to permit persons to whom the Software is furnished to do so, subject to | ||
19 | * the following conditions: | ||
20 | * | ||
21 | * The above copyright notice and this permission notice shall be included in | ||
22 | * all copies or substantial portions of the Software. | ||
23 | * | ||
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
29 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
30 | * IN THE SOFTWARE. | ||
31 | */ | ||
32 | |||
33 | #include <linux/types.h> | ||
34 | #include <linux/vmalloc.h> | ||
35 | #include <asm/xen/hypervisor.h> | ||
36 | #include <xen/interface/xen.h> | ||
37 | #include <xen/interface/event_channel.h> | ||
38 | #include <xen/events.h> | ||
39 | #include <xen/grant_table.h> | ||
40 | #include <xen/xenbus.h> | ||
41 | |||
42 | const char *xenbus_strstate(enum xenbus_state state) | ||
43 | { | ||
44 | static const char *const name[] = { | ||
45 | [ XenbusStateUnknown ] = "Unknown", | ||
46 | [ XenbusStateInitialising ] = "Initialising", | ||
47 | [ XenbusStateInitWait ] = "InitWait", | ||
48 | [ XenbusStateInitialised ] = "Initialised", | ||
49 | [ XenbusStateConnected ] = "Connected", | ||
50 | [ XenbusStateClosing ] = "Closing", | ||
51 | [ XenbusStateClosed ] = "Closed", | ||
52 | }; | ||
53 | return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID"; | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(xenbus_strstate); | ||
56 | |||
57 | /** | ||
58 | * xenbus_watch_path - register a watch | ||
59 | * @dev: xenbus device | ||
60 | * @path: path to watch | ||
61 | * @watch: watch to register | ||
62 | * @callback: callback to register | ||
63 | * | ||
64 | * Register a @watch on the given path, using the given xenbus_watch structure | ||
65 | * for storage, and the given @callback function as the callback. Return 0 on | ||
66 | * success, or -errno on error. On success, the given @path will be saved as | ||
67 | * @watch->node, and remains the caller's to free. On error, @watch->node will | ||
68 | * be NULL, the device will switch to %XenbusStateClosing, and the error will | ||
69 | * be saved in the store. | ||
70 | */ | ||
71 | int xenbus_watch_path(struct xenbus_device *dev, const char *path, | ||
72 | struct xenbus_watch *watch, | ||
73 | void (*callback)(struct xenbus_watch *, | ||
74 | const char **, unsigned int)) | ||
75 | { | ||
76 | int err; | ||
77 | |||
78 | watch->node = path; | ||
79 | watch->callback = callback; | ||
80 | |||
81 | err = register_xenbus_watch(watch); | ||
82 | |||
83 | if (err) { | ||
84 | watch->node = NULL; | ||
85 | watch->callback = NULL; | ||
86 | xenbus_dev_fatal(dev, err, "adding watch on %s", path); | ||
87 | } | ||
88 | |||
89 | return err; | ||
90 | } | ||
91 | EXPORT_SYMBOL_GPL(xenbus_watch_path); | ||
92 | |||
93 | |||
94 | /** | ||
95 | * xenbus_watch_pathfmt - register a watch on a sprintf-formatted path | ||
96 | * @dev: xenbus device | ||
97 | * @watch: watch to register | ||
98 | * @callback: callback to register | ||
99 | * @pathfmt: format of path to watch | ||
100 | * | ||
101 | * Register a watch on the given @path, using the given xenbus_watch | ||
102 | * structure for storage, and the given @callback function as the callback. | ||
103 | * Return 0 on success, or -errno on error. On success, the watched path | ||
104 | * (@path/@path2) will be saved as @watch->node, and becomes the caller's to | ||
105 | * kfree(). On error, watch->node will be NULL, so the caller has nothing to | ||
106 | * free, the device will switch to %XenbusStateClosing, and the error will be | ||
107 | * saved in the store. | ||
108 | */ | ||
109 | int xenbus_watch_pathfmt(struct xenbus_device *dev, | ||
110 | struct xenbus_watch *watch, | ||
111 | void (*callback)(struct xenbus_watch *, | ||
112 | const char **, unsigned int), | ||
113 | const char *pathfmt, ...) | ||
114 | { | ||
115 | int err; | ||
116 | va_list ap; | ||
117 | char *path; | ||
118 | |||
119 | va_start(ap, pathfmt); | ||
120 | path = kvasprintf(GFP_KERNEL, pathfmt, ap); | ||
121 | va_end(ap); | ||
122 | |||
123 | if (!path) { | ||
124 | xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch"); | ||
125 | return -ENOMEM; | ||
126 | } | ||
127 | err = xenbus_watch_path(dev, path, watch, callback); | ||
128 | |||
129 | if (err) | ||
130 | kfree(path); | ||
131 | return err; | ||
132 | } | ||
133 | EXPORT_SYMBOL_GPL(xenbus_watch_pathfmt); | ||
134 | |||
135 | |||
136 | /** | ||
137 | * xenbus_switch_state | ||
138 | * @dev: xenbus device | ||
139 | * @xbt: transaction handle | ||
140 | * @state: new state | ||
141 | * | ||
142 | * Advertise in the store a change of the given driver to the given new_state. | ||
143 | * Return 0 on success, or -errno on error. On error, the device will switch | ||
144 | * to XenbusStateClosing, and the error will be saved in the store. | ||
145 | */ | ||
146 | int xenbus_switch_state(struct xenbus_device *dev, enum xenbus_state state) | ||
147 | { | ||
148 | /* We check whether the state is currently set to the given value, and | ||
149 | if not, then the state is set. We don't want to unconditionally | ||
150 | write the given state, because we don't want to fire watches | ||
151 | unnecessarily. Furthermore, if the node has gone, we don't write | ||
152 | to it, as the device will be tearing down, and we don't want to | ||
153 | resurrect that directory. | ||
154 | |||
155 | Note that, because of this cached value of our state, this function | ||
156 | will not work inside a Xenstore transaction (something it was | ||
157 | trying to in the past) because dev->state would not get reset if | ||
158 | the transaction was aborted. | ||
159 | |||
160 | */ | ||
161 | |||
162 | int current_state; | ||
163 | int err; | ||
164 | |||
165 | if (state == dev->state) | ||
166 | return 0; | ||
167 | |||
168 | err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d", | ||
169 | ¤t_state); | ||
170 | if (err != 1) | ||
171 | return 0; | ||
172 | |||
173 | err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state); | ||
174 | if (err) { | ||
175 | if (state != XenbusStateClosing) /* Avoid looping */ | ||
176 | xenbus_dev_fatal(dev, err, "writing new state"); | ||
177 | return err; | ||
178 | } | ||
179 | |||
180 | dev->state = state; | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | EXPORT_SYMBOL_GPL(xenbus_switch_state); | ||
185 | |||
186 | int xenbus_frontend_closed(struct xenbus_device *dev) | ||
187 | { | ||
188 | xenbus_switch_state(dev, XenbusStateClosed); | ||
189 | complete(&dev->down); | ||
190 | return 0; | ||
191 | } | ||
192 | EXPORT_SYMBOL_GPL(xenbus_frontend_closed); | ||
193 | |||
194 | /** | ||
195 | * Return the path to the error node for the given device, or NULL on failure. | ||
196 | * If the value returned is non-NULL, then it is the caller's to kfree. | ||
197 | */ | ||
198 | static char *error_path(struct xenbus_device *dev) | ||
199 | { | ||
200 | return kasprintf(GFP_KERNEL, "error/%s", dev->nodename); | ||
201 | } | ||
202 | |||
203 | |||
204 | static void xenbus_va_dev_error(struct xenbus_device *dev, int err, | ||
205 | const char *fmt, va_list ap) | ||
206 | { | ||
207 | int ret; | ||
208 | unsigned int len; | ||
209 | char *printf_buffer = NULL; | ||
210 | char *path_buffer = NULL; | ||
211 | |||
212 | #define PRINTF_BUFFER_SIZE 4096 | ||
213 | printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL); | ||
214 | if (printf_buffer == NULL) | ||
215 | goto fail; | ||
216 | |||
217 | len = sprintf(printf_buffer, "%i ", -err); | ||
218 | ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap); | ||
219 | |||
220 | BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1); | ||
221 | |||
222 | dev_err(&dev->dev, "%s\n", printf_buffer); | ||
223 | |||
224 | path_buffer = error_path(dev); | ||
225 | |||
226 | if (path_buffer == NULL) { | ||
227 | dev_err(&dev->dev, "failed to write error node for %s (%s)\n", | ||
228 | dev->nodename, printf_buffer); | ||
229 | goto fail; | ||
230 | } | ||
231 | |||
232 | if (xenbus_write(XBT_NIL, path_buffer, "error", printf_buffer) != 0) { | ||
233 | dev_err(&dev->dev, "failed to write error node for %s (%s)\n", | ||
234 | dev->nodename, printf_buffer); | ||
235 | goto fail; | ||
236 | } | ||
237 | |||
238 | fail: | ||
239 | kfree(printf_buffer); | ||
240 | kfree(path_buffer); | ||
241 | } | ||
242 | |||
243 | |||
244 | /** | ||
245 | * xenbus_dev_error | ||
246 | * @dev: xenbus device | ||
247 | * @err: error to report | ||
248 | * @fmt: error message format | ||
249 | * | ||
250 | * Report the given negative errno into the store, along with the given | ||
251 | * formatted message. | ||
252 | */ | ||
253 | void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...) | ||
254 | { | ||
255 | va_list ap; | ||
256 | |||
257 | va_start(ap, fmt); | ||
258 | xenbus_va_dev_error(dev, err, fmt, ap); | ||
259 | va_end(ap); | ||
260 | } | ||
261 | EXPORT_SYMBOL_GPL(xenbus_dev_error); | ||
262 | |||
263 | /** | ||
264 | * xenbus_dev_fatal | ||
265 | * @dev: xenbus device | ||
266 | * @err: error to report | ||
267 | * @fmt: error message format | ||
268 | * | ||
269 | * Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by | ||
270 | * xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly | ||
271 | * closedown of this driver and its peer. | ||
272 | */ | ||
273 | |||
274 | void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt, ...) | ||
275 | { | ||
276 | va_list ap; | ||
277 | |||
278 | va_start(ap, fmt); | ||
279 | xenbus_va_dev_error(dev, err, fmt, ap); | ||
280 | va_end(ap); | ||
281 | |||
282 | xenbus_switch_state(dev, XenbusStateClosing); | ||
283 | } | ||
284 | EXPORT_SYMBOL_GPL(xenbus_dev_fatal); | ||
285 | |||
286 | /** | ||
287 | * xenbus_grant_ring | ||
288 | * @dev: xenbus device | ||
289 | * @ring_mfn: mfn of ring to grant | ||
290 | |||
291 | * Grant access to the given @ring_mfn to the peer of the given device. Return | ||
292 | * 0 on success, or -errno on error. On error, the device will switch to | ||
293 | * XenbusStateClosing, and the error will be saved in the store. | ||
294 | */ | ||
295 | int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn) | ||
296 | { | ||
297 | int err = gnttab_grant_foreign_access(dev->otherend_id, ring_mfn, 0); | ||
298 | if (err < 0) | ||
299 | xenbus_dev_fatal(dev, err, "granting access to ring page"); | ||
300 | return err; | ||
301 | } | ||
302 | EXPORT_SYMBOL_GPL(xenbus_grant_ring); | ||
303 | |||
304 | |||
305 | /** | ||
306 | * Allocate an event channel for the given xenbus_device, assigning the newly | ||
307 | * created local port to *port. Return 0 on success, or -errno on error. On | ||
308 | * error, the device will switch to XenbusStateClosing, and the error will be | ||
309 | * saved in the store. | ||
310 | */ | ||
311 | int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port) | ||
312 | { | ||
313 | struct evtchn_alloc_unbound alloc_unbound; | ||
314 | int err; | ||
315 | |||
316 | alloc_unbound.dom = DOMID_SELF; | ||
317 | alloc_unbound.remote_dom = dev->otherend_id; | ||
318 | |||
319 | err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, | ||
320 | &alloc_unbound); | ||
321 | if (err) | ||
322 | xenbus_dev_fatal(dev, err, "allocating event channel"); | ||
323 | else | ||
324 | *port = alloc_unbound.port; | ||
325 | |||
326 | return err; | ||
327 | } | ||
328 | EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn); | ||
329 | |||
330 | |||
331 | /** | ||
332 | * Bind to an existing interdomain event channel in another domain. Returns 0 | ||
333 | * on success and stores the local port in *port. On error, returns -errno, | ||
334 | * switches the device to XenbusStateClosing, and saves the error in XenStore. | ||
335 | */ | ||
336 | int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port) | ||
337 | { | ||
338 | struct evtchn_bind_interdomain bind_interdomain; | ||
339 | int err; | ||
340 | |||
341 | bind_interdomain.remote_dom = dev->otherend_id; | ||
342 | bind_interdomain.remote_port = remote_port; | ||
343 | |||
344 | err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, | ||
345 | &bind_interdomain); | ||
346 | if (err) | ||
347 | xenbus_dev_fatal(dev, err, | ||
348 | "binding to event channel %d from domain %d", | ||
349 | remote_port, dev->otherend_id); | ||
350 | else | ||
351 | *port = bind_interdomain.local_port; | ||
352 | |||
353 | return err; | ||
354 | } | ||
355 | EXPORT_SYMBOL_GPL(xenbus_bind_evtchn); | ||
356 | |||
357 | |||
358 | /** | ||
359 | * Free an existing event channel. Returns 0 on success or -errno on error. | ||
360 | */ | ||
361 | int xenbus_free_evtchn(struct xenbus_device *dev, int port) | ||
362 | { | ||
363 | struct evtchn_close close; | ||
364 | int err; | ||
365 | |||
366 | close.port = port; | ||
367 | |||
368 | err = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); | ||
369 | if (err) | ||
370 | xenbus_dev_error(dev, err, "freeing event channel %d", port); | ||
371 | |||
372 | return err; | ||
373 | } | ||
374 | EXPORT_SYMBOL_GPL(xenbus_free_evtchn); | ||
375 | |||
376 | |||
377 | /** | ||
378 | * xenbus_map_ring_valloc | ||
379 | * @dev: xenbus device | ||
380 | * @gnt_ref: grant reference | ||
381 | * @vaddr: pointer to address to be filled out by mapping | ||
382 | * | ||
383 | * Based on Rusty Russell's skeleton driver's map_page. | ||
384 | * Map a page of memory into this domain from another domain's grant table. | ||
385 | * xenbus_map_ring_valloc allocates a page of virtual address space, maps the | ||
386 | * page to that address, and sets *vaddr to that address. | ||
387 | * Returns 0 on success, and GNTST_* (see xen/include/interface/grant_table.h) | ||
388 | * or -ENOMEM on error. If an error is returned, device will switch to | ||
389 | * XenbusStateClosing and the error message will be saved in XenStore. | ||
390 | */ | ||
391 | int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr) | ||
392 | { | ||
393 | struct gnttab_map_grant_ref op = { | ||
394 | .flags = GNTMAP_host_map, | ||
395 | .ref = gnt_ref, | ||
396 | .dom = dev->otherend_id, | ||
397 | }; | ||
398 | struct vm_struct *area; | ||
399 | |||
400 | *vaddr = NULL; | ||
401 | |||
402 | area = alloc_vm_area(PAGE_SIZE); | ||
403 | if (!area) | ||
404 | return -ENOMEM; | ||
405 | |||
406 | op.host_addr = (unsigned long)area->addr; | ||
407 | |||
408 | if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)) | ||
409 | BUG(); | ||
410 | |||
411 | if (op.status != GNTST_okay) { | ||
412 | free_vm_area(area); | ||
413 | xenbus_dev_fatal(dev, op.status, | ||
414 | "mapping in shared page %d from domain %d", | ||
415 | gnt_ref, dev->otherend_id); | ||
416 | return op.status; | ||
417 | } | ||
418 | |||
419 | /* Stuff the handle in an unused field */ | ||
420 | area->phys_addr = (unsigned long)op.handle; | ||
421 | |||
422 | *vaddr = area->addr; | ||
423 | return 0; | ||
424 | } | ||
425 | EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc); | ||
426 | |||
427 | |||
428 | /** | ||
429 | * xenbus_map_ring | ||
430 | * @dev: xenbus device | ||
431 | * @gnt_ref: grant reference | ||
432 | * @handle: pointer to grant handle to be filled | ||
433 | * @vaddr: address to be mapped to | ||
434 | * | ||
435 | * Map a page of memory into this domain from another domain's grant table. | ||
436 | * xenbus_map_ring does not allocate the virtual address space (you must do | ||
437 | * this yourself!). It only maps in the page to the specified address. | ||
438 | * Returns 0 on success, and GNTST_* (see xen/include/interface/grant_table.h) | ||
439 | * or -ENOMEM on error. If an error is returned, device will switch to | ||
440 | * XenbusStateClosing and the error message will be saved in XenStore. | ||
441 | */ | ||
442 | int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref, | ||
443 | grant_handle_t *handle, void *vaddr) | ||
444 | { | ||
445 | struct gnttab_map_grant_ref op = { | ||
446 | .host_addr = (unsigned long)vaddr, | ||
447 | .flags = GNTMAP_host_map, | ||
448 | .ref = gnt_ref, | ||
449 | .dom = dev->otherend_id, | ||
450 | }; | ||
451 | |||
452 | if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)) | ||
453 | BUG(); | ||
454 | |||
455 | if (op.status != GNTST_okay) { | ||
456 | xenbus_dev_fatal(dev, op.status, | ||
457 | "mapping in shared page %d from domain %d", | ||
458 | gnt_ref, dev->otherend_id); | ||
459 | } else | ||
460 | *handle = op.handle; | ||
461 | |||
462 | return op.status; | ||
463 | } | ||
464 | EXPORT_SYMBOL_GPL(xenbus_map_ring); | ||
465 | |||
466 | |||
467 | /** | ||
468 | * xenbus_unmap_ring_vfree | ||
469 | * @dev: xenbus device | ||
470 | * @vaddr: addr to unmap | ||
471 | * | ||
472 | * Based on Rusty Russell's skeleton driver's unmap_page. | ||
473 | * Unmap a page of memory in this domain that was imported from another domain. | ||
474 | * Use xenbus_unmap_ring_vfree if you mapped in your memory with | ||
475 | * xenbus_map_ring_valloc (it will free the virtual address space). | ||
476 | * Returns 0 on success and returns GNTST_* on error | ||
477 | * (see xen/include/interface/grant_table.h). | ||
478 | */ | ||
479 | int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr) | ||
480 | { | ||
481 | struct vm_struct *area; | ||
482 | struct gnttab_unmap_grant_ref op = { | ||
483 | .host_addr = (unsigned long)vaddr, | ||
484 | }; | ||
485 | |||
486 | /* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr) | ||
487 | * method so that we don't have to muck with vmalloc internals here. | ||
488 | * We could force the user to hang on to their struct vm_struct from | ||
489 | * xenbus_map_ring_valloc, but these 6 lines considerably simplify | ||
490 | * this API. | ||
491 | */ | ||
492 | read_lock(&vmlist_lock); | ||
493 | for (area = vmlist; area != NULL; area = area->next) { | ||
494 | if (area->addr == vaddr) | ||
495 | break; | ||
496 | } | ||
497 | read_unlock(&vmlist_lock); | ||
498 | |||
499 | if (!area) { | ||
500 | xenbus_dev_error(dev, -ENOENT, | ||
501 | "can't find mapped virtual address %p", vaddr); | ||
502 | return GNTST_bad_virt_addr; | ||
503 | } | ||
504 | |||
505 | op.handle = (grant_handle_t)area->phys_addr; | ||
506 | |||
507 | if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)) | ||
508 | BUG(); | ||
509 | |||
510 | if (op.status == GNTST_okay) | ||
511 | free_vm_area(area); | ||
512 | else | ||
513 | xenbus_dev_error(dev, op.status, | ||
514 | "unmapping page at handle %d error %d", | ||
515 | (int16_t)area->phys_addr, op.status); | ||
516 | |||
517 | return op.status; | ||
518 | } | ||
519 | EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree); | ||
520 | |||
521 | |||
522 | /** | ||
523 | * xenbus_unmap_ring | ||
524 | * @dev: xenbus device | ||
525 | * @handle: grant handle | ||
526 | * @vaddr: addr to unmap | ||
527 | * | ||
528 | * Unmap a page of memory in this domain that was imported from another domain. | ||
529 | * Returns 0 on success and returns GNTST_* on error | ||
530 | * (see xen/include/interface/grant_table.h). | ||
531 | */ | ||
532 | int xenbus_unmap_ring(struct xenbus_device *dev, | ||
533 | grant_handle_t handle, void *vaddr) | ||
534 | { | ||
535 | struct gnttab_unmap_grant_ref op = { | ||
536 | .host_addr = (unsigned long)vaddr, | ||
537 | .handle = handle, | ||
538 | }; | ||
539 | |||
540 | if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)) | ||
541 | BUG(); | ||
542 | |||
543 | if (op.status != GNTST_okay) | ||
544 | xenbus_dev_error(dev, op.status, | ||
545 | "unmapping page at handle %d error %d", | ||
546 | handle, op.status); | ||
547 | |||
548 | return op.status; | ||
549 | } | ||
550 | EXPORT_SYMBOL_GPL(xenbus_unmap_ring); | ||
551 | |||
552 | |||
553 | /** | ||
554 | * xenbus_read_driver_state | ||
555 | * @path: path for driver | ||
556 | * | ||
557 | * Return the state of the driver rooted at the given store path, or | ||
558 | * XenbusStateUnknown if no state can be read. | ||
559 | */ | ||
560 | enum xenbus_state xenbus_read_driver_state(const char *path) | ||
561 | { | ||
562 | enum xenbus_state result; | ||
563 | int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL); | ||
564 | if (err) | ||
565 | result = XenbusStateUnknown; | ||
566 | |||
567 | return result; | ||
568 | } | ||
569 | EXPORT_SYMBOL_GPL(xenbus_read_driver_state); | ||
diff --git a/drivers/xen/xenbus/xenbus_comms.c b/drivers/xen/xenbus/xenbus_comms.c new file mode 100644 index 000000000000..6efbe3f29ca5 --- /dev/null +++ b/drivers/xen/xenbus/xenbus_comms.c | |||
@@ -0,0 +1,233 @@ | |||
1 | /****************************************************************************** | ||
2 | * xenbus_comms.c | ||
3 | * | ||
4 | * Low level code to talks to Xen Store: ringbuffer and event channel. | ||
5 | * | ||
6 | * Copyright (C) 2005 Rusty Russell, IBM Corporation | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version 2 | ||
10 | * as published by the Free Software Foundation; or, when distributed | ||
11 | * separately from the Linux kernel or incorporated into other | ||
12 | * software packages, subject to the following license: | ||
13 | * | ||
14 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
15 | * of this source file (the "Software"), to deal in the Software without | ||
16 | * restriction, including without limitation the rights to use, copy, modify, | ||
17 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
18 | * and to permit persons to whom the Software is furnished to do so, subject to | ||
19 | * the following conditions: | ||
20 | * | ||
21 | * The above copyright notice and this permission notice shall be included in | ||
22 | * all copies or substantial portions of the Software. | ||
23 | * | ||
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
29 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
30 | * IN THE SOFTWARE. | ||
31 | */ | ||
32 | |||
33 | #include <linux/wait.h> | ||
34 | #include <linux/interrupt.h> | ||
35 | #include <linux/sched.h> | ||
36 | #include <linux/err.h> | ||
37 | #include <xen/xenbus.h> | ||
38 | #include <asm/xen/hypervisor.h> | ||
39 | #include <xen/events.h> | ||
40 | #include <xen/page.h> | ||
41 | #include "xenbus_comms.h" | ||
42 | |||
43 | static int xenbus_irq; | ||
44 | |||
45 | static DECLARE_WORK(probe_work, xenbus_probe); | ||
46 | |||
47 | static DECLARE_WAIT_QUEUE_HEAD(xb_waitq); | ||
48 | |||
49 | static irqreturn_t wake_waiting(int irq, void *unused) | ||
50 | { | ||
51 | if (unlikely(xenstored_ready == 0)) { | ||
52 | xenstored_ready = 1; | ||
53 | schedule_work(&probe_work); | ||
54 | } | ||
55 | |||
56 | wake_up(&xb_waitq); | ||
57 | return IRQ_HANDLED; | ||
58 | } | ||
59 | |||
60 | static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod) | ||
61 | { | ||
62 | return ((prod - cons) <= XENSTORE_RING_SIZE); | ||
63 | } | ||
64 | |||
65 | static void *get_output_chunk(XENSTORE_RING_IDX cons, | ||
66 | XENSTORE_RING_IDX prod, | ||
67 | char *buf, uint32_t *len) | ||
68 | { | ||
69 | *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod); | ||
70 | if ((XENSTORE_RING_SIZE - (prod - cons)) < *len) | ||
71 | *len = XENSTORE_RING_SIZE - (prod - cons); | ||
72 | return buf + MASK_XENSTORE_IDX(prod); | ||
73 | } | ||
74 | |||
75 | static const void *get_input_chunk(XENSTORE_RING_IDX cons, | ||
76 | XENSTORE_RING_IDX prod, | ||
77 | const char *buf, uint32_t *len) | ||
78 | { | ||
79 | *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons); | ||
80 | if ((prod - cons) < *len) | ||
81 | *len = prod - cons; | ||
82 | return buf + MASK_XENSTORE_IDX(cons); | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * xb_write - low level write | ||
87 | * @data: buffer to send | ||
88 | * @len: length of buffer | ||
89 | * | ||
90 | * Returns 0 on success, error otherwise. | ||
91 | */ | ||
92 | int xb_write(const void *data, unsigned len) | ||
93 | { | ||
94 | struct xenstore_domain_interface *intf = xen_store_interface; | ||
95 | XENSTORE_RING_IDX cons, prod; | ||
96 | int rc; | ||
97 | |||
98 | while (len != 0) { | ||
99 | void *dst; | ||
100 | unsigned int avail; | ||
101 | |||
102 | rc = wait_event_interruptible( | ||
103 | xb_waitq, | ||
104 | (intf->req_prod - intf->req_cons) != | ||
105 | XENSTORE_RING_SIZE); | ||
106 | if (rc < 0) | ||
107 | return rc; | ||
108 | |||
109 | /* Read indexes, then verify. */ | ||
110 | cons = intf->req_cons; | ||
111 | prod = intf->req_prod; | ||
112 | if (!check_indexes(cons, prod)) { | ||
113 | intf->req_cons = intf->req_prod = 0; | ||
114 | return -EIO; | ||
115 | } | ||
116 | |||
117 | dst = get_output_chunk(cons, prod, intf->req, &avail); | ||
118 | if (avail == 0) | ||
119 | continue; | ||
120 | if (avail > len) | ||
121 | avail = len; | ||
122 | |||
123 | /* Must write data /after/ reading the consumer index. */ | ||
124 | mb(); | ||
125 | |||
126 | memcpy(dst, data, avail); | ||
127 | data += avail; | ||
128 | len -= avail; | ||
129 | |||
130 | /* Other side must not see new producer until data is there. */ | ||
131 | wmb(); | ||
132 | intf->req_prod += avail; | ||
133 | |||
134 | /* Implies mb(): other side will see the updated producer. */ | ||
135 | notify_remote_via_evtchn(xen_store_evtchn); | ||
136 | } | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | int xb_data_to_read(void) | ||
142 | { | ||
143 | struct xenstore_domain_interface *intf = xen_store_interface; | ||
144 | return (intf->rsp_cons != intf->rsp_prod); | ||
145 | } | ||
146 | |||
147 | int xb_wait_for_data_to_read(void) | ||
148 | { | ||
149 | return wait_event_interruptible(xb_waitq, xb_data_to_read()); | ||
150 | } | ||
151 | |||
152 | int xb_read(void *data, unsigned len) | ||
153 | { | ||
154 | struct xenstore_domain_interface *intf = xen_store_interface; | ||
155 | XENSTORE_RING_IDX cons, prod; | ||
156 | int rc; | ||
157 | |||
158 | while (len != 0) { | ||
159 | unsigned int avail; | ||
160 | const char *src; | ||
161 | |||
162 | rc = xb_wait_for_data_to_read(); | ||
163 | if (rc < 0) | ||
164 | return rc; | ||
165 | |||
166 | /* Read indexes, then verify. */ | ||
167 | cons = intf->rsp_cons; | ||
168 | prod = intf->rsp_prod; | ||
169 | if (!check_indexes(cons, prod)) { | ||
170 | intf->rsp_cons = intf->rsp_prod = 0; | ||
171 | return -EIO; | ||
172 | } | ||
173 | |||
174 | src = get_input_chunk(cons, prod, intf->rsp, &avail); | ||
175 | if (avail == 0) | ||
176 | continue; | ||
177 | if (avail > len) | ||
178 | avail = len; | ||
179 | |||
180 | /* Must read data /after/ reading the producer index. */ | ||
181 | rmb(); | ||
182 | |||
183 | memcpy(data, src, avail); | ||
184 | data += avail; | ||
185 | len -= avail; | ||
186 | |||
187 | /* Other side must not see free space until we've copied out */ | ||
188 | mb(); | ||
189 | intf->rsp_cons += avail; | ||
190 | |||
191 | pr_debug("Finished read of %i bytes (%i to go)\n", avail, len); | ||
192 | |||
193 | /* Implies mb(): other side will see the updated consumer. */ | ||
194 | notify_remote_via_evtchn(xen_store_evtchn); | ||
195 | } | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | * xb_init_comms - Set up interrupt handler off store event channel. | ||
202 | */ | ||
203 | int xb_init_comms(void) | ||
204 | { | ||
205 | struct xenstore_domain_interface *intf = xen_store_interface; | ||
206 | int err; | ||
207 | |||
208 | if (intf->req_prod != intf->req_cons) | ||
209 | printk(KERN_ERR "XENBUS request ring is not quiescent " | ||
210 | "(%08x:%08x)!\n", intf->req_cons, intf->req_prod); | ||
211 | |||
212 | if (intf->rsp_prod != intf->rsp_cons) { | ||
213 | printk(KERN_WARNING "XENBUS response ring is not quiescent " | ||
214 | "(%08x:%08x): fixing up\n", | ||
215 | intf->rsp_cons, intf->rsp_prod); | ||
216 | intf->rsp_cons = intf->rsp_prod; | ||
217 | } | ||
218 | |||
219 | if (xenbus_irq) | ||
220 | unbind_from_irqhandler(xenbus_irq, &xb_waitq); | ||
221 | |||
222 | err = bind_evtchn_to_irqhandler( | ||
223 | xen_store_evtchn, wake_waiting, | ||
224 | 0, "xenbus", &xb_waitq); | ||
225 | if (err <= 0) { | ||
226 | printk(KERN_ERR "XENBUS request irq failed %i\n", err); | ||
227 | return err; | ||
228 | } | ||
229 | |||
230 | xenbus_irq = err; | ||
231 | |||
232 | return 0; | ||
233 | } | ||
diff --git a/drivers/xen/xenbus/xenbus_comms.h b/drivers/xen/xenbus/xenbus_comms.h new file mode 100644 index 000000000000..c21db7513736 --- /dev/null +++ b/drivers/xen/xenbus/xenbus_comms.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * Private include for xenbus communications. | ||
3 | * | ||
4 | * Copyright (C) 2005 Rusty Russell, IBM Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation; or, when distributed | ||
9 | * separately from the Linux kernel or incorporated into other | ||
10 | * software packages, subject to the following license: | ||
11 | * | ||
12 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
13 | * of this source file (the "Software"), to deal in the Software without | ||
14 | * restriction, including without limitation the rights to use, copy, modify, | ||
15 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
16 | * and to permit persons to whom the Software is furnished to do so, subject to | ||
17 | * the following conditions: | ||
18 | * | ||
19 | * The above copyright notice and this permission notice shall be included in | ||
20 | * all copies or substantial portions of the Software. | ||
21 | * | ||
22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
23 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
24 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
25 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
26 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
27 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
28 | * IN THE SOFTWARE. | ||
29 | */ | ||
30 | |||
31 | #ifndef _XENBUS_COMMS_H | ||
32 | #define _XENBUS_COMMS_H | ||
33 | |||
34 | int xs_init(void); | ||
35 | int xb_init_comms(void); | ||
36 | |||
37 | /* Low level routines. */ | ||
38 | int xb_write(const void *data, unsigned len); | ||
39 | int xb_read(void *data, unsigned len); | ||
40 | int xb_data_to_read(void); | ||
41 | int xb_wait_for_data_to_read(void); | ||
42 | int xs_input_avail(void); | ||
43 | extern struct xenstore_domain_interface *xen_store_interface; | ||
44 | extern int xen_store_evtchn; | ||
45 | |||
46 | #endif /* _XENBUS_COMMS_H */ | ||
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c new file mode 100644 index 000000000000..0b769f7c4a48 --- /dev/null +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
@@ -0,0 +1,935 @@ | |||
1 | /****************************************************************************** | ||
2 | * Talks to Xen Store to figure out what devices we have. | ||
3 | * | ||
4 | * Copyright (C) 2005 Rusty Russell, IBM Corporation | ||
5 | * Copyright (C) 2005 Mike Wray, Hewlett-Packard | ||
6 | * Copyright (C) 2005, 2006 XenSource Ltd | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version 2 | ||
10 | * as published by the Free Software Foundation; or, when distributed | ||
11 | * separately from the Linux kernel or incorporated into other | ||
12 | * software packages, subject to the following license: | ||
13 | * | ||
14 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
15 | * of this source file (the "Software"), to deal in the Software without | ||
16 | * restriction, including without limitation the rights to use, copy, modify, | ||
17 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
18 | * and to permit persons to whom the Software is furnished to do so, subject to | ||
19 | * the following conditions: | ||
20 | * | ||
21 | * The above copyright notice and this permission notice shall be included in | ||
22 | * all copies or substantial portions of the Software. | ||
23 | * | ||
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
29 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
30 | * IN THE SOFTWARE. | ||
31 | */ | ||
32 | |||
33 | #define DPRINTK(fmt, args...) \ | ||
34 | pr_debug("xenbus_probe (%s:%d) " fmt ".\n", \ | ||
35 | __func__, __LINE__, ##args) | ||
36 | |||
37 | #include <linux/kernel.h> | ||
38 | #include <linux/err.h> | ||
39 | #include <linux/string.h> | ||
40 | #include <linux/ctype.h> | ||
41 | #include <linux/fcntl.h> | ||
42 | #include <linux/mm.h> | ||
43 | #include <linux/notifier.h> | ||
44 | #include <linux/kthread.h> | ||
45 | #include <linux/mutex.h> | ||
46 | #include <linux/io.h> | ||
47 | |||
48 | #include <asm/page.h> | ||
49 | #include <asm/pgtable.h> | ||
50 | #include <asm/xen/hypervisor.h> | ||
51 | #include <xen/xenbus.h> | ||
52 | #include <xen/events.h> | ||
53 | #include <xen/page.h> | ||
54 | |||
55 | #include "xenbus_comms.h" | ||
56 | #include "xenbus_probe.h" | ||
57 | |||
58 | int xen_store_evtchn; | ||
59 | struct xenstore_domain_interface *xen_store_interface; | ||
60 | static unsigned long xen_store_mfn; | ||
61 | |||
62 | static BLOCKING_NOTIFIER_HEAD(xenstore_chain); | ||
63 | |||
64 | static void wait_for_devices(struct xenbus_driver *xendrv); | ||
65 | |||
66 | static int xenbus_probe_frontend(const char *type, const char *name); | ||
67 | |||
68 | static void xenbus_dev_shutdown(struct device *_dev); | ||
69 | |||
70 | /* If something in array of ids matches this device, return it. */ | ||
71 | static const struct xenbus_device_id * | ||
72 | match_device(const struct xenbus_device_id *arr, struct xenbus_device *dev) | ||
73 | { | ||
74 | for (; *arr->devicetype != '\0'; arr++) { | ||
75 | if (!strcmp(arr->devicetype, dev->devicetype)) | ||
76 | return arr; | ||
77 | } | ||
78 | return NULL; | ||
79 | } | ||
80 | |||
81 | int xenbus_match(struct device *_dev, struct device_driver *_drv) | ||
82 | { | ||
83 | struct xenbus_driver *drv = to_xenbus_driver(_drv); | ||
84 | |||
85 | if (!drv->ids) | ||
86 | return 0; | ||
87 | |||
88 | return match_device(drv->ids, to_xenbus_device(_dev)) != NULL; | ||
89 | } | ||
90 | |||
91 | /* device/<type>/<id> => <type>-<id> */ | ||
92 | static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename) | ||
93 | { | ||
94 | nodename = strchr(nodename, '/'); | ||
95 | if (!nodename || strlen(nodename + 1) >= BUS_ID_SIZE) { | ||
96 | printk(KERN_WARNING "XENBUS: bad frontend %s\n", nodename); | ||
97 | return -EINVAL; | ||
98 | } | ||
99 | |||
100 | strlcpy(bus_id, nodename + 1, BUS_ID_SIZE); | ||
101 | if (!strchr(bus_id, '/')) { | ||
102 | printk(KERN_WARNING "XENBUS: bus_id %s no slash\n", bus_id); | ||
103 | return -EINVAL; | ||
104 | } | ||
105 | *strchr(bus_id, '/') = '-'; | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | |||
110 | static void free_otherend_details(struct xenbus_device *dev) | ||
111 | { | ||
112 | kfree(dev->otherend); | ||
113 | dev->otherend = NULL; | ||
114 | } | ||
115 | |||
116 | |||
117 | static void free_otherend_watch(struct xenbus_device *dev) | ||
118 | { | ||
119 | if (dev->otherend_watch.node) { | ||
120 | unregister_xenbus_watch(&dev->otherend_watch); | ||
121 | kfree(dev->otherend_watch.node); | ||
122 | dev->otherend_watch.node = NULL; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | |||
127 | int read_otherend_details(struct xenbus_device *xendev, | ||
128 | char *id_node, char *path_node) | ||
129 | { | ||
130 | int err = xenbus_gather(XBT_NIL, xendev->nodename, | ||
131 | id_node, "%i", &xendev->otherend_id, | ||
132 | path_node, NULL, &xendev->otherend, | ||
133 | NULL); | ||
134 | if (err) { | ||
135 | xenbus_dev_fatal(xendev, err, | ||
136 | "reading other end details from %s", | ||
137 | xendev->nodename); | ||
138 | return err; | ||
139 | } | ||
140 | if (strlen(xendev->otherend) == 0 || | ||
141 | !xenbus_exists(XBT_NIL, xendev->otherend, "")) { | ||
142 | xenbus_dev_fatal(xendev, -ENOENT, | ||
143 | "unable to read other end from %s. " | ||
144 | "missing or inaccessible.", | ||
145 | xendev->nodename); | ||
146 | free_otherend_details(xendev); | ||
147 | return -ENOENT; | ||
148 | } | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | |||
154 | static int read_backend_details(struct xenbus_device *xendev) | ||
155 | { | ||
156 | return read_otherend_details(xendev, "backend-id", "backend"); | ||
157 | } | ||
158 | |||
159 | |||
160 | /* Bus type for frontend drivers. */ | ||
161 | static struct xen_bus_type xenbus_frontend = { | ||
162 | .root = "device", | ||
163 | .levels = 2, /* device/type/<id> */ | ||
164 | .get_bus_id = frontend_bus_id, | ||
165 | .probe = xenbus_probe_frontend, | ||
166 | .bus = { | ||
167 | .name = "xen", | ||
168 | .match = xenbus_match, | ||
169 | .probe = xenbus_dev_probe, | ||
170 | .remove = xenbus_dev_remove, | ||
171 | .shutdown = xenbus_dev_shutdown, | ||
172 | }, | ||
173 | }; | ||
174 | |||
175 | static void otherend_changed(struct xenbus_watch *watch, | ||
176 | const char **vec, unsigned int len) | ||
177 | { | ||
178 | struct xenbus_device *dev = | ||
179 | container_of(watch, struct xenbus_device, otherend_watch); | ||
180 | struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver); | ||
181 | enum xenbus_state state; | ||
182 | |||
183 | /* Protect us against watches firing on old details when the otherend | ||
184 | details change, say immediately after a resume. */ | ||
185 | if (!dev->otherend || | ||
186 | strncmp(dev->otherend, vec[XS_WATCH_PATH], | ||
187 | strlen(dev->otherend))) { | ||
188 | dev_dbg(&dev->dev, "Ignoring watch at %s", vec[XS_WATCH_PATH]); | ||
189 | return; | ||
190 | } | ||
191 | |||
192 | state = xenbus_read_driver_state(dev->otherend); | ||
193 | |||
194 | dev_dbg(&dev->dev, "state is %d, (%s), %s, %s", | ||
195 | state, xenbus_strstate(state), dev->otherend_watch.node, | ||
196 | vec[XS_WATCH_PATH]); | ||
197 | |||
198 | /* | ||
199 | * Ignore xenbus transitions during shutdown. This prevents us doing | ||
200 | * work that can fail e.g., when the rootfs is gone. | ||
201 | */ | ||
202 | if (system_state > SYSTEM_RUNNING) { | ||
203 | struct xen_bus_type *bus = bus; | ||
204 | bus = container_of(dev->dev.bus, struct xen_bus_type, bus); | ||
205 | /* If we're frontend, drive the state machine to Closed. */ | ||
206 | /* This should cause the backend to release our resources. */ | ||
207 | if ((bus == &xenbus_frontend) && (state == XenbusStateClosing)) | ||
208 | xenbus_frontend_closed(dev); | ||
209 | return; | ||
210 | } | ||
211 | |||
212 | if (drv->otherend_changed) | ||
213 | drv->otherend_changed(dev, state); | ||
214 | } | ||
215 | |||
216 | |||
217 | static int talk_to_otherend(struct xenbus_device *dev) | ||
218 | { | ||
219 | struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver); | ||
220 | |||
221 | free_otherend_watch(dev); | ||
222 | free_otherend_details(dev); | ||
223 | |||
224 | return drv->read_otherend_details(dev); | ||
225 | } | ||
226 | |||
227 | |||
228 | static int watch_otherend(struct xenbus_device *dev) | ||
229 | { | ||
230 | return xenbus_watch_pathfmt(dev, &dev->otherend_watch, otherend_changed, | ||
231 | "%s/%s", dev->otherend, "state"); | ||
232 | } | ||
233 | |||
234 | |||
235 | int xenbus_dev_probe(struct device *_dev) | ||
236 | { | ||
237 | struct xenbus_device *dev = to_xenbus_device(_dev); | ||
238 | struct xenbus_driver *drv = to_xenbus_driver(_dev->driver); | ||
239 | const struct xenbus_device_id *id; | ||
240 | int err; | ||
241 | |||
242 | DPRINTK("%s", dev->nodename); | ||
243 | |||
244 | if (!drv->probe) { | ||
245 | err = -ENODEV; | ||
246 | goto fail; | ||
247 | } | ||
248 | |||
249 | id = match_device(drv->ids, dev); | ||
250 | if (!id) { | ||
251 | err = -ENODEV; | ||
252 | goto fail; | ||
253 | } | ||
254 | |||
255 | err = talk_to_otherend(dev); | ||
256 | if (err) { | ||
257 | dev_warn(&dev->dev, "talk_to_otherend on %s failed.\n", | ||
258 | dev->nodename); | ||
259 | return err; | ||
260 | } | ||
261 | |||
262 | err = drv->probe(dev, id); | ||
263 | if (err) | ||
264 | goto fail; | ||
265 | |||
266 | err = watch_otherend(dev); | ||
267 | if (err) { | ||
268 | dev_warn(&dev->dev, "watch_otherend on %s failed.\n", | ||
269 | dev->nodename); | ||
270 | return err; | ||
271 | } | ||
272 | |||
273 | return 0; | ||
274 | fail: | ||
275 | xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename); | ||
276 | xenbus_switch_state(dev, XenbusStateClosed); | ||
277 | return -ENODEV; | ||
278 | } | ||
279 | |||
280 | int xenbus_dev_remove(struct device *_dev) | ||
281 | { | ||
282 | struct xenbus_device *dev = to_xenbus_device(_dev); | ||
283 | struct xenbus_driver *drv = to_xenbus_driver(_dev->driver); | ||
284 | |||
285 | DPRINTK("%s", dev->nodename); | ||
286 | |||
287 | free_otherend_watch(dev); | ||
288 | free_otherend_details(dev); | ||
289 | |||
290 | if (drv->remove) | ||
291 | drv->remove(dev); | ||
292 | |||
293 | xenbus_switch_state(dev, XenbusStateClosed); | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static void xenbus_dev_shutdown(struct device *_dev) | ||
298 | { | ||
299 | struct xenbus_device *dev = to_xenbus_device(_dev); | ||
300 | unsigned long timeout = 5*HZ; | ||
301 | |||
302 | DPRINTK("%s", dev->nodename); | ||
303 | |||
304 | get_device(&dev->dev); | ||
305 | if (dev->state != XenbusStateConnected) { | ||
306 | printk(KERN_INFO "%s: %s: %s != Connected, skipping\n", __func__, | ||
307 | dev->nodename, xenbus_strstate(dev->state)); | ||
308 | goto out; | ||
309 | } | ||
310 | xenbus_switch_state(dev, XenbusStateClosing); | ||
311 | timeout = wait_for_completion_timeout(&dev->down, timeout); | ||
312 | if (!timeout) | ||
313 | printk(KERN_INFO "%s: %s timeout closing device\n", | ||
314 | __func__, dev->nodename); | ||
315 | out: | ||
316 | put_device(&dev->dev); | ||
317 | } | ||
318 | |||
319 | int xenbus_register_driver_common(struct xenbus_driver *drv, | ||
320 | struct xen_bus_type *bus, | ||
321 | struct module *owner, | ||
322 | const char *mod_name) | ||
323 | { | ||
324 | drv->driver.name = drv->name; | ||
325 | drv->driver.bus = &bus->bus; | ||
326 | drv->driver.owner = owner; | ||
327 | drv->driver.mod_name = mod_name; | ||
328 | |||
329 | return driver_register(&drv->driver); | ||
330 | } | ||
331 | |||
332 | int __xenbus_register_frontend(struct xenbus_driver *drv, | ||
333 | struct module *owner, const char *mod_name) | ||
334 | { | ||
335 | int ret; | ||
336 | |||
337 | drv->read_otherend_details = read_backend_details; | ||
338 | |||
339 | ret = xenbus_register_driver_common(drv, &xenbus_frontend, | ||
340 | owner, mod_name); | ||
341 | if (ret) | ||
342 | return ret; | ||
343 | |||
344 | /* If this driver is loaded as a module wait for devices to attach. */ | ||
345 | wait_for_devices(drv); | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | EXPORT_SYMBOL_GPL(__xenbus_register_frontend); | ||
350 | |||
351 | void xenbus_unregister_driver(struct xenbus_driver *drv) | ||
352 | { | ||
353 | driver_unregister(&drv->driver); | ||
354 | } | ||
355 | EXPORT_SYMBOL_GPL(xenbus_unregister_driver); | ||
356 | |||
357 | struct xb_find_info | ||
358 | { | ||
359 | struct xenbus_device *dev; | ||
360 | const char *nodename; | ||
361 | }; | ||
362 | |||
363 | static int cmp_dev(struct device *dev, void *data) | ||
364 | { | ||
365 | struct xenbus_device *xendev = to_xenbus_device(dev); | ||
366 | struct xb_find_info *info = data; | ||
367 | |||
368 | if (!strcmp(xendev->nodename, info->nodename)) { | ||
369 | info->dev = xendev; | ||
370 | get_device(dev); | ||
371 | return 1; | ||
372 | } | ||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | struct xenbus_device *xenbus_device_find(const char *nodename, | ||
377 | struct bus_type *bus) | ||
378 | { | ||
379 | struct xb_find_info info = { .dev = NULL, .nodename = nodename }; | ||
380 | |||
381 | bus_for_each_dev(bus, NULL, &info, cmp_dev); | ||
382 | return info.dev; | ||
383 | } | ||
384 | |||
385 | static int cleanup_dev(struct device *dev, void *data) | ||
386 | { | ||
387 | struct xenbus_device *xendev = to_xenbus_device(dev); | ||
388 | struct xb_find_info *info = data; | ||
389 | int len = strlen(info->nodename); | ||
390 | |||
391 | DPRINTK("%s", info->nodename); | ||
392 | |||
393 | /* Match the info->nodename path, or any subdirectory of that path. */ | ||
394 | if (strncmp(xendev->nodename, info->nodename, len)) | ||
395 | return 0; | ||
396 | |||
397 | /* If the node name is longer, ensure it really is a subdirectory. */ | ||
398 | if ((strlen(xendev->nodename) > len) && (xendev->nodename[len] != '/')) | ||
399 | return 0; | ||
400 | |||
401 | info->dev = xendev; | ||
402 | get_device(dev); | ||
403 | return 1; | ||
404 | } | ||
405 | |||
406 | static void xenbus_cleanup_devices(const char *path, struct bus_type *bus) | ||
407 | { | ||
408 | struct xb_find_info info = { .nodename = path }; | ||
409 | |||
410 | do { | ||
411 | info.dev = NULL; | ||
412 | bus_for_each_dev(bus, NULL, &info, cleanup_dev); | ||
413 | if (info.dev) { | ||
414 | device_unregister(&info.dev->dev); | ||
415 | put_device(&info.dev->dev); | ||
416 | } | ||
417 | } while (info.dev); | ||
418 | } | ||
419 | |||
420 | static void xenbus_dev_release(struct device *dev) | ||
421 | { | ||
422 | if (dev) | ||
423 | kfree(to_xenbus_device(dev)); | ||
424 | } | ||
425 | |||
426 | static ssize_t xendev_show_nodename(struct device *dev, | ||
427 | struct device_attribute *attr, char *buf) | ||
428 | { | ||
429 | return sprintf(buf, "%s\n", to_xenbus_device(dev)->nodename); | ||
430 | } | ||
431 | DEVICE_ATTR(nodename, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_nodename, NULL); | ||
432 | |||
433 | static ssize_t xendev_show_devtype(struct device *dev, | ||
434 | struct device_attribute *attr, char *buf) | ||
435 | { | ||
436 | return sprintf(buf, "%s\n", to_xenbus_device(dev)->devicetype); | ||
437 | } | ||
438 | DEVICE_ATTR(devtype, S_IRUSR | S_IRGRP | S_IROTH, xendev_show_devtype, NULL); | ||
439 | |||
440 | |||
441 | int xenbus_probe_node(struct xen_bus_type *bus, | ||
442 | const char *type, | ||
443 | const char *nodename) | ||
444 | { | ||
445 | int err; | ||
446 | struct xenbus_device *xendev; | ||
447 | size_t stringlen; | ||
448 | char *tmpstring; | ||
449 | |||
450 | enum xenbus_state state = xenbus_read_driver_state(nodename); | ||
451 | |||
452 | if (state != XenbusStateInitialising) { | ||
453 | /* Device is not new, so ignore it. This can happen if a | ||
454 | device is going away after switching to Closed. */ | ||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | stringlen = strlen(nodename) + 1 + strlen(type) + 1; | ||
459 | xendev = kzalloc(sizeof(*xendev) + stringlen, GFP_KERNEL); | ||
460 | if (!xendev) | ||
461 | return -ENOMEM; | ||
462 | |||
463 | xendev->state = XenbusStateInitialising; | ||
464 | |||
465 | /* Copy the strings into the extra space. */ | ||
466 | |||
467 | tmpstring = (char *)(xendev + 1); | ||
468 | strcpy(tmpstring, nodename); | ||
469 | xendev->nodename = tmpstring; | ||
470 | |||
471 | tmpstring += strlen(tmpstring) + 1; | ||
472 | strcpy(tmpstring, type); | ||
473 | xendev->devicetype = tmpstring; | ||
474 | init_completion(&xendev->down); | ||
475 | |||
476 | xendev->dev.bus = &bus->bus; | ||
477 | xendev->dev.release = xenbus_dev_release; | ||
478 | |||
479 | err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename); | ||
480 | if (err) | ||
481 | goto fail; | ||
482 | |||
483 | /* Register with generic device framework. */ | ||
484 | err = device_register(&xendev->dev); | ||
485 | if (err) | ||
486 | goto fail; | ||
487 | |||
488 | err = device_create_file(&xendev->dev, &dev_attr_nodename); | ||
489 | if (err) | ||
490 | goto fail_unregister; | ||
491 | |||
492 | err = device_create_file(&xendev->dev, &dev_attr_devtype); | ||
493 | if (err) | ||
494 | goto fail_remove_file; | ||
495 | |||
496 | return 0; | ||
497 | fail_remove_file: | ||
498 | device_remove_file(&xendev->dev, &dev_attr_nodename); | ||
499 | fail_unregister: | ||
500 | device_unregister(&xendev->dev); | ||
501 | fail: | ||
502 | kfree(xendev); | ||
503 | return err; | ||
504 | } | ||
505 | |||
506 | /* device/<typename>/<name> */ | ||
507 | static int xenbus_probe_frontend(const char *type, const char *name) | ||
508 | { | ||
509 | char *nodename; | ||
510 | int err; | ||
511 | |||
512 | nodename = kasprintf(GFP_KERNEL, "%s/%s/%s", | ||
513 | xenbus_frontend.root, type, name); | ||
514 | if (!nodename) | ||
515 | return -ENOMEM; | ||
516 | |||
517 | DPRINTK("%s", nodename); | ||
518 | |||
519 | err = xenbus_probe_node(&xenbus_frontend, type, nodename); | ||
520 | kfree(nodename); | ||
521 | return err; | ||
522 | } | ||
523 | |||
524 | static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type) | ||
525 | { | ||
526 | int err = 0; | ||
527 | char **dir; | ||
528 | unsigned int dir_n = 0; | ||
529 | int i; | ||
530 | |||
531 | dir = xenbus_directory(XBT_NIL, bus->root, type, &dir_n); | ||
532 | if (IS_ERR(dir)) | ||
533 | return PTR_ERR(dir); | ||
534 | |||
535 | for (i = 0; i < dir_n; i++) { | ||
536 | err = bus->probe(type, dir[i]); | ||
537 | if (err) | ||
538 | break; | ||
539 | } | ||
540 | kfree(dir); | ||
541 | return err; | ||
542 | } | ||
543 | |||
544 | int xenbus_probe_devices(struct xen_bus_type *bus) | ||
545 | { | ||
546 | int err = 0; | ||
547 | char **dir; | ||
548 | unsigned int i, dir_n; | ||
549 | |||
550 | dir = xenbus_directory(XBT_NIL, bus->root, "", &dir_n); | ||
551 | if (IS_ERR(dir)) | ||
552 | return PTR_ERR(dir); | ||
553 | |||
554 | for (i = 0; i < dir_n; i++) { | ||
555 | err = xenbus_probe_device_type(bus, dir[i]); | ||
556 | if (err) | ||
557 | break; | ||
558 | } | ||
559 | kfree(dir); | ||
560 | return err; | ||
561 | } | ||
562 | |||
563 | static unsigned int char_count(const char *str, char c) | ||
564 | { | ||
565 | unsigned int i, ret = 0; | ||
566 | |||
567 | for (i = 0; str[i]; i++) | ||
568 | if (str[i] == c) | ||
569 | ret++; | ||
570 | return ret; | ||
571 | } | ||
572 | |||
573 | static int strsep_len(const char *str, char c, unsigned int len) | ||
574 | { | ||
575 | unsigned int i; | ||
576 | |||
577 | for (i = 0; str[i]; i++) | ||
578 | if (str[i] == c) { | ||
579 | if (len == 0) | ||
580 | return i; | ||
581 | len--; | ||
582 | } | ||
583 | return (len == 0) ? i : -ERANGE; | ||
584 | } | ||
585 | |||
586 | void xenbus_dev_changed(const char *node, struct xen_bus_type *bus) | ||
587 | { | ||
588 | int exists, rootlen; | ||
589 | struct xenbus_device *dev; | ||
590 | char type[BUS_ID_SIZE]; | ||
591 | const char *p, *root; | ||
592 | |||
593 | if (char_count(node, '/') < 2) | ||
594 | return; | ||
595 | |||
596 | exists = xenbus_exists(XBT_NIL, node, ""); | ||
597 | if (!exists) { | ||
598 | xenbus_cleanup_devices(node, &bus->bus); | ||
599 | return; | ||
600 | } | ||
601 | |||
602 | /* backend/<type>/... or device/<type>/... */ | ||
603 | p = strchr(node, '/') + 1; | ||
604 | snprintf(type, BUS_ID_SIZE, "%.*s", (int)strcspn(p, "/"), p); | ||
605 | type[BUS_ID_SIZE-1] = '\0'; | ||
606 | |||
607 | rootlen = strsep_len(node, '/', bus->levels); | ||
608 | if (rootlen < 0) | ||
609 | return; | ||
610 | root = kasprintf(GFP_KERNEL, "%.*s", rootlen, node); | ||
611 | if (!root) | ||
612 | return; | ||
613 | |||
614 | dev = xenbus_device_find(root, &bus->bus); | ||
615 | if (!dev) | ||
616 | xenbus_probe_node(bus, type, root); | ||
617 | else | ||
618 | put_device(&dev->dev); | ||
619 | |||
620 | kfree(root); | ||
621 | } | ||
622 | |||
623 | static void frontend_changed(struct xenbus_watch *watch, | ||
624 | const char **vec, unsigned int len) | ||
625 | { | ||
626 | DPRINTK(""); | ||
627 | |||
628 | xenbus_dev_changed(vec[XS_WATCH_PATH], &xenbus_frontend); | ||
629 | } | ||
630 | |||
631 | /* We watch for devices appearing and vanishing. */ | ||
632 | static struct xenbus_watch fe_watch = { | ||
633 | .node = "device", | ||
634 | .callback = frontend_changed, | ||
635 | }; | ||
636 | |||
637 | static int suspend_dev(struct device *dev, void *data) | ||
638 | { | ||
639 | int err = 0; | ||
640 | struct xenbus_driver *drv; | ||
641 | struct xenbus_device *xdev; | ||
642 | |||
643 | DPRINTK(""); | ||
644 | |||
645 | if (dev->driver == NULL) | ||
646 | return 0; | ||
647 | drv = to_xenbus_driver(dev->driver); | ||
648 | xdev = container_of(dev, struct xenbus_device, dev); | ||
649 | if (drv->suspend) | ||
650 | err = drv->suspend(xdev); | ||
651 | if (err) | ||
652 | printk(KERN_WARNING | ||
653 | "xenbus: suspend %s failed: %i\n", dev->bus_id, err); | ||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | static int suspend_cancel_dev(struct device *dev, void *data) | ||
658 | { | ||
659 | int err = 0; | ||
660 | struct xenbus_driver *drv; | ||
661 | struct xenbus_device *xdev; | ||
662 | |||
663 | DPRINTK(""); | ||
664 | |||
665 | if (dev->driver == NULL) | ||
666 | return 0; | ||
667 | drv = to_xenbus_driver(dev->driver); | ||
668 | xdev = container_of(dev, struct xenbus_device, dev); | ||
669 | if (drv->suspend_cancel) | ||
670 | err = drv->suspend_cancel(xdev); | ||
671 | if (err) | ||
672 | printk(KERN_WARNING | ||
673 | "xenbus: suspend_cancel %s failed: %i\n", | ||
674 | dev->bus_id, err); | ||
675 | return 0; | ||
676 | } | ||
677 | |||
678 | static int resume_dev(struct device *dev, void *data) | ||
679 | { | ||
680 | int err; | ||
681 | struct xenbus_driver *drv; | ||
682 | struct xenbus_device *xdev; | ||
683 | |||
684 | DPRINTK(""); | ||
685 | |||
686 | if (dev->driver == NULL) | ||
687 | return 0; | ||
688 | |||
689 | drv = to_xenbus_driver(dev->driver); | ||
690 | xdev = container_of(dev, struct xenbus_device, dev); | ||
691 | |||
692 | err = talk_to_otherend(xdev); | ||
693 | if (err) { | ||
694 | printk(KERN_WARNING | ||
695 | "xenbus: resume (talk_to_otherend) %s failed: %i\n", | ||
696 | dev->bus_id, err); | ||
697 | return err; | ||
698 | } | ||
699 | |||
700 | xdev->state = XenbusStateInitialising; | ||
701 | |||
702 | if (drv->resume) { | ||
703 | err = drv->resume(xdev); | ||
704 | if (err) { | ||
705 | printk(KERN_WARNING | ||
706 | "xenbus: resume %s failed: %i\n", | ||
707 | dev->bus_id, err); | ||
708 | return err; | ||
709 | } | ||
710 | } | ||
711 | |||
712 | err = watch_otherend(xdev); | ||
713 | if (err) { | ||
714 | printk(KERN_WARNING | ||
715 | "xenbus_probe: resume (watch_otherend) %s failed: " | ||
716 | "%d.\n", dev->bus_id, err); | ||
717 | return err; | ||
718 | } | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | void xenbus_suspend(void) | ||
724 | { | ||
725 | DPRINTK(""); | ||
726 | |||
727 | bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_dev); | ||
728 | xenbus_backend_suspend(suspend_dev); | ||
729 | xs_suspend(); | ||
730 | } | ||
731 | EXPORT_SYMBOL_GPL(xenbus_suspend); | ||
732 | |||
733 | void xenbus_resume(void) | ||
734 | { | ||
735 | xb_init_comms(); | ||
736 | xs_resume(); | ||
737 | bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, resume_dev); | ||
738 | xenbus_backend_resume(resume_dev); | ||
739 | } | ||
740 | EXPORT_SYMBOL_GPL(xenbus_resume); | ||
741 | |||
742 | void xenbus_suspend_cancel(void) | ||
743 | { | ||
744 | xs_suspend_cancel(); | ||
745 | bus_for_each_dev(&xenbus_frontend.bus, NULL, NULL, suspend_cancel_dev); | ||
746 | xenbus_backend_resume(suspend_cancel_dev); | ||
747 | } | ||
748 | EXPORT_SYMBOL_GPL(xenbus_suspend_cancel); | ||
749 | |||
750 | /* A flag to determine if xenstored is 'ready' (i.e. has started) */ | ||
751 | int xenstored_ready = 0; | ||
752 | |||
753 | |||
754 | int register_xenstore_notifier(struct notifier_block *nb) | ||
755 | { | ||
756 | int ret = 0; | ||
757 | |||
758 | if (xenstored_ready > 0) | ||
759 | ret = nb->notifier_call(nb, 0, NULL); | ||
760 | else | ||
761 | blocking_notifier_chain_register(&xenstore_chain, nb); | ||
762 | |||
763 | return ret; | ||
764 | } | ||
765 | EXPORT_SYMBOL_GPL(register_xenstore_notifier); | ||
766 | |||
767 | void unregister_xenstore_notifier(struct notifier_block *nb) | ||
768 | { | ||
769 | blocking_notifier_chain_unregister(&xenstore_chain, nb); | ||
770 | } | ||
771 | EXPORT_SYMBOL_GPL(unregister_xenstore_notifier); | ||
772 | |||
773 | void xenbus_probe(struct work_struct *unused) | ||
774 | { | ||
775 | BUG_ON((xenstored_ready <= 0)); | ||
776 | |||
777 | /* Enumerate devices in xenstore and watch for changes. */ | ||
778 | xenbus_probe_devices(&xenbus_frontend); | ||
779 | register_xenbus_watch(&fe_watch); | ||
780 | xenbus_backend_probe_and_watch(); | ||
781 | |||
782 | /* Notify others that xenstore is up */ | ||
783 | blocking_notifier_call_chain(&xenstore_chain, 0, NULL); | ||
784 | } | ||
785 | |||
786 | static int __init xenbus_probe_init(void) | ||
787 | { | ||
788 | int err = 0; | ||
789 | |||
790 | DPRINTK(""); | ||
791 | |||
792 | err = -ENODEV; | ||
793 | if (!is_running_on_xen()) | ||
794 | goto out_error; | ||
795 | |||
796 | /* Register ourselves with the kernel bus subsystem */ | ||
797 | err = bus_register(&xenbus_frontend.bus); | ||
798 | if (err) | ||
799 | goto out_error; | ||
800 | |||
801 | err = xenbus_backend_bus_register(); | ||
802 | if (err) | ||
803 | goto out_unreg_front; | ||
804 | |||
805 | /* | ||
806 | * Domain0 doesn't have a store_evtchn or store_mfn yet. | ||
807 | */ | ||
808 | if (is_initial_xendomain()) { | ||
809 | /* dom0 not yet supported */ | ||
810 | } else { | ||
811 | xenstored_ready = 1; | ||
812 | xen_store_evtchn = xen_start_info->store_evtchn; | ||
813 | xen_store_mfn = xen_start_info->store_mfn; | ||
814 | } | ||
815 | xen_store_interface = mfn_to_virt(xen_store_mfn); | ||
816 | |||
817 | /* Initialize the interface to xenstore. */ | ||
818 | err = xs_init(); | ||
819 | if (err) { | ||
820 | printk(KERN_WARNING | ||
821 | "XENBUS: Error initializing xenstore comms: %i\n", err); | ||
822 | goto out_unreg_back; | ||
823 | } | ||
824 | |||
825 | if (!is_initial_xendomain()) | ||
826 | xenbus_probe(NULL); | ||
827 | |||
828 | return 0; | ||
829 | |||
830 | out_unreg_back: | ||
831 | xenbus_backend_bus_unregister(); | ||
832 | |||
833 | out_unreg_front: | ||
834 | bus_unregister(&xenbus_frontend.bus); | ||
835 | |||
836 | out_error: | ||
837 | return err; | ||
838 | } | ||
839 | |||
840 | postcore_initcall(xenbus_probe_init); | ||
841 | |||
842 | MODULE_LICENSE("GPL"); | ||
843 | |||
844 | static int is_disconnected_device(struct device *dev, void *data) | ||
845 | { | ||
846 | struct xenbus_device *xendev = to_xenbus_device(dev); | ||
847 | struct device_driver *drv = data; | ||
848 | |||
849 | /* | ||
850 | * A device with no driver will never connect. We care only about | ||
851 | * devices which should currently be in the process of connecting. | ||
852 | */ | ||
853 | if (!dev->driver) | ||
854 | return 0; | ||
855 | |||
856 | /* Is this search limited to a particular driver? */ | ||
857 | if (drv && (dev->driver != drv)) | ||
858 | return 0; | ||
859 | |||
860 | return (xendev->state != XenbusStateConnected); | ||
861 | } | ||
862 | |||
863 | static int exists_disconnected_device(struct device_driver *drv) | ||
864 | { | ||
865 | return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, | ||
866 | is_disconnected_device); | ||
867 | } | ||
868 | |||
869 | static int print_device_status(struct device *dev, void *data) | ||
870 | { | ||
871 | struct xenbus_device *xendev = to_xenbus_device(dev); | ||
872 | struct device_driver *drv = data; | ||
873 | |||
874 | /* Is this operation limited to a particular driver? */ | ||
875 | if (drv && (dev->driver != drv)) | ||
876 | return 0; | ||
877 | |||
878 | if (!dev->driver) { | ||
879 | /* Information only: is this too noisy? */ | ||
880 | printk(KERN_INFO "XENBUS: Device with no driver: %s\n", | ||
881 | xendev->nodename); | ||
882 | } else if (xendev->state != XenbusStateConnected) { | ||
883 | printk(KERN_WARNING "XENBUS: Timeout connecting " | ||
884 | "to device: %s (state %d)\n", | ||
885 | xendev->nodename, xendev->state); | ||
886 | } | ||
887 | |||
888 | return 0; | ||
889 | } | ||
890 | |||
891 | /* We only wait for device setup after most initcalls have run. */ | ||
892 | static int ready_to_wait_for_devices; | ||
893 | |||
894 | /* | ||
895 | * On a 10 second timeout, wait for all devices currently configured. We need | ||
896 | * to do this to guarantee that the filesystems and / or network devices | ||
897 | * needed for boot are available, before we can allow the boot to proceed. | ||
898 | * | ||
899 | * This needs to be on a late_initcall, to happen after the frontend device | ||
900 | * drivers have been initialised, but before the root fs is mounted. | ||
901 | * | ||
902 | * A possible improvement here would be to have the tools add a per-device | ||
903 | * flag to the store entry, indicating whether it is needed at boot time. | ||
904 | * This would allow people who knew what they were doing to accelerate their | ||
905 | * boot slightly, but of course needs tools or manual intervention to set up | ||
906 | * those flags correctly. | ||
907 | */ | ||
908 | static void wait_for_devices(struct xenbus_driver *xendrv) | ||
909 | { | ||
910 | unsigned long timeout = jiffies + 10*HZ; | ||
911 | struct device_driver *drv = xendrv ? &xendrv->driver : NULL; | ||
912 | |||
913 | if (!ready_to_wait_for_devices || !is_running_on_xen()) | ||
914 | return; | ||
915 | |||
916 | while (exists_disconnected_device(drv)) { | ||
917 | if (time_after(jiffies, timeout)) | ||
918 | break; | ||
919 | schedule_timeout_interruptible(HZ/10); | ||
920 | } | ||
921 | |||
922 | bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, | ||
923 | print_device_status); | ||
924 | } | ||
925 | |||
926 | #ifndef MODULE | ||
927 | static int __init boot_wait_for_devices(void) | ||
928 | { | ||
929 | ready_to_wait_for_devices = 1; | ||
930 | wait_for_devices(NULL); | ||
931 | return 0; | ||
932 | } | ||
933 | |||
934 | late_initcall(boot_wait_for_devices); | ||
935 | #endif | ||
diff --git a/drivers/xen/xenbus/xenbus_probe.h b/drivers/xen/xenbus/xenbus_probe.h new file mode 100644 index 000000000000..e09b19415a40 --- /dev/null +++ b/drivers/xen/xenbus/xenbus_probe.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /****************************************************************************** | ||
2 | * xenbus_probe.h | ||
3 | * | ||
4 | * Talks to Xen Store to figure out what devices we have. | ||
5 | * | ||
6 | * Copyright (C) 2005 Rusty Russell, IBM Corporation | ||
7 | * Copyright (C) 2005 XenSource Ltd. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License version 2 | ||
11 | * as published by the Free Software Foundation; or, when distributed | ||
12 | * separately from the Linux kernel or incorporated into other | ||
13 | * software packages, subject to the following license: | ||
14 | * | ||
15 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
16 | * of this source file (the "Software"), to deal in the Software without | ||
17 | * restriction, including without limitation the rights to use, copy, modify, | ||
18 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
19 | * and to permit persons to whom the Software is furnished to do so, subject to | ||
20 | * the following conditions: | ||
21 | * | ||
22 | * The above copyright notice and this permission notice shall be included in | ||
23 | * all copies or substantial portions of the Software. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
26 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
27 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
28 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
29 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
30 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
31 | * IN THE SOFTWARE. | ||
32 | */ | ||
33 | |||
34 | #ifndef _XENBUS_PROBE_H | ||
35 | #define _XENBUS_PROBE_H | ||
36 | |||
37 | #ifdef CONFIG_XEN_BACKEND | ||
38 | extern void xenbus_backend_suspend(int (*fn)(struct device *, void *)); | ||
39 | extern void xenbus_backend_resume(int (*fn)(struct device *, void *)); | ||
40 | extern void xenbus_backend_probe_and_watch(void); | ||
41 | extern int xenbus_backend_bus_register(void); | ||
42 | extern void xenbus_backend_bus_unregister(void); | ||
43 | #else | ||
44 | static inline void xenbus_backend_suspend(int (*fn)(struct device *, void *)) {} | ||
45 | static inline void xenbus_backend_resume(int (*fn)(struct device *, void *)) {} | ||
46 | static inline void xenbus_backend_probe_and_watch(void) {} | ||
47 | static inline int xenbus_backend_bus_register(void) { return 0; } | ||
48 | static inline void xenbus_backend_bus_unregister(void) {} | ||
49 | #endif | ||
50 | |||
51 | struct xen_bus_type | ||
52 | { | ||
53 | char *root; | ||
54 | unsigned int levels; | ||
55 | int (*get_bus_id)(char bus_id[BUS_ID_SIZE], const char *nodename); | ||
56 | int (*probe)(const char *type, const char *dir); | ||
57 | struct bus_type bus; | ||
58 | }; | ||
59 | |||
60 | extern int xenbus_match(struct device *_dev, struct device_driver *_drv); | ||
61 | extern int xenbus_dev_probe(struct device *_dev); | ||
62 | extern int xenbus_dev_remove(struct device *_dev); | ||
63 | extern int xenbus_register_driver_common(struct xenbus_driver *drv, | ||
64 | struct xen_bus_type *bus, | ||
65 | struct module *owner, | ||
66 | const char *mod_name); | ||
67 | extern int xenbus_probe_node(struct xen_bus_type *bus, | ||
68 | const char *type, | ||
69 | const char *nodename); | ||
70 | extern int xenbus_probe_devices(struct xen_bus_type *bus); | ||
71 | |||
72 | extern void xenbus_dev_changed(const char *node, struct xen_bus_type *bus); | ||
73 | |||
74 | #endif | ||
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c new file mode 100644 index 000000000000..9e943fbce81b --- /dev/null +++ b/drivers/xen/xenbus/xenbus_xs.c | |||
@@ -0,0 +1,861 @@ | |||
1 | /****************************************************************************** | ||
2 | * xenbus_xs.c | ||
3 | * | ||
4 | * This is the kernel equivalent of the "xs" library. We don't need everything | ||
5 | * and we use xenbus_comms for communication. | ||
6 | * | ||
7 | * Copyright (C) 2005 Rusty Russell, IBM Corporation | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License version 2 | ||
11 | * as published by the Free Software Foundation; or, when distributed | ||
12 | * separately from the Linux kernel or incorporated into other | ||
13 | * software packages, subject to the following license: | ||
14 | * | ||
15 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
16 | * of this source file (the "Software"), to deal in the Software without | ||
17 | * restriction, including without limitation the rights to use, copy, modify, | ||
18 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, | ||
19 | * and to permit persons to whom the Software is furnished to do so, subject to | ||
20 | * the following conditions: | ||
21 | * | ||
22 | * The above copyright notice and this permission notice shall be included in | ||
23 | * all copies or substantial portions of the Software. | ||
24 | * | ||
25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
26 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
27 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
28 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
29 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
30 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
31 | * IN THE SOFTWARE. | ||
32 | */ | ||
33 | |||
34 | #include <linux/unistd.h> | ||
35 | #include <linux/errno.h> | ||
36 | #include <linux/types.h> | ||
37 | #include <linux/uio.h> | ||
38 | #include <linux/kernel.h> | ||
39 | #include <linux/string.h> | ||
40 | #include <linux/err.h> | ||
41 | #include <linux/slab.h> | ||
42 | #include <linux/fcntl.h> | ||
43 | #include <linux/kthread.h> | ||
44 | #include <linux/rwsem.h> | ||
45 | #include <linux/module.h> | ||
46 | #include <linux/mutex.h> | ||
47 | #include <xen/xenbus.h> | ||
48 | #include "xenbus_comms.h" | ||
49 | |||
50 | struct xs_stored_msg { | ||
51 | struct list_head list; | ||
52 | |||
53 | struct xsd_sockmsg hdr; | ||
54 | |||
55 | union { | ||
56 | /* Queued replies. */ | ||
57 | struct { | ||
58 | char *body; | ||
59 | } reply; | ||
60 | |||
61 | /* Queued watch events. */ | ||
62 | struct { | ||
63 | struct xenbus_watch *handle; | ||
64 | char **vec; | ||
65 | unsigned int vec_size; | ||
66 | } watch; | ||
67 | } u; | ||
68 | }; | ||
69 | |||
70 | struct xs_handle { | ||
71 | /* A list of replies. Currently only one will ever be outstanding. */ | ||
72 | struct list_head reply_list; | ||
73 | spinlock_t reply_lock; | ||
74 | wait_queue_head_t reply_waitq; | ||
75 | |||
76 | /* | ||
77 | * Mutex ordering: transaction_mutex -> watch_mutex -> request_mutex. | ||
78 | * response_mutex is never taken simultaneously with the other three. | ||
79 | */ | ||
80 | |||
81 | /* One request at a time. */ | ||
82 | struct mutex request_mutex; | ||
83 | |||
84 | /* Protect xenbus reader thread against save/restore. */ | ||
85 | struct mutex response_mutex; | ||
86 | |||
87 | /* Protect transactions against save/restore. */ | ||
88 | struct rw_semaphore transaction_mutex; | ||
89 | |||
90 | /* Protect watch (de)register against save/restore. */ | ||
91 | struct rw_semaphore watch_mutex; | ||
92 | }; | ||
93 | |||
94 | static struct xs_handle xs_state; | ||
95 | |||
96 | /* List of registered watches, and a lock to protect it. */ | ||
97 | static LIST_HEAD(watches); | ||
98 | static DEFINE_SPINLOCK(watches_lock); | ||
99 | |||
100 | /* List of pending watch callback events, and a lock to protect it. */ | ||
101 | static LIST_HEAD(watch_events); | ||
102 | static DEFINE_SPINLOCK(watch_events_lock); | ||
103 | |||
104 | /* | ||
105 | * Details of the xenwatch callback kernel thread. The thread waits on the | ||
106 | * watch_events_waitq for work to do (queued on watch_events list). When it | ||
107 | * wakes up it acquires the xenwatch_mutex before reading the list and | ||
108 | * carrying out work. | ||
109 | */ | ||
110 | static pid_t xenwatch_pid; | ||
111 | static DEFINE_MUTEX(xenwatch_mutex); | ||
112 | static DECLARE_WAIT_QUEUE_HEAD(watch_events_waitq); | ||
113 | |||
114 | static int get_error(const char *errorstring) | ||
115 | { | ||
116 | unsigned int i; | ||
117 | |||
118 | for (i = 0; strcmp(errorstring, xsd_errors[i].errstring) != 0; i++) { | ||
119 | if (i == ARRAY_SIZE(xsd_errors) - 1) { | ||
120 | printk(KERN_WARNING | ||
121 | "XENBUS xen store gave: unknown error %s", | ||
122 | errorstring); | ||
123 | return EINVAL; | ||
124 | } | ||
125 | } | ||
126 | return xsd_errors[i].errnum; | ||
127 | } | ||
128 | |||
129 | static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len) | ||
130 | { | ||
131 | struct xs_stored_msg *msg; | ||
132 | char *body; | ||
133 | |||
134 | spin_lock(&xs_state.reply_lock); | ||
135 | |||
136 | while (list_empty(&xs_state.reply_list)) { | ||
137 | spin_unlock(&xs_state.reply_lock); | ||
138 | /* XXX FIXME: Avoid synchronous wait for response here. */ | ||
139 | wait_event(xs_state.reply_waitq, | ||
140 | !list_empty(&xs_state.reply_list)); | ||
141 | spin_lock(&xs_state.reply_lock); | ||
142 | } | ||
143 | |||
144 | msg = list_entry(xs_state.reply_list.next, | ||
145 | struct xs_stored_msg, list); | ||
146 | list_del(&msg->list); | ||
147 | |||
148 | spin_unlock(&xs_state.reply_lock); | ||
149 | |||
150 | *type = msg->hdr.type; | ||
151 | if (len) | ||
152 | *len = msg->hdr.len; | ||
153 | body = msg->u.reply.body; | ||
154 | |||
155 | kfree(msg); | ||
156 | |||
157 | return body; | ||
158 | } | ||
159 | |||
160 | void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg) | ||
161 | { | ||
162 | void *ret; | ||
163 | struct xsd_sockmsg req_msg = *msg; | ||
164 | int err; | ||
165 | |||
166 | if (req_msg.type == XS_TRANSACTION_START) | ||
167 | down_read(&xs_state.transaction_mutex); | ||
168 | |||
169 | mutex_lock(&xs_state.request_mutex); | ||
170 | |||
171 | err = xb_write(msg, sizeof(*msg) + msg->len); | ||
172 | if (err) { | ||
173 | msg->type = XS_ERROR; | ||
174 | ret = ERR_PTR(err); | ||
175 | } else | ||
176 | ret = read_reply(&msg->type, &msg->len); | ||
177 | |||
178 | mutex_unlock(&xs_state.request_mutex); | ||
179 | |||
180 | if ((msg->type == XS_TRANSACTION_END) || | ||
181 | ((req_msg.type == XS_TRANSACTION_START) && | ||
182 | (msg->type == XS_ERROR))) | ||
183 | up_read(&xs_state.transaction_mutex); | ||
184 | |||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | /* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */ | ||
189 | static void *xs_talkv(struct xenbus_transaction t, | ||
190 | enum xsd_sockmsg_type type, | ||
191 | const struct kvec *iovec, | ||
192 | unsigned int num_vecs, | ||
193 | unsigned int *len) | ||
194 | { | ||
195 | struct xsd_sockmsg msg; | ||
196 | void *ret = NULL; | ||
197 | unsigned int i; | ||
198 | int err; | ||
199 | |||
200 | msg.tx_id = t.id; | ||
201 | msg.req_id = 0; | ||
202 | msg.type = type; | ||
203 | msg.len = 0; | ||
204 | for (i = 0; i < num_vecs; i++) | ||
205 | msg.len += iovec[i].iov_len; | ||
206 | |||
207 | mutex_lock(&xs_state.request_mutex); | ||
208 | |||
209 | err = xb_write(&msg, sizeof(msg)); | ||
210 | if (err) { | ||
211 | mutex_unlock(&xs_state.request_mutex); | ||
212 | return ERR_PTR(err); | ||
213 | } | ||
214 | |||
215 | for (i = 0; i < num_vecs; i++) { | ||
216 | err = xb_write(iovec[i].iov_base, iovec[i].iov_len); | ||
217 | if (err) { | ||
218 | mutex_unlock(&xs_state.request_mutex); | ||
219 | return ERR_PTR(err); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | ret = read_reply(&msg.type, len); | ||
224 | |||
225 | mutex_unlock(&xs_state.request_mutex); | ||
226 | |||
227 | if (IS_ERR(ret)) | ||
228 | return ret; | ||
229 | |||
230 | if (msg.type == XS_ERROR) { | ||
231 | err = get_error(ret); | ||
232 | kfree(ret); | ||
233 | return ERR_PTR(-err); | ||
234 | } | ||
235 | |||
236 | if (msg.type != type) { | ||
237 | if (printk_ratelimit()) | ||
238 | printk(KERN_WARNING | ||
239 | "XENBUS unexpected type [%d], expected [%d]\n", | ||
240 | msg.type, type); | ||
241 | kfree(ret); | ||
242 | return ERR_PTR(-EINVAL); | ||
243 | } | ||
244 | return ret; | ||
245 | } | ||
246 | |||
247 | /* Simplified version of xs_talkv: single message. */ | ||
248 | static void *xs_single(struct xenbus_transaction t, | ||
249 | enum xsd_sockmsg_type type, | ||
250 | const char *string, | ||
251 | unsigned int *len) | ||
252 | { | ||
253 | struct kvec iovec; | ||
254 | |||
255 | iovec.iov_base = (void *)string; | ||
256 | iovec.iov_len = strlen(string) + 1; | ||
257 | return xs_talkv(t, type, &iovec, 1, len); | ||
258 | } | ||
259 | |||
260 | /* Many commands only need an ack, don't care what it says. */ | ||
261 | static int xs_error(char *reply) | ||
262 | { | ||
263 | if (IS_ERR(reply)) | ||
264 | return PTR_ERR(reply); | ||
265 | kfree(reply); | ||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static unsigned int count_strings(const char *strings, unsigned int len) | ||
270 | { | ||
271 | unsigned int num; | ||
272 | const char *p; | ||
273 | |||
274 | for (p = strings, num = 0; p < strings + len; p += strlen(p) + 1) | ||
275 | num++; | ||
276 | |||
277 | return num; | ||
278 | } | ||
279 | |||
280 | /* Return the path to dir with /name appended. Buffer must be kfree()'ed. */ | ||
281 | static char *join(const char *dir, const char *name) | ||
282 | { | ||
283 | char *buffer; | ||
284 | |||
285 | if (strlen(name) == 0) | ||
286 | buffer = kasprintf(GFP_KERNEL, "%s", dir); | ||
287 | else | ||
288 | buffer = kasprintf(GFP_KERNEL, "%s/%s", dir, name); | ||
289 | return (!buffer) ? ERR_PTR(-ENOMEM) : buffer; | ||
290 | } | ||
291 | |||
292 | static char **split(char *strings, unsigned int len, unsigned int *num) | ||
293 | { | ||
294 | char *p, **ret; | ||
295 | |||
296 | /* Count the strings. */ | ||
297 | *num = count_strings(strings, len); | ||
298 | |||
299 | /* Transfer to one big alloc for easy freeing. */ | ||
300 | ret = kmalloc(*num * sizeof(char *) + len, GFP_KERNEL); | ||
301 | if (!ret) { | ||
302 | kfree(strings); | ||
303 | return ERR_PTR(-ENOMEM); | ||
304 | } | ||
305 | memcpy(&ret[*num], strings, len); | ||
306 | kfree(strings); | ||
307 | |||
308 | strings = (char *)&ret[*num]; | ||
309 | for (p = strings, *num = 0; p < strings + len; p += strlen(p) + 1) | ||
310 | ret[(*num)++] = p; | ||
311 | |||
312 | return ret; | ||
313 | } | ||
314 | |||
315 | char **xenbus_directory(struct xenbus_transaction t, | ||
316 | const char *dir, const char *node, unsigned int *num) | ||
317 | { | ||
318 | char *strings, *path; | ||
319 | unsigned int len; | ||
320 | |||
321 | path = join(dir, node); | ||
322 | if (IS_ERR(path)) | ||
323 | return (char **)path; | ||
324 | |||
325 | strings = xs_single(t, XS_DIRECTORY, path, &len); | ||
326 | kfree(path); | ||
327 | if (IS_ERR(strings)) | ||
328 | return (char **)strings; | ||
329 | |||
330 | return split(strings, len, num); | ||
331 | } | ||
332 | EXPORT_SYMBOL_GPL(xenbus_directory); | ||
333 | |||
334 | /* Check if a path exists. Return 1 if it does. */ | ||
335 | int xenbus_exists(struct xenbus_transaction t, | ||
336 | const char *dir, const char *node) | ||
337 | { | ||
338 | char **d; | ||
339 | int dir_n; | ||
340 | |||
341 | d = xenbus_directory(t, dir, node, &dir_n); | ||
342 | if (IS_ERR(d)) | ||
343 | return 0; | ||
344 | kfree(d); | ||
345 | return 1; | ||
346 | } | ||
347 | EXPORT_SYMBOL_GPL(xenbus_exists); | ||
348 | |||
349 | /* Get the value of a single file. | ||
350 | * Returns a kmalloced value: call free() on it after use. | ||
351 | * len indicates length in bytes. | ||
352 | */ | ||
353 | void *xenbus_read(struct xenbus_transaction t, | ||
354 | const char *dir, const char *node, unsigned int *len) | ||
355 | { | ||
356 | char *path; | ||
357 | void *ret; | ||
358 | |||
359 | path = join(dir, node); | ||
360 | if (IS_ERR(path)) | ||
361 | return (void *)path; | ||
362 | |||
363 | ret = xs_single(t, XS_READ, path, len); | ||
364 | kfree(path); | ||
365 | return ret; | ||
366 | } | ||
367 | EXPORT_SYMBOL_GPL(xenbus_read); | ||
368 | |||
369 | /* Write the value of a single file. | ||
370 | * Returns -err on failure. | ||
371 | */ | ||
372 | int xenbus_write(struct xenbus_transaction t, | ||
373 | const char *dir, const char *node, const char *string) | ||
374 | { | ||
375 | const char *path; | ||
376 | struct kvec iovec[2]; | ||
377 | int ret; | ||
378 | |||
379 | path = join(dir, node); | ||
380 | if (IS_ERR(path)) | ||
381 | return PTR_ERR(path); | ||
382 | |||
383 | iovec[0].iov_base = (void *)path; | ||
384 | iovec[0].iov_len = strlen(path) + 1; | ||
385 | iovec[1].iov_base = (void *)string; | ||
386 | iovec[1].iov_len = strlen(string); | ||
387 | |||
388 | ret = xs_error(xs_talkv(t, XS_WRITE, iovec, ARRAY_SIZE(iovec), NULL)); | ||
389 | kfree(path); | ||
390 | return ret; | ||
391 | } | ||
392 | EXPORT_SYMBOL_GPL(xenbus_write); | ||
393 | |||
394 | /* Create a new directory. */ | ||
395 | int xenbus_mkdir(struct xenbus_transaction t, | ||
396 | const char *dir, const char *node) | ||
397 | { | ||
398 | char *path; | ||
399 | int ret; | ||
400 | |||
401 | path = join(dir, node); | ||
402 | if (IS_ERR(path)) | ||
403 | return PTR_ERR(path); | ||
404 | |||
405 | ret = xs_error(xs_single(t, XS_MKDIR, path, NULL)); | ||
406 | kfree(path); | ||
407 | return ret; | ||
408 | } | ||
409 | EXPORT_SYMBOL_GPL(xenbus_mkdir); | ||
410 | |||
411 | /* Destroy a file or directory (directories must be empty). */ | ||
412 | int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node) | ||
413 | { | ||
414 | char *path; | ||
415 | int ret; | ||
416 | |||
417 | path = join(dir, node); | ||
418 | if (IS_ERR(path)) | ||
419 | return PTR_ERR(path); | ||
420 | |||
421 | ret = xs_error(xs_single(t, XS_RM, path, NULL)); | ||
422 | kfree(path); | ||
423 | return ret; | ||
424 | } | ||
425 | EXPORT_SYMBOL_GPL(xenbus_rm); | ||
426 | |||
427 | /* Start a transaction: changes by others will not be seen during this | ||
428 | * transaction, and changes will not be visible to others until end. | ||
429 | */ | ||
430 | int xenbus_transaction_start(struct xenbus_transaction *t) | ||
431 | { | ||
432 | char *id_str; | ||
433 | |||
434 | down_read(&xs_state.transaction_mutex); | ||
435 | |||
436 | id_str = xs_single(XBT_NIL, XS_TRANSACTION_START, "", NULL); | ||
437 | if (IS_ERR(id_str)) { | ||
438 | up_read(&xs_state.transaction_mutex); | ||
439 | return PTR_ERR(id_str); | ||
440 | } | ||
441 | |||
442 | t->id = simple_strtoul(id_str, NULL, 0); | ||
443 | kfree(id_str); | ||
444 | return 0; | ||
445 | } | ||
446 | EXPORT_SYMBOL_GPL(xenbus_transaction_start); | ||
447 | |||
448 | /* End a transaction. | ||
449 | * If abandon is true, transaction is discarded instead of committed. | ||
450 | */ | ||
451 | int xenbus_transaction_end(struct xenbus_transaction t, int abort) | ||
452 | { | ||
453 | char abortstr[2]; | ||
454 | int err; | ||
455 | |||
456 | if (abort) | ||
457 | strcpy(abortstr, "F"); | ||
458 | else | ||
459 | strcpy(abortstr, "T"); | ||
460 | |||
461 | err = xs_error(xs_single(t, XS_TRANSACTION_END, abortstr, NULL)); | ||
462 | |||
463 | up_read(&xs_state.transaction_mutex); | ||
464 | |||
465 | return err; | ||
466 | } | ||
467 | EXPORT_SYMBOL_GPL(xenbus_transaction_end); | ||
468 | |||
469 | /* Single read and scanf: returns -errno or num scanned. */ | ||
470 | int xenbus_scanf(struct xenbus_transaction t, | ||
471 | const char *dir, const char *node, const char *fmt, ...) | ||
472 | { | ||
473 | va_list ap; | ||
474 | int ret; | ||
475 | char *val; | ||
476 | |||
477 | val = xenbus_read(t, dir, node, NULL); | ||
478 | if (IS_ERR(val)) | ||
479 | return PTR_ERR(val); | ||
480 | |||
481 | va_start(ap, fmt); | ||
482 | ret = vsscanf(val, fmt, ap); | ||
483 | va_end(ap); | ||
484 | kfree(val); | ||
485 | /* Distinctive errno. */ | ||
486 | if (ret == 0) | ||
487 | return -ERANGE; | ||
488 | return ret; | ||
489 | } | ||
490 | EXPORT_SYMBOL_GPL(xenbus_scanf); | ||
491 | |||
492 | /* Single printf and write: returns -errno or 0. */ | ||
493 | int xenbus_printf(struct xenbus_transaction t, | ||
494 | const char *dir, const char *node, const char *fmt, ...) | ||
495 | { | ||
496 | va_list ap; | ||
497 | int ret; | ||
498 | #define PRINTF_BUFFER_SIZE 4096 | ||
499 | char *printf_buffer; | ||
500 | |||
501 | printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL); | ||
502 | if (printf_buffer == NULL) | ||
503 | return -ENOMEM; | ||
504 | |||
505 | va_start(ap, fmt); | ||
506 | ret = vsnprintf(printf_buffer, PRINTF_BUFFER_SIZE, fmt, ap); | ||
507 | va_end(ap); | ||
508 | |||
509 | BUG_ON(ret > PRINTF_BUFFER_SIZE-1); | ||
510 | ret = xenbus_write(t, dir, node, printf_buffer); | ||
511 | |||
512 | kfree(printf_buffer); | ||
513 | |||
514 | return ret; | ||
515 | } | ||
516 | EXPORT_SYMBOL_GPL(xenbus_printf); | ||
517 | |||
518 | /* Takes tuples of names, scanf-style args, and void **, NULL terminated. */ | ||
519 | int xenbus_gather(struct xenbus_transaction t, const char *dir, ...) | ||
520 | { | ||
521 | va_list ap; | ||
522 | const char *name; | ||
523 | int ret = 0; | ||
524 | |||
525 | va_start(ap, dir); | ||
526 | while (ret == 0 && (name = va_arg(ap, char *)) != NULL) { | ||
527 | const char *fmt = va_arg(ap, char *); | ||
528 | void *result = va_arg(ap, void *); | ||
529 | char *p; | ||
530 | |||
531 | p = xenbus_read(t, dir, name, NULL); | ||
532 | if (IS_ERR(p)) { | ||
533 | ret = PTR_ERR(p); | ||
534 | break; | ||
535 | } | ||
536 | if (fmt) { | ||
537 | if (sscanf(p, fmt, result) == 0) | ||
538 | ret = -EINVAL; | ||
539 | kfree(p); | ||
540 | } else | ||
541 | *(char **)result = p; | ||
542 | } | ||
543 | va_end(ap); | ||
544 | return ret; | ||
545 | } | ||
546 | EXPORT_SYMBOL_GPL(xenbus_gather); | ||
547 | |||
548 | static int xs_watch(const char *path, const char *token) | ||
549 | { | ||
550 | struct kvec iov[2]; | ||
551 | |||
552 | iov[0].iov_base = (void *)path; | ||
553 | iov[0].iov_len = strlen(path) + 1; | ||
554 | iov[1].iov_base = (void *)token; | ||
555 | iov[1].iov_len = strlen(token) + 1; | ||
556 | |||
557 | return xs_error(xs_talkv(XBT_NIL, XS_WATCH, iov, | ||
558 | ARRAY_SIZE(iov), NULL)); | ||
559 | } | ||
560 | |||
561 | static int xs_unwatch(const char *path, const char *token) | ||
562 | { | ||
563 | struct kvec iov[2]; | ||
564 | |||
565 | iov[0].iov_base = (char *)path; | ||
566 | iov[0].iov_len = strlen(path) + 1; | ||
567 | iov[1].iov_base = (char *)token; | ||
568 | iov[1].iov_len = strlen(token) + 1; | ||
569 | |||
570 | return xs_error(xs_talkv(XBT_NIL, XS_UNWATCH, iov, | ||
571 | ARRAY_SIZE(iov), NULL)); | ||
572 | } | ||
573 | |||
574 | static struct xenbus_watch *find_watch(const char *token) | ||
575 | { | ||
576 | struct xenbus_watch *i, *cmp; | ||
577 | |||
578 | cmp = (void *)simple_strtoul(token, NULL, 16); | ||
579 | |||
580 | list_for_each_entry(i, &watches, list) | ||
581 | if (i == cmp) | ||
582 | return i; | ||
583 | |||
584 | return NULL; | ||
585 | } | ||
586 | |||
587 | /* Register callback to watch this node. */ | ||
588 | int register_xenbus_watch(struct xenbus_watch *watch) | ||
589 | { | ||
590 | /* Pointer in ascii is the token. */ | ||
591 | char token[sizeof(watch) * 2 + 1]; | ||
592 | int err; | ||
593 | |||
594 | sprintf(token, "%lX", (long)watch); | ||
595 | |||
596 | down_read(&xs_state.watch_mutex); | ||
597 | |||
598 | spin_lock(&watches_lock); | ||
599 | BUG_ON(find_watch(token)); | ||
600 | list_add(&watch->list, &watches); | ||
601 | spin_unlock(&watches_lock); | ||
602 | |||
603 | err = xs_watch(watch->node, token); | ||
604 | |||
605 | /* Ignore errors due to multiple registration. */ | ||
606 | if ((err != 0) && (err != -EEXIST)) { | ||
607 | spin_lock(&watches_lock); | ||
608 | list_del(&watch->list); | ||
609 | spin_unlock(&watches_lock); | ||
610 | } | ||
611 | |||
612 | up_read(&xs_state.watch_mutex); | ||
613 | |||
614 | return err; | ||
615 | } | ||
616 | EXPORT_SYMBOL_GPL(register_xenbus_watch); | ||
617 | |||
618 | void unregister_xenbus_watch(struct xenbus_watch *watch) | ||
619 | { | ||
620 | struct xs_stored_msg *msg, *tmp; | ||
621 | char token[sizeof(watch) * 2 + 1]; | ||
622 | int err; | ||
623 | |||
624 | sprintf(token, "%lX", (long)watch); | ||
625 | |||
626 | down_read(&xs_state.watch_mutex); | ||
627 | |||
628 | spin_lock(&watches_lock); | ||
629 | BUG_ON(!find_watch(token)); | ||
630 | list_del(&watch->list); | ||
631 | spin_unlock(&watches_lock); | ||
632 | |||
633 | err = xs_unwatch(watch->node, token); | ||
634 | if (err) | ||
635 | printk(KERN_WARNING | ||
636 | "XENBUS Failed to release watch %s: %i\n", | ||
637 | watch->node, err); | ||
638 | |||
639 | up_read(&xs_state.watch_mutex); | ||
640 | |||
641 | /* Make sure there are no callbacks running currently (unless | ||
642 | its us) */ | ||
643 | if (current->pid != xenwatch_pid) | ||
644 | mutex_lock(&xenwatch_mutex); | ||
645 | |||
646 | /* Cancel pending watch events. */ | ||
647 | spin_lock(&watch_events_lock); | ||
648 | list_for_each_entry_safe(msg, tmp, &watch_events, list) { | ||
649 | if (msg->u.watch.handle != watch) | ||
650 | continue; | ||
651 | list_del(&msg->list); | ||
652 | kfree(msg->u.watch.vec); | ||
653 | kfree(msg); | ||
654 | } | ||
655 | spin_unlock(&watch_events_lock); | ||
656 | |||
657 | if (current->pid != xenwatch_pid) | ||
658 | mutex_unlock(&xenwatch_mutex); | ||
659 | } | ||
660 | EXPORT_SYMBOL_GPL(unregister_xenbus_watch); | ||
661 | |||
662 | void xs_suspend(void) | ||
663 | { | ||
664 | down_write(&xs_state.transaction_mutex); | ||
665 | down_write(&xs_state.watch_mutex); | ||
666 | mutex_lock(&xs_state.request_mutex); | ||
667 | mutex_lock(&xs_state.response_mutex); | ||
668 | } | ||
669 | |||
670 | void xs_resume(void) | ||
671 | { | ||
672 | struct xenbus_watch *watch; | ||
673 | char token[sizeof(watch) * 2 + 1]; | ||
674 | |||
675 | mutex_unlock(&xs_state.response_mutex); | ||
676 | mutex_unlock(&xs_state.request_mutex); | ||
677 | up_write(&xs_state.transaction_mutex); | ||
678 | |||
679 | /* No need for watches_lock: the watch_mutex is sufficient. */ | ||
680 | list_for_each_entry(watch, &watches, list) { | ||
681 | sprintf(token, "%lX", (long)watch); | ||
682 | xs_watch(watch->node, token); | ||
683 | } | ||
684 | |||
685 | up_write(&xs_state.watch_mutex); | ||
686 | } | ||
687 | |||
688 | void xs_suspend_cancel(void) | ||
689 | { | ||
690 | mutex_unlock(&xs_state.response_mutex); | ||
691 | mutex_unlock(&xs_state.request_mutex); | ||
692 | up_write(&xs_state.watch_mutex); | ||
693 | up_write(&xs_state.transaction_mutex); | ||
694 | } | ||
695 | |||
696 | static int xenwatch_thread(void *unused) | ||
697 | { | ||
698 | struct list_head *ent; | ||
699 | struct xs_stored_msg *msg; | ||
700 | |||
701 | for (;;) { | ||
702 | wait_event_interruptible(watch_events_waitq, | ||
703 | !list_empty(&watch_events)); | ||
704 | |||
705 | if (kthread_should_stop()) | ||
706 | break; | ||
707 | |||
708 | mutex_lock(&xenwatch_mutex); | ||
709 | |||
710 | spin_lock(&watch_events_lock); | ||
711 | ent = watch_events.next; | ||
712 | if (ent != &watch_events) | ||
713 | list_del(ent); | ||
714 | spin_unlock(&watch_events_lock); | ||
715 | |||
716 | if (ent != &watch_events) { | ||
717 | msg = list_entry(ent, struct xs_stored_msg, list); | ||
718 | msg->u.watch.handle->callback( | ||
719 | msg->u.watch.handle, | ||
720 | (const char **)msg->u.watch.vec, | ||
721 | msg->u.watch.vec_size); | ||
722 | kfree(msg->u.watch.vec); | ||
723 | kfree(msg); | ||
724 | } | ||
725 | |||
726 | mutex_unlock(&xenwatch_mutex); | ||
727 | } | ||
728 | |||
729 | return 0; | ||
730 | } | ||
731 | |||
732 | static int process_msg(void) | ||
733 | { | ||
734 | struct xs_stored_msg *msg; | ||
735 | char *body; | ||
736 | int err; | ||
737 | |||
738 | /* | ||
739 | * We must disallow save/restore while reading a xenstore message. | ||
740 | * A partial read across s/r leaves us out of sync with xenstored. | ||
741 | */ | ||
742 | for (;;) { | ||
743 | err = xb_wait_for_data_to_read(); | ||
744 | if (err) | ||
745 | return err; | ||
746 | mutex_lock(&xs_state.response_mutex); | ||
747 | if (xb_data_to_read()) | ||
748 | break; | ||
749 | /* We raced with save/restore: pending data 'disappeared'. */ | ||
750 | mutex_unlock(&xs_state.response_mutex); | ||
751 | } | ||
752 | |||
753 | |||
754 | msg = kmalloc(sizeof(*msg), GFP_KERNEL); | ||
755 | if (msg == NULL) { | ||
756 | err = -ENOMEM; | ||
757 | goto out; | ||
758 | } | ||
759 | |||
760 | err = xb_read(&msg->hdr, sizeof(msg->hdr)); | ||
761 | if (err) { | ||
762 | kfree(msg); | ||
763 | goto out; | ||
764 | } | ||
765 | |||
766 | body = kmalloc(msg->hdr.len + 1, GFP_KERNEL); | ||
767 | if (body == NULL) { | ||
768 | kfree(msg); | ||
769 | err = -ENOMEM; | ||
770 | goto out; | ||
771 | } | ||
772 | |||
773 | err = xb_read(body, msg->hdr.len); | ||
774 | if (err) { | ||
775 | kfree(body); | ||
776 | kfree(msg); | ||
777 | goto out; | ||
778 | } | ||
779 | body[msg->hdr.len] = '\0'; | ||
780 | |||
781 | if (msg->hdr.type == XS_WATCH_EVENT) { | ||
782 | msg->u.watch.vec = split(body, msg->hdr.len, | ||
783 | &msg->u.watch.vec_size); | ||
784 | if (IS_ERR(msg->u.watch.vec)) { | ||
785 | kfree(msg); | ||
786 | err = PTR_ERR(msg->u.watch.vec); | ||
787 | goto out; | ||
788 | } | ||
789 | |||
790 | spin_lock(&watches_lock); | ||
791 | msg->u.watch.handle = find_watch( | ||
792 | msg->u.watch.vec[XS_WATCH_TOKEN]); | ||
793 | if (msg->u.watch.handle != NULL) { | ||
794 | spin_lock(&watch_events_lock); | ||
795 | list_add_tail(&msg->list, &watch_events); | ||
796 | wake_up(&watch_events_waitq); | ||
797 | spin_unlock(&watch_events_lock); | ||
798 | } else { | ||
799 | kfree(msg->u.watch.vec); | ||
800 | kfree(msg); | ||
801 | } | ||
802 | spin_unlock(&watches_lock); | ||
803 | } else { | ||
804 | msg->u.reply.body = body; | ||
805 | spin_lock(&xs_state.reply_lock); | ||
806 | list_add_tail(&msg->list, &xs_state.reply_list); | ||
807 | spin_unlock(&xs_state.reply_lock); | ||
808 | wake_up(&xs_state.reply_waitq); | ||
809 | } | ||
810 | |||
811 | out: | ||
812 | mutex_unlock(&xs_state.response_mutex); | ||
813 | return err; | ||
814 | } | ||
815 | |||
816 | static int xenbus_thread(void *unused) | ||
817 | { | ||
818 | int err; | ||
819 | |||
820 | for (;;) { | ||
821 | err = process_msg(); | ||
822 | if (err) | ||
823 | printk(KERN_WARNING "XENBUS error %d while reading " | ||
824 | "message\n", err); | ||
825 | if (kthread_should_stop()) | ||
826 | break; | ||
827 | } | ||
828 | |||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | int xs_init(void) | ||
833 | { | ||
834 | int err; | ||
835 | struct task_struct *task; | ||
836 | |||
837 | INIT_LIST_HEAD(&xs_state.reply_list); | ||
838 | spin_lock_init(&xs_state.reply_lock); | ||
839 | init_waitqueue_head(&xs_state.reply_waitq); | ||
840 | |||
841 | mutex_init(&xs_state.request_mutex); | ||
842 | mutex_init(&xs_state.response_mutex); | ||
843 | init_rwsem(&xs_state.transaction_mutex); | ||
844 | init_rwsem(&xs_state.watch_mutex); | ||
845 | |||
846 | /* Initialize the shared memory rings to talk to xenstored */ | ||
847 | err = xb_init_comms(); | ||
848 | if (err) | ||
849 | return err; | ||
850 | |||
851 | task = kthread_run(xenwatch_thread, NULL, "xenwatch"); | ||
852 | if (IS_ERR(task)) | ||
853 | return PTR_ERR(task); | ||
854 | xenwatch_pid = task->pid; | ||
855 | |||
856 | task = kthread_run(xenbus_thread, NULL, "xenbus"); | ||
857 | if (IS_ERR(task)) | ||
858 | return PTR_ERR(task); | ||
859 | |||
860 | return 0; | ||
861 | } | ||